Spring aop的通知名称的问题?

发布于 2022-09-07 21:52:38 字数 241 浏览 17 评论 0

Spring AOP拦截器通知的名字如下:

MethodBeforeAdviceInterceptor (前置通知)
AspectJAfterThrowingAdvice (异常后通知)
AspectJAfterAdvice (最终通知)
AfterReturningAdviceInterceptor (后置通知)


请问大家,为什么有的以Interceptor结尾,而另一些以Advice结尾?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

恍梦境° 2022-09-14 21:52:38

楼上说的也不准确,这还是要从AOP联盟和规范说起,你可在spring-aop包下看到,两块东西,其中一块就是aop规范的接口,Rod Johnson只是把它集成了,没有打算重写和修改规范的意图,而其中除了一个Advice顶级接口和一个AdiceException剩下的主要以Interceptor结尾
spring aop其中部分通知接口继承了Advice接口但是自己又重新定义了,例如:org.springframework.aop.BeforeAdvice
而部分则采用aop规范的接口,例如:org.aopalliance.intercept.MethodInterceptor

图片描述

更新(2018-09-01):
我就再说多一点,首先不是所有通知都实现了MethodInterceptor(环绕通知)
前置通知:MethodBeforeAdviceBeforeAdvice只是继承了Advice
后置通知:AfterReturningAdviceAfterAdvice也只是继承了Advice
异常通知:ThrowsAdvice继承了AfterAdvice,也是一种后置通知
引介通知:IntroductionInterceptor才是继承了MethodInterceptor
从以上来看,命名还是很规范的,对吧,主要以advice为后缀

好了,再说Aspctj,织入是将增强添加到目标类的具体连接点上的过程。根据不同的实现技术,AOP有3种织入方式。
(1)编译期织入,这要求使用特殊的Java编译器。
(2)类装载期织入,这要求使用特殊的类装载器。
(3)动态代理织入,在运行期为目标类添加增强生成子类的方式。
Spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。

Spring AOP无意将Aspectj拒之门外,而是采取了兼收并蓄的方式,即继承了Aspectj的表达式语法来定义切点和增强(你可以简单理解为通知),所以一般要用AOP的话除了引入spring-aop.jar的包还会引用aspecj.weaver.jar(或者aspect.tools.jar,后者包含前者)来引入语法相关的工具(一些注解和接口,例如@Before),一般我们有若干方式来启用Aspectj,但主要就是注解和配置两种,当然了,对应到容器中主要还是实体类,而这些类主要以Aspectj为前缀,例如AspectJMethodBeforeAdviceAspectJExpressionPointcutAdvisor(注意,Advisor不用于Advice)

/**
 * 注解
 */
@Aspect
@Component
public class UserAdvice {

  @Before("execution(* *UserByName(..))")
  public void before() {
    System.err.println("before...");
  }
}

/**
 * xml配置
 */
<aop:config>
    <aop:aspect ref="**">
        <aop:before pointcut="execution(* *UserByName(..))" method="**">
    </aop:aspect>
</aop:config>
``
当梦初醒 2022-09-14 21:52:38

这两种并不都是通知
以Interceptor结尾的类主要是org.aopalliance.intercept.MethodInterceptor接口的实现类,在MethodBeforeAdviceInterceptor源码中可以看到:

/**
 * Interceptor to wrap am {@link org.springframework.aop.MethodBeforeAdvice}.
 * Used internally by the AOP framework; application developers should not need
 * to use this class directly.
 *
 * @author Rod Johnson
 */
@SuppressWarnings("serial")
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
    private MethodBeforeAdvice advice;
    ...
}

可以看到在MethodBeforeAdviceInterceptor中就包含了一个MethodBeforeAdvice,并且在注释里坐着建议不要直接使用这个类
因为这一种'Interceptor'用于生成代理对象,即实际上通过cglib生成的代理类,就是这货。
MethodBeforeAdvice这类'advice'才是你所说的通知,一些操作比如切面判断,执行对应的代理方法等操作就是在里面实现的。

之前我正好有写到模拟实现spring的AOP的功能,你感兴趣可以看看:
实现AOP
引入aspectj实现AOP切点
加强AOP功能

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文