Spring之AOP概述及实现原理(动态代理)

一、AOP的背景知识 

具体介绍:https://baike.baidu.com/item/AOP/1332219?fr=aladdin

        1、AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

        2、使用场景:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

动态权限例如:

          我们在向数据库保存数据时,我们不希望任何人都能实现对数据库数据的修改,这时我们需要设置操作的权限。传统方式:
          我们解决的方法是采用用纵向继承的方式实现,通过创造一个BaseDao类来实现对方法权限校验的定义,利用继承的方式实            现,显然这样的方式会改变业务逻辑层的代码。但是利用AOP的思想来对程序进行扩展,而且不改变程序的原有代码;如果            我们不需要的时候,我们就可以去除。

二、AOP实现方法

1、实现原理    :动态代理

代理的含义:指为一个目标对象提供一个代理对象, 并由代理对象控制对目标对象的引用. 使用代理对象, 是为了在不修改目标对象的基础上, 增强目标对象的业务逻辑.
        JDK动态代理    :  只能对实现接口的类产生代理
        Cglib                 :(类似于javassist第三方代理技术):对没有实现接口类的类产生代理对象。生成子类对象。

2、JDK实现动态代理的过程(只能对实现接口的类产生代理   

例如:增强save()方法的demo(类似的权限控制等功能的实现理念都是如此);

步骤:1、先创建一个接口UserDao;

           2、实现接口用UserDaoImpl类;

           3、使用JDK的动态代理对UserDao产生代理,创建JdkProxy代理类

           4、对JdkProxy类进行测试

==================================UserDao 接口类=====================================
//1、接口类....被代理的类,利用动态代理增强它的save()方法
public interface UserDao {
    public void save();
}
//public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("Save执行了...");
    }
}
====================================UserDao 的实现类==================================
//2、UserDao 的实现类
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("Save执行了...");
    }
}
====================================代理类JdkProxy ====================================
//3、创建代理类JdkProxy  用该类代理UserDao,并增强它的save方法
public class JdkProxy implements InvocationHandler{
    private UserDao userDao;
    public JdkProxy(UserDao userDao){
        this.userDao = userDao;
    }
    /*
    * 产生UserDao代理的方法
    * */
    public UserDao createProxy(){
        /**
         * proxy:代理类代理的真实代理对象com.sun.proxy.$Proxy0
         * method:我们所要调用某个对象真实的方法的Method对象
         * args:指代代理对象方法传递的参数
         */
        UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
                userDao.getClass().getInterfaces(),this);
        return userDaoProxy;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //1、判断方法名是不是save
        if("save".equals(method.getName())){
            System.out.println("校验校验===================");
            return method.invoke(userDao,args);
        }
        return method.invoke(userDao,args);
    }
}
=================================测试类 ===============================================
    @Test
    //JDK使用动态代理的方式
    public void demo01(){
        UserDao userDao = new UserDaoImpl();
    }

2、Cglib实现动态代理  

  同样增强save()方法,CglibProxy类的实现代码:

public class CglibProxy implements MethodInterceptor{

    private CustomerDao customerDao;

    public CglibProxy(CustomerDao customerDao) {
        this.customerDao = customerDao;
    }
    /*
    * 利用Cglib实现动态代理:
    *  方法:
    *
    * */
    public CustomerDao createProxy(){
        //1、创建cglib的核心类对象
        Enhancer enhancer = new Enhancer();
        //2、设置父类
        enhancer.setSuperclass(customerDao.getClass());
        //3、设置回调(类似于InvocationHandler对象)
        enhancer.setCallback(this);
        //4、创建代理对象
        CustomerDao proxy = (CustomerDao) enhancer.create();
        return proxy;
    }

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        //判断方法 是否为save
        if("save1".equals(method.getName())){
            //增强方法,使用代理。用代理对象
            System.out.println("权限校验===========");
            return methodProxy.invokeSuper(proxy,args);//proxy代理对象
        }
        return methodProxy.invokeSuper(proxy,args);//如果不是save方法,执行父类的方法,没有增强
    }
}

三、AOP的开发(AspectJ的XML的方式)

1、SpringAOP的简介
         AOP联盟提出的,Spring使用了这种思想。Spring的AOP有自己的方式(非常的繁琐)
         AspectJ:是一个AOP的一个框架,Spring引入了AspectJ作为自身的AOP开发。
2、因此Spring有两套AOP的开发方式
        Spring传统的
        Spring基于AspectJ的AOP的开发

四、AOP开发中的相关术语:

Spring之AOP概述及实现原理(动态代理)_第1张图片
    JoinPoint:连接点,可以被拦截(增强)到的点(如:增删改查的方法,都可以成为连接点)
    pointCut:切入点,真正要被拦截(增强)到的点(如:实际开发中,我们只对一个方法增强,添加的方法)

    Advice:通知、增强。方法层面的增强。比如权限校验的方法被称为是通知。
    Introduction:引介,也是增强,不过是类层面的增强。一般研究的是方法层面。

    Target:目标,被增强的对象(例如userDao)
    Weaving:织入,将通知应用到目标的过程。比如将权限校验的代码应用到UserDao的save方法上的过程。
    Proxy:一个类被AOP织入增强后,产生一个结果代理类
    Aspect:切面,多个通知和多个切入点的组合

    先了解,下篇详细介绍

五、Spring的AOP的入门(AspectJ的XML的方式)

步骤:1、引入jar包 
                  基本开发包
                  AOP的包
          2、创建XML文件,引入约束
          3、编写目标类。增强
          4、编写测试类   

 也先了解,下篇一起介绍。因为,AOP的入门必须先了解相关的术语,以及AOP的实现原理,知道作用,才能知道怎么运用。

你可能感兴趣的:(Spring学习)