三.Spring之AOP介绍

  • Post author:
  • Post category:其他


一.AOP介绍

  • 面向切面编程;
  • AOP采用横向抽取机制,取代传统纵向继承体系重复性代码;
  • 作用:性能检测,事物管理,安全检查,缓存;
  • Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码;

二.AOP相关概念

  • Joinpoint(连接点):所谓连接点是指那些被拦截到的点,在spring中,这些点指的是方法,因为spring只支持方法类型的连接点;
  • Pointcut(切入点):所为切入点是指我们要对那些Joinpoint进行拦截的定义;
  • Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知,通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能);
  • Introduction(引介):引介是一种特殊的通知在不修改类的代码的前提下,Introduction可以运行为类动态地添加一些方法和属性(filed);
  • Target(目标对象):代理的目标对象;
  • Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程,spring采用动态代理织入,而AspectJ采用编译器织入和类装载期织入;
  • Proxy(代理):一个类被AOP织入增强后,就会产生一个结果类;
  • Aspect(切面):是切入点和通知(引介)的结合

说明:

  • 对于不使用接口的业务类,无法使用JDK代理类;
  • CGLib采用非常底层字节码技术,可以为一个类创建子类,解决无接口代理问题.

三.code

  1. JDK

  1. package com.batac.demo1;
    
    public interface UserDao {
        public void save();
    
        public void update();
    
        public void delete();
    
        public void find();
    }
    

    package com.batac.demo1;
    
    public class UserDaoImpl implements UserDao {
        @Override
        public void save() {
            System.out.println("save");
        }
    
        @Override
        public void update() {
            System.out.println("update");
        }
    
        @Override
        public void delete() {
            System.out.println("delete");
        }
    
        @Override
        public void find() {
            System.out.println("find");
        }
    }
    
    package com.batac.demo1;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class MyJdkProxy implements InvocationHandler {
    
        private UserDao userDao;
    
        public MyJdkProxy(UserDao userDao){
            this.userDao = userDao;
        }
    
    
        public Object createProxy(){
            Object object =  Proxy.newProxyInstance(userDao.getClass().getClassLoader(),userDao.getClass().getInterfaces(),this);
            return object;
        }
    
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if ("save".equals(method.getName())){
                System.out.println("增强save方法");
                return method.invoke(userDao,args);
            }
    
            return method.invoke(userDao,args);
        }
    }
    package com.batac.demo1;
    
    import org.junit.Test;
    
    public class UserDaoTest {
    
        @Test
        public void demo1(){
    
            UserDao userDao = new UserDaoImpl();
            UserDao proxy = (UserDao) new MyJdkProxy(userDao).createProxy();
            proxy.save();
            proxy.delete();
            proxy.update();
            proxy.find();
    
        }
    
    }
    

  2. CGLIB

package com.batac.demo2;

public class ProductDao {

    public void save(){
        System.out.println("save");
    }

    public void delete(){
        System.out.println("delete");
    }

    public void update(){
        System.out.println("update");
    }

    public void find(){
        System.out.println("find");
    }
}
package com.batac.demo2;

import com.batac.demo1.MyJdkProxy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyCglibProxy implements MethodInterceptor {

    private ProductDao productDao;

    public MyCglibProxy(ProductDao productDao){
        this.productDao = productDao;
    }

    public Object createProxy(){
        //1.创建核心类
        Enhancer enhancer = new Enhancer();
        //2.设置父类
        enhancer.setSuperclass(productDao.getClass());
        //3.设置回调
        enhancer.setCallback(this);
        //4.生成代理
        Object proxy = (Object) enhancer.create();
        return proxy;
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        if ("save".equals(method.getName())){

            System.out.println("加强save方法");
            return methodProxy.invokeSuper(o,objects);
        }
        return methodProxy.invokeSuper(o,objects);
    }
}
package com.batac.demo2;

import org.junit.Test;

public class ProductDaoTest {

    @Test
    public void demo1(){
        ProductDao productDao = new ProductDao();
        ProductDao productDao1 = (ProductDao) new MyCglibProxy(productDao).createProxy();

        productDao1.save();
        productDao1.delete();
        productDao1.find();
        productDao1.update();

    }


}

导入依赖

<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>


    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.1.9.RELEASE</version>
    </dependency>

总结



版权声明:本文为Batac_Lee原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。