【Spring学习笔记】AOP

一、何为AOP?

AOP(Aspect-Oriented Programming,面向切面编程)是对传统传统 OOP(Object-Oriented Programming,面向对象编程)的补充,属于一种横向扩展。其将与核心业务无关的代码,如日志记录、性能监控、事务处理等从业务逻辑代码中抽离出来,进行横向排列,从而实现低耦合,提高开发效率。

3

二、AOP相关术语

名称 说明
Advice(通知) 例如日志记录、性能监控、事务处理等增强的功能。
Joinpoint(连接点) 具体执行增强的地方。例如方法调用前、调用后和方法捕获异常后。
Pointcut(切入点) 匹配连接点的正则表达式,是实现增强的具体连接点的集合。
Aspect(切面) 切入点和通知的结合。
Introduction(引介) 一种特殊的通知,可以在运行期为类动态地添加一些方法或 Field。
Proxy(代理) 一个类被 AOP 织入增强后,就产生一个结果代理类。
Target(目标) 指代理的目标对象。
Weaving(织入) 把切面应用到目标对象,并创建代理对象的过程。

三、AOP流行框架比较

当下最流行的AOP框架为Spring AOP 及 AspectJ

比较 Spring AOP AspectJ
能力和目标 旨在通过Spring IoC提供一个简单的AOP实现。
不是一个完整的AOP解决方案,只能用于被Spring容器管理的bean。
完整的AOP解决方案,比Spirng AOP复杂。
能够被应用于所有的领域对象。
织入时机 只能在运行时织入 可以在编译时,加载期,编译后(jar包和字节码文件)。
依赖 使用JDK动态代理或者VGLIB动态代理。 不依赖任何运行时环境,只需要引入编译器AspectJ compiler(ajc)完成织入。
连接点 使用代理模式,所以不能作用于final类、static方法、final方法。
只支持方法执行连接点。
没有限制。方法调用,方法执行,构造器调用,构造器执行,静态初始化执行,对象初始化,成员引用,成员赋值,处理器执行,通知执行。
复杂度 不需要额外的编译器,只能和Spirng管理的bean一起工作 AOP 需要引入AJC编译器并重新打包
性能 基于代理的框架,运行时会有目标类的代理对象生成。 在应用执行前织入切面到代码中,没有额外的运行时开销。

四、动态代理

基于接口的动态代理
提供者:JDK官方的ava.lang.reflect.Proxy 类。
要求: 被代理类至少实现一个接口。

基于子类的动态代理
提供者:第三方的CGLib, CGLIB 要依赖于 ASM 的包。
要求:被代理类不能用final修饰的类(最终类)。

下面以一个例子来了解两者的差别:

1.创建接口UserDao
public interface UserDao {
   

    public void add();// 添加

    public void delete();// 删除
}
2.创建实现类 UserDaoImpl
public class UserDaoImpl implements UserDao {
   
    @Override
    public void add() {
   
        System.out.println("添加用户");
    }

    @Override
    public void delete() {
   
        System.out.println("删除用户");
    }
}
3.创建切面类MyAspect
public class MyAspect {
   
    public void myBefore() {
   
        System.out.println("方法执行之前...");
    }
    public void myAfter() {
   
        System.out.println("方法执行之后...");
    }
}
4.创建代理类 JdkBeanFactory

JDK动态代理实现原理

public class JdkBeanFactory {
   
    public static UserDao getBean() {
   
        // 准备目标类
        final UserDaoImpl userDao = new UserDaoImpl();
        // 创建切面类实例
        final MyAspect myAspect = new MyAspect();

        // 使用代理类,进行增强
        return (UserDao) Proxy.newProxyInstance(JdkBeanFactory.class.getClassLoader(),
                new Class[]{
   UserDao.class}, new InvocationHandler() {
   
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   
                        myAspect.myBefore(); // 前增强
                        Object obj = method.invoke(userDao, args);
                        myAspect.myAfter
  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值