扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
本篇文章给大家分享的是有关Springboot中EnableAspectJAutoProxy的作用是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
创新互联2013年开创至今,先为廊坊等服务建站,廊坊等地企业,进行企业商务咨询服务。为廊坊企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
Spring Framwork
的两大核心技术就是IOC
和AOP
,AOP
在Spring
的产品线中有着大量的应用。如果说反射是你通向高级的基础,那么代理就是你站稳高级的底气。AOP
的本质也就是大家所熟悉的CGLIB
动态代理技术,在日常工作中想必或多或少都用过但是它背后的秘密值得我们去深思。本文主要从Spring AOP
运行过程上,结合一定的源码整体上介绍Spring AOP
的一个运行过程。知其然,知其所以然,才能更好的驾驭这门核心技术。
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Import({AspectJAutoProxyRegistrar.class}) public @interface EnableAspectJAutoProxy { //表明该类采用CGLIB代理还是使用JDK的动态代理 boolean proxyTargetClass() default false; /** * @since 4.3.1 代理的暴露方式:解决内部调用不能使用代理的场景 默认为false表示不处理 * true:这个代理就可以通过AopContext.currentProxy()获得这个代理对象的一个副本(ThreadLocal里面),从而我们可以很方便得在Spring框架上下文中拿到当前代理对象(处理事务时很方便) * 必须为true才能调用AopContext得方法,否则报错:Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available. */ boolean exposeProxy() default false; }
所有的EnableXXX
驱动技术都得看他的@Import
,所以上面最重要的是这一句@Import(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) { //表示强制指定了要使用CGLIB if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } //强制暴露Bean的代理对象到AopContext if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } } }
AspectJAutoProxyRegistrar
是一个项容器注册自动代理创建器
@Nullable public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); }
说明:spring
容器的注解代理创建器就是AnnotationAwareAspectJAutoProxyCreator
@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()); /** *用户注册的创建器,必须是InfrastructureAdvisorAutoProxyCreator *AspectJAwareAdvisorAutoProxyCreator,AnnotationAwareAspectJAutoProxyCreator之一 */ int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; } //若用户自己没有定义,那就用默认的AnnotationAwareAspectJAutoProxyCreator RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); //此处注意,增加了一个属性:最高优先级执行,后面会和@Async注解一起使用的时候起关键作用 beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
我们就成功的注入了一个Bean:AnnotationAwareAspectJAutoProxyCreator
基于注解的自动代理创建器
由此可见,Spring
使用BeanPostProcessor
让自动生成代理。基于BeanPostProcessor
的自动代理创建器的实现类,将根据一些规则在容器实例化Bean
时为匹配的Bean
生成代理实例。
AbstractAutoProxyCreator
是对自动代理创建器的一个抽象实现。最重要的是,它实现了SmartInstantiationAwareBeanPostProcessor
接口,因此会介入到Spring IoC
容器Bean
实例化的过程。
SmartInstantiationAwareBeanPostProcessor
继承InstantiationAwareBeanPostProcessor
所以它最主要的 职责是在bean
的初始化前,先会执行所有的InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
,谁第一个返回了不为null
的Bean
,后面就都不会执行了 。然后会再执行BeanPostProcessor#postProcessAfterInitialization
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); } } } return exposedObject; }
说明:这个方法是spring
的三级缓存中的其中一环,当你调用Object earlySingletonReference = getSingleton(beanName, false);
时候就会触发,其实还有一个地方exposedObject = initializeBean(beanName, exposedObject, mbd);
也会触发导致返回一个代理对象。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction
强调: 这2个地方虽然都有后置增强的作用,但是@Async
所使用的AsyncAnnotationBeanPostProcessor
不是SmartInstantiationAwareBeanPostProcessor
的实现类,所以此处会导致@Transactional
和@Async
处理循环依赖时候的不一致性。对于循环依赖后续会有单独章节进行分享。
以上就是Springboot中EnableAspectJAutoProxy的作用是什么,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注创新互联行业资讯频道。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流