AOP的两种实现-Spring AOP以及AspectJ

本文深入探讨了AOP的两种实现,包括Spring AOP的基于代理和CGLIB的方式,以及AspectJ的静态织入。通过案例分析了Spring AOP在动态代理中的局限性,解释了如何强制使用CGLIB。同时,文章介绍了AspectJ的织入原理和与Spring AOP的差异,强调了AspectJ在AOP功能上的优势。
摘要由CSDN通过智能技术生成

1. 前言

注解是个很奇妙的存在,为什么加上了@Transactional之后,方法会在一个事务的上下文中被执行呢?为什么加上了@Cacheable之后,方法的返回值会被记录到缓存中,从而让下次的重复调用能够直接利用缓存的结果呢?

随着对AOP的逐渐应用和了解,才明白注解只是一个表象,在幕后Spring AOP/AspectJ做了大量的工作才得以实现这些神奇的功能。

2. 基于代理(Proxy)的AOP实现

@Component
public class SampleBean {
    
  public void advicedMethod() {
    
  }

  public void invokeAdvicedMethod() {
    
    advicedMethod();
  }
}

@Aspect
@Component
public class SampleAspect {
    
  @Before("execution(void advicedMethod())")
  public void logException() {
    
    System.out.println("Aspect被调用了");
  }
}

sampleBean.invokeAdvicedMethod(); // 会打印出 "Aspect被调用了" 吗?

SampleBean扮演的就是目标方法所在Bean的角色,而SampleAspect扮演的则是Advice的角色。很显然,被AOP修饰过的方法是advicedMethod(),而非invokeAdvicedMethod()。然而,invokeAdvicedMethod()方法在内部调用了advicedMethod()。那么会打印出来Advice中的输出吗?

答案是不会。

这是在使用Spring AOP的时候可能会遇到的一个问题。类似这种间接调用不会触发Advice的原因在于调用发生在目标方法所在Bean的内部,和外面的代理对象可是没有半毛钱的关系哦。我们可以把这个代理想象成一个中介,只有它知道Advice的存在,调用者Bean和目标方法所在Bean知道彼此的存在,但是对于代理或者是Advice却是一无所知的。因此,没有通过代理的调用是绝无可能触发Advice的逻辑的。

3. Spring AOP的两种实现方式

  • 基于接口的动态代理(Dynamic Proxy)
  • 基于子类化的CGLIB代理

我们在使用Spring AOP的时候,一般是不需要选择具体的实现方式的。Spring AOP能根据上下文环境帮助我们选择一种合适的。那么是不是每次都能够这么”智能”地选择出来呢?也不尽然,下面的例子就反映了这个问题:


public interface SampleInterface {
    }

@Component
public class SampleBean implements SampleInterface {
    
  public void advicedMethod() {
    
  }

  public void invokeAdvicedMethod() {
    
    advicedMethod();
  }
}

在上述代码中,我们为原来的Bean实现了一个新的接口SampleInterface,这个接口中并没有定义任何方法。这个时候,再次运行相关测试代码的时候就会出现异常.从异常信息来看并不明显,实际上这个问题的根源在于Spring AOP在创建代理的时候出现了问题。
这个问题的根源可以在这里得到一些线索:

Spring AOP defaults to using standard JDK dynamic proxies for AOP proxies. This enables any interface (or set of interfaces) to be proxied.
Spring AOP can also use CGLIB proxies. This is necessary to proxy classes rather than interfaces. CGLIB is used by default if a business object does not implement an interface. As it is good practice to program to interfaces rather than classes; business classes norma

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值