通知方式
前置通知 @Before 在目标方法之前运行 后置通知 @After 在目标方法之后运行 返回通知 @AfterReturning 在目标方法正常返回之后运行 异常通知 @AfterThrowing 在目标方法异常运行之后执行 环绕通知 @Round 手动判断是哪个环节 使用方式
配置切面 @Aspect 告诉spring这是个切面类 写入通知方式
@Pointcut ( "execution(public int spring.demo.aop.CustomerPlus.*(..))" )
public void pointCut ( ) {
}
@Before ( "pointCut()" )
public void start ( JoinPoint joinPoint) {
Object [ ] args = joinPoint. getArgs ( ) ;
String className = joinPoint. getSignature ( ) . getDeclaringType ( ) . getSimpleName ( ) ;
String methodName = joinPoint. getSignature ( ) . getName ( ) ;
System . out. println ( "方法 : " + joinPoint. getSignature ( ) . getName ( ) + "计算入参" + Arrays . asList ( args) ) ;
}
@After ( "pointCut()" )
public void end ( JoinPoint joinPoint) {
System . out. println ( "方法 : " + joinPoint. getSignature ( ) . getName ( ) + "方法返回 end " ) ;
}
@AfterThrowing ( value = "pointCut()" , throwing = "exception" )
public void throwException ( JoinPoint joinPoint, Exception exception) {
System . out. println ( "方法 : " + joinPoint. getSignature ( ) . getName ( ) + "异常返回 throwException " + exception. getMessage ( ) ) ;
}
@AfterReturning ( value = "pointCut()" , returning = "result" )
public void AfterReturning ( JoinPoint joinPoint, Object result) {
System . out. println ( "方法 : " + joinPoint. getSignature ( ) . getName ( ) + "成功常返回 AfterReturning 返回值 " + result) ;
}
异常返回 需要添加 throwing = “exception” 方法签名须有一个Exception exception 来接收这个异常信息 正常返回 需要添加 returning = “result” 方法签名须有一个Object result 接收这个参数 开启注解 在配置类或者启动类上添加@EnableAspectJAutoProxy 告诉spring我要启用AOP
public class CustomerPlus {
public int abs(int a,int b){
return a/b;
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@EnableAspectJAutoProxy
@Configuration
public class CustomerConfig {
@Bean
public CustomerPlus customerPlus(){
return new CustomerPlus();
}
@Bean
public AopConfig aopConfig(){
return new AopConfig();
}
}
源码解析
AnnotationAwareAspectJAutoProxyCreator
AspectJAwareAdvisorAutoProxyCreator
AbstractAdvisorAutoProxyCreator
AbstractAutoProxyCreator [postProcessBeforeInstantiation]
ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
ProxyConfig Ordered, BeanClassLoaderAware [setBeanClassLoader], AopInfrastructureBean
BeanFactoryAware setBeanFacotry
SmartInstantiationAwareBeanPostProcessor [getEarlyBeanReference]获取对指定 Bean 的早期访问的引用,通常用于解析循环引用
InstantiationAwareBeanPostProcessor [postProcessBeforeInstantiation]目标方法初始化之前 [postProcessAfterInstantiation]目标方法初始化之后
BeanPostProcessor [postProcessBeforeInitialization] init-method方法执行前的处理器 [postProcessAfterInitialization] init-method方法执行后处理器
registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", AnnotationAwareAspectJAutoProxyCreator);
AbstractAutoProxyCreator.
AbstractAutoProxyCreator#postProcessBeforeInstantiation
AbstractAutoProxyCreator#postProcessAfterInitialization
AbstractAdvisorAutoProxyCreator#setBeanFactory
AnnotationAwareAspectJAutoProxyCreator#initBeanFactory
Aop 执行过程
1 start 创建容器 刷新容器
2:registerBeanPostProcessors 注册后置处理器
3:AbstractBeanFactory#doGetBean
4:AbstractAutowireCapableBeanFactory#doCreateBean
populateBean 属性赋值
initializeBean 初始化bean
invokeAwareMethods 调用awareMethod方法
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
applyBeanPostProcessorsBeforeInitialization 所有前置处理器 执行一遍
invokeInitMethods 执行初始化方法
invokeCustomInitMethod 执行用户自定义的init-method
applyBeanPostProcessorsAfterInitialization 执行后置处理器
5:
方法拦截过程
CglibAopProxy.DynamicAdvisedInterceptor#intercept
AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice
DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
获取拦截器链 前置通知,后置通知,异常返回通知,成功返回通知,环绕通知
new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)
构造一个CglibMethodInvocation对象执行proceed方法 递归方法
this.currentInterceptorIndex 开始是-1 每次++操作
AspectJAfterThrowingAdvice
AfterReturningAdviceInterceptor
MethodBeforeAdviceInterceptor
before 就是this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() ); return mi.proceed(); 先执行目标方法 再执行preceed方法