位置:首页 » 文章/教程分享 » Spring AOP初步介绍(二)

4. Spring AOP

前文提到 JDK 代理和 CGLIB 代理两种动态代理。优秀的 Spring 框架把两种方式在底层都集成了进去,我们无需担心自己去实现动态生成代理。那么,Spring是如何生成代理对象的?

  1. 创建容器对象的时候,根据切入点表达式拦截的类,生成代理对象。
  2. 如果目标对象有实现接口,使用 JDK 代理。如果目标对象没有实现接口,则使用 CGLIB 代理。然后从容器获取代理后的对象,在运行期植入“切面”类的方法。通过查看 Spring 源码,我们在 DefaultAopProxyFactory 类中,找到这样一段话。

简单的从字面意思看出:如果有接口,则使用 JDK 代理,反之使用 CGLIB ,这刚好印证了前文所阐述的内容。Spring AOP 综合两种代理方式的使用前提有会如下结论:如果目标类没有实现接口,且 class 为 final 修饰的,则不能进行 Spring AOP 编程!

知道了原理,现在我们将自己手动实现 Spring 的 AOP:

package test.spring_aop_anno;
 
import org.aspectj.lang.ProceedingJoinPoint;
 
public interface IUserDao {
    void save();
}
 
// 用于测试 CGLIB 动态代理
class OrderDao {
    public void save() {
        //int i =1/0; 用于测试异常通知
        System.out.println("保存订单...");
    }
}
 
//用于测试 JDK 动态代理
class UserDao implements IUserDao {
    public void save() {
        //int i =1/0; 用于测试异常通知
        System.out.println("保存用户...");
    }
}
 
//切面类
class TransactionAop {
 
    public void beginTransaction() {
        System.out.println("[前置通知]  开启事务..");
    }
 
    public void commit() {
        System.out.println("[后置通知] 提交事务..");
    }
 
    public void afterReturing() {
        System.out.println("[返回后通知]");
    }
 
    public void afterThrowing() {
        System.out.println("[异常通知]");
    }
 
    public void arroud(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("[环绕前:]");
        pjp.proceed(); // 执行目标方法
        System.out.println("[环绕后:]");
    }
}


Spring 的 XML 配置文件:



 
    
    
 
    
    
 
    
    
 
    
    
        
        
        
        
            
            
            
            
            
            
            
            
            
            
        
    

切入点表达式不在这里介绍。参考 Spring AOP 切入点表达式

代码的测试结果如下:

到这里,我们已经全部介绍完Spring AOP。回到开篇的问题,我们拿它做什么?

  1. Spring声明式事务管理配置:请参考博主的另一篇文章:分布式系统架构实战 demo:SSM+Dubbo
  2. Controller层的参数校验:参考 Spring AOP拦截Controller做参数校验
  3. 使用 Spring AOP 实现 MySQL 数据库读写分离案例分析
  4. 在执行方法前,判断是否具有权限
  5. 对部分函数的调用进行日志记录:监控部分重要函数,若抛出指定的异常,可以以短信或邮件方式通知相关人员。
  6. 信息过滤,页面转发等等功能