zoukankan      html  css  js  c++  java
  • 面向切面编程AOP[二](java @EnableAspectJAutoProxy 代码原理)

    前言

    @EnableAspectJAutoProxy 是启动aop功能的意思,那么里面是什么呢?

    正文

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import({AspectJAutoProxyRegistrar.class})
    public @interface EnableAspectJAutoProxy {
        boolean proxyTargetClass() default false;
    
        boolean exposeProxy() default false;
    }
    

    在这个接口中,又导入了AspectJAutoProxyRegistrar.class,看下这个是啥。

    class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
        AspectJAutoProxyRegistrar() {
        }
    
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
            AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
            if (enableAspectJAutoProxy != null) {
                if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                }
    
                if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                    AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
                }
            }
    
        }
    }
    

    AspectJAutoProxyRegistrar 是来实现接口,ImportBeanDefinitionRegistrar。

    重点就是ImportBeanDefinitionRegistrar,这个告诉了我们这个东西将会为我们注入一些服务,而我们需要明白的就是到底注册了一个什么服务,然后服务又是如何运行的。

    AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

    表示的是,是否注册一个AspectJAnnotationAutoProxy,其实这里我们可以猜到大概是要将这个AspectJAnnotationAutoProxy注入到容器中。

    继续进去看下:

    @Nullable
    private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
    	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    	if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
    		BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
    		if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
    			int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
    			int requiredPriority = findPriorityForClass(cls);
    			if (currentPriority < requiredPriority) {
    				apcDefinition.setBeanClassName(cls.getName());
    			}
    		}
    
    		return null;
    	} else {
    		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    		beanDefinition.setSource(source);
    		beanDefinition.getPropertyValues().add("order", -2147483648);
    		beanDefinition.setRole(2);
    		registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
    		return beanDefinition;
    	}
    }
    

    这里可以说明了,我们大概要注册一个类型为:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator的东西了。

    上面if里面判断为,是否有一个org.springframework.aop.config.internalAutoProxyCreator的注册类型,然后去获取到类型对应的服务的class 是否为cls.getName(),也就是AnnotationAwareAspectJAutoProxyCreator。

    如果没有,那么会到根容器中或注入。

    当注册完之后,那么又会去干一些什么呢?

    AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
    if (enableAspectJAutoProxy != null) {
    	if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
    		AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
    	}
    
    	if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
    		AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
    	}
    }
    

    这时候就是去判断一些属性,然后做一些事情。

    那么其实应该重点关注AnnotationAwareAspectJAutoProxyCreator,到底为我们提供了一些什么服务,然后再来分析它有一些什么属性,能为我们带来什么。

    下一节

    AnnotationAwareAspectJAutoProxyCreator 为我们提供了什么服务。

  • 相关阅读:
    [转贴]35岁之前成功12条法则
    any type,any name
    The quick brown fox jumps over the lazy dog.
    [总结]软件工程师笔试题目(C++)
    [转]IOCP介绍
    A simple IOCP Server/Client Class
    Flash for Linux
    看看你是否需要更新SYMBOL文件了??
    [转贴]The Code Project Visual C++ Forum FAQ
    (搜集)一些少走弯路的话语+参考信息
  • 原文地址:https://www.cnblogs.com/aoximin/p/12953584.html
Copyright © 2011-2022 走看看