Spring的AOP简介

OOP的不足:当需要为多个不具有继承关系的对象引入一个公共行为,例如日志、权限验证、事务等,只能在每个对象里引用公共行为,这样做不便于维护,而且有大量重复代码,AOP的出现就弥补了OOP的这点不足。

代理模式:比如A对象要做一件事情,在没有代理前,自己来做,在对A代理后,由A的代理类B来做。代理其实是在原实例前后加了一层处理,这也是AOP的初级轮廓。

静态代理模式:在程序运行前就已经存在代理类的字节码文件,代理类和原始类的关系在运行前就已经确定。示例如下:
// 接口
public interface IUserDao {
    void save();
    void find();
}
//目标对象
class UserDao implements IUserDao{
    @Override
    public void save() {
        System.out.println("模拟:保存用户!");
    }
    @Override
    public void find() {
           System.out.println("模拟:查询用户");
    }
}
/**
   静态代理
         特点:
 1. 目标对象必须要实现接口
 2. 代理对象,要实现与目标对象一样的接口
*/
class UserDaoProxy implements IUserDao{
    // 代理对象,需要维护一个目标对象
    private IUserDao target = new UserDao();
    @Override
    public void save() {
        System.out.println("代理操作: 开启事务...");
        target.save();   // 执行目标对象的方法
        System.out.println("代理操作:提交事务...");
    }
    @Override
    public void find() {
        target.find();
    }
}
静态代理虽然保证了业务类只需关注逻辑本身,代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理。再者,如果增加一个方法,除了实现类需要实现这个方法外,所有的代理类也要实现此方法。增加了代码的维护成本。那么要如何解决呢?答案是使用动态代理。

动态代理模式:动态代理类的源码是在程序运行期间通过JVM反射等机制动态生成,代理类和委托类的关系是运行时才确定的。示例如下:
// 接口
public interface IUserDao {
    void save();
    void find();
}
//目标对象
class UserDao implements IUserDao{
    @Override
    public void save() {
        System.out.println("模拟: 保存用户!");
    }
    @Override
    public void find() {
           System.out.println("查询");
     }
}
/**
* 动态代理:
*    代理工厂,给多个目标对象生成代理对象!
*
*/
class ProxyFactory {
    // 接收一个目标对象
    private Object target;
    public ProxyFactory(Object target) {
        this.target = target;
     }
    // 返回对目标对象(target)代理后的对象(proxy)
    public Object getProxyInstance() {
        Object proxy = Proxy.newProxyInstance(
                 target.getClass().getClassLoader(),  // 目标对象使用的类加载器
                target.getClass().getInterfaces(),   // 目标对象实现的所有接口
                 new InvocationHandler() {      // 执行代理对象方法时候触发
                       @Override
                      public Object invoke(Object proxy, Method method, Object[] args)
                               throws Throwable {

                             // 获取当前执行的方法的方法名
                             String methodName = method.getName();
                             // 方法返回值
                             Object result = ;
                             if ("find".equals(methodName)) {
                                   // 直接调用目标对象方法
                                   result = method.invoke(target, args);
                             } else {
                                   System.out.println("开启事务...");
                                   // 执行目标对象方法
                                   result = method.invoke(target, args);
                                   System.out.println("提交事务...");
                             }
                             return result;
                       }
                 }
           );
           return proxy;
     }
}
AOP的定义:面向切面编程,核心原理是使用动态代理模式在方法执行前后或出现异常时加入相关逻辑。

之后实现前置、后置、环绕、异常接口并进行配置。

优点:1.各个步骤之间的良好隔离性,耦合性大大降低 ;
           2.源代码无关性,在扩展功能的同时不对源码进行修改操作。

猜你喜欢

转载自www.cnblogs.com/yuanfei1110111/p/10211143.html