SpringAOP中@EnableAspectJAutoProxy注解的作用

如果要使用SpringAOP的功能,必须要添加一个@EnableAspectJAutoProxy注解,有了这个注解才能支持@Aspect等相关的一系列AOP注解,这个注解就相当于在传统的xml配置文件中添加 <aop:aspectj-autoproxy>一样。

在学习SpringAOP相关的知识之前,建议一定要先搞清楚IOC相关的知识,如果不清楚的可以先阅读Spring专栏中IOC系列的文章。

接下来就来看一下@EnableAspectJAutoProxy注解到底做了什么?

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
    
    

	/**
	 * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
	 * to standard Java interface-based proxies. The default is {@code false}.
	 */
	boolean proxyTargetClass() default false;

	/**
	 * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
	 * for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
	 * Off by default, i.e. no guarantees that {@code AopContext} access will work.
	 * @since 4.3.1
	 */
	boolean exposeProxy() default false;

}

看到@Import注解,直接点进去

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.
	 */
	 //spring启动时,会调用到这个方法
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    
    
		//注册AnnotationAwareAspectJAutoProxyCreator
		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);
			}
		}
	}

}
	@Nullable
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    
    
		return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
	}

	@Nullable
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {
    
    
		
		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}
	@Nullable
	private static BeanDefinition registerOrEscalateApcAsRequired(
			Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
    
    

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
    
    
			BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
    
    
				int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
				int requiredPriority = findPriorityForClass(cls);
				if (currentPriority < requiredPriority) {
    
    
					apcDefinition.setBeanClassName(cls.getName());
				}
			}
			return null;
		}
		//把AnnotationAwareAspectJAutoProxyCreator封装成RootBeanDefinition
		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		//把需要spring管理的bean放入beanDefinitionMap和beanDefinitionNames,分别是一个map和list容器。
		//spring在实例化bean时,就会遍历容器中的bean然后依次处理。
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

可以看出@EnableAspectJAutoProxy注解最主要的作用实际上就是通过@Import注解把AnnotationAwareAspectJAutoProxyCreator这个对象注入到spring容器中。

先看一下AnnotationAwareAspectJAutoProxyCreator类的结构图
在这里插入图片描述

间接的实现了BeanPostProcessor接口,那么spring就能利用前置处理器、后置处理器完成一些事情了。

这部分代码来自ioc初始化bean对象的过程

	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    
    
		if (System.getSecurityManager() != null) {
    
    
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    
    
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
    
    
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
    
    
			//调动前置处理器
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
    
    
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
    
    
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
    
    
			//调动后置处理器
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
    
    

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
    
    
			//从刚刚的类图中可以看出AnnotationAwareAspectJAutoProxyCreator类或者继承类中,肯定有重写这个方法
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
    
    
				return result;
			}
			result = current;
		}
		return result;
	}

分析一下这段流程,AnnotationAwareAspectJAutoProxyCreator因为间接继承了抽象类AbstractAutoProxyCreator,而这个抽象类又间接实现了BeanPostPorcessor接口,所以在每个bean对象最后初始化的时候,通过postProcessAfterInitialization方法完成了AOP相关的处理。

本文就没有继续接着postProcessAfterInitialization方法继续深入,因为还是打算另起一篇文章着重分析,可以先下一个结论,这个方法就是扫描并解析aop注解的入口,如果当前bean对象符合配置的增加规则,最终就会返回实现增加方法的代理类。

猜你喜欢

转载自blog.csdn.net/CSDN_WYL2016/article/details/108886940