1. 程式人生 > 實用技巧 >JAVA尚矽谷之Spring註解驅動原理

JAVA尚矽谷之Spring註解驅動原理

AOP註解原理

實現AOP切面需要做的三步

  • 1)將業務邏輯元件和切面類都加入到容器中,告訴Spring哪個是切面類(@Aspect)
    1. 在切面類上的每一個通知方法上標註通知註解,告訴Spring何時何地執行(切入點表示式)
    1. 開啟基於註解的aop模式,@EnableAspectJAutoProxy

第一步:看 @EnableAspectJAutoProxy做了什麼

配置類:
MainConfigOfAOP.java

@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {

    @Bean
    public MathCalculator calculator(){
        MathCalculator cal =  new MathCalculator();
        int i=0;
        return cal;
    }

    @Bean
    public LogAspects logAspects(){
        return new LogAspects();
    }
}

切面類
LogAspects.java

@Aspect
public class LogAspects {


    @Pointcut("execution(public int com.atguigu.aop.MathCalculator.*(..))")
   public void PointCut(){}


   @Before("PointCut()")
    public void  logStart(JoinPoint joinPoint){
       Object[] args = joinPoint.getArgs();
       System.out.println(joinPoint.getSignature().getName()+"執行,,,引數列表:{"+Arrays.asList(args) +"}");
    }
    @After("PointCut()")
    public void  logEnd(){
        System.out.println("除法結束");
    }
    @AfterReturning(value="PointCut()",returning = "result")
    public void  logReturn(Object result){
        System.out.println("除法正常返回。。執行結果:{"+result+"}");
    }
    @AfterThrowing(value = "PointCut()",throwing = "exception")
    public void  logException(Exception exception){
        System.out.println("除法執行異常");
    }

邏輯元件
MathCalculator.java

public class MathCalculator {
    public  int div(int i,int j)
    {
        System.out.println("計算結果:"+i/j);
        return  i/j;
    }
}

開始分析:

  • 進入nableAspectJAutoProxy,裡面需要@Import(AspectJAutoProxyRegistrar.class),會把AspectJAutoProxyRegistrar放入到容器中,跳轉到AspectJAutoProxyRegistrar
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	/**
	 * Register, escalate, and configure the AspectJ auto proxy creator based on the value
	 * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
	 * {@code @Configuration} class.
	 */
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
                //對AspectJAnnotationAutoProxyCreator的一個類進行註冊
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
               //......
      }
}

最終在AopConfigUtils中的方法內把
key為 org.springframework.aop.config.internalAutoProxyCreator
value為 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator 的bean定義
的鍵值 註冊到BeanDefinitionRegistry類中(此時只是註冊,還未例項化)

  • 看一下 AnnotationAwareAspectJAutoProxyCreator 的定義
    AnnotationAwareAspectJAutoProxyCreator:繼承關係
    AnnotationAwareAspectJAutoProxyCreator
    AspectJAwareAdvisorAutoProxyCreator
    AbstractAdvisorAutoProxyCreator
    AbstractAutoProxyCreator
    SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
    說明AnnotationAwareAspectJAutoProxyCreator本身是一個後置處理器,所有我們需要關注

    後置處理器(就是bean初始化前後做事情),自動裝配BeanFactory