回首Spring源码之AOP:@EnableAspectJAutoProxy

前言

        AOP是spring的重点和难点,它的本质是用动态代理增强容器中bean的方法,本篇从基于注解的AOP开发方式开始分析。当你需要进行AOP切面编程时,首相要引入一个注解:@EnableAspectJAutoProxy。

@EnableAspectJAutoProxy

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
    //是否使用cglib动态代理,默认时false
	boolean proxyTargetClass() default false;
    //是否暴露代理到本地线程变量,默认false
	boolean exposeProxy() default false;
}

        可以看到在@Import中引入了AspectJAutoProxyRegistrar,这是一个ImportBeanDefinitionRegistrar,可以向spring容器注册一个BeanDefinition:

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {


	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		//注册aop相关的bean
		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);
			}
		}
	}
}

一路来到注册的代码:

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}


private static BeanDefinition registerOrEscalateApcAsRequired(
			Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

		//如果容器中已经有了名为AUTO_PROXY_CREATOR_BEAN_NAME的bean,则会根据优先级Priority选择是否覆盖
        //如果同时开启了aop和声明式事务会有两个bean,aop会覆盖声明式事务
		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;
		}

		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		//设置最高优先级
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        //注册BeanDefinition
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

        最终注册到容器中的bean为:AnnotationAwareAspectJAutoProxyCreator,这个bean会在spring容器加载时解析aspect切面,把切面中的方法解析为一个个通知器Advisor,并在bean的初始化后置调用中为bean创建代理对象。

总结

 @EnableAspectJAutoProxy这个注解是spirng AOP的入口,下篇将会详细分析解析切面的流程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值