本篇文章給大家分享的是有關(guān)Springboot中EnableAspectJAutoProxy的作用是什么,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
創(chuàng)新互聯(lián)2013年開創(chuàng)至今,先為廊坊等服務(wù)建站,廊坊等地企業(yè),進行企業(yè)商務(wù)咨詢服務(wù)。為廊坊企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
Spring Framwork
的兩大核心技術(shù)就是IOC
和AOP
,AOP
在Spring
的產(chǎn)品線中有著大量的應(yīng)用。如果說反射是你通向高級的基礎(chǔ),那么代理就是你站穩(wěn)高級的底氣。AOP
的本質(zhì)也就是大家所熟悉的CGLIB
動態(tài)代理技術(shù),在日常工作中想必或多或少都用過但是它背后的秘密值得我們?nèi)ド钏?。本文主要?code>Spring AOP運行過程上,結(jié)合一定的源碼整體上介紹Spring AOP
的一個運行過程。知其然,知其所以然,才能更好的駕馭這門核心技術(shù)。
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Import({AspectJAutoProxyRegistrar.class}) public @interface EnableAspectJAutoProxy { //表明該類采用CGLIB代理還是使用JDK的動態(tài)代理 boolean proxyTargetClass() default false; /** * @since 4.3.1 代理的暴露方式:解決內(nèi)部調(diào)用不能使用代理的場景 默認為false表示不處理 * true:這個代理就可以通過AopContext.currentProxy()獲得這個代理對象的一個副本(ThreadLocal里面),從而我們可以很方便得在Spring框架上下文中拿到當前代理對象(處理事務(wù)時很方便) * 必須為true才能調(diào)用AopContext得方法,否則報錯:Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available. */ boolean exposeProxy() default false; }
所有的EnableXXX
驅(qū)動技術(shù)都得看他的@Import
,所以上面最重要的是這一句@Import(AspectJAutoProxyRegistrar.class)
,下面看看它
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { AspectJAutoProxyRegistrar() { } public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //注冊了一個基于注解的自動代理創(chuàng)建器 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
是一個項容器注冊自動代理創(chuàng)建器
@Nullable public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); }
說明:spring
容器的注解代理創(chuàng)建器就是AnnotationAwareAspectJAutoProxyCreator
@Nullable private static BeanDefinition registerOrEscalateApcAsRequired(Class> cls, BeanDefinitionRegistry registry, @Nullable Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); //這里如果我們自己定義了這樣一個自動代理創(chuàng)建器就是用我們自定義的 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()); /** *用戶注冊的創(chuàng)建器,必須是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); //此處注意,增加了一個屬性:最高優(yōu)先級執(zhí)行,后面會和@Async注解一起使用的時候起關(guān)鍵作用 beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
我們就成功的注入了一個Bean:AnnotationAwareAspectJAutoProxyCreator
基于注解的自動代理創(chuàng)建器
由此可見,Spring
使用BeanPostProcessor
讓自動生成代理?;?code>BeanPostProcessor的自動代理創(chuàng)建器的實現(xiàn)類,將根據(jù)一些規(guī)則在容器實例化Bean
時為匹配的Bean
生成代理實例。
AbstractAutoProxyCreator
是對自動代理創(chuàng)建器的一個抽象實現(xiàn)。最重要的是,它實現(xiàn)了SmartInstantiationAwareBeanPostProcessor
接口,因此會介入到Spring IoC
容器Bean
實例化的過程。
SmartInstantiationAwareBeanPostProcessor
繼承InstantiationAwareBeanPostProcessor
所以它最主要的 職責是在bean
的初始化前,先會執(zhí)行所有的InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
,誰第一個返回了不為null
的Bean
,后面就都不會執(zhí)行了 。然后會再執(zhí)行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
的三級緩存中的其中一環(huán),當你調(diào)用Object earlySingletonReference = getSingleton(beanName, false);
時候就會觸發(fā),其實還有一個地方exposedObject = initializeBean(beanName, exposedObject, mbd);
也會觸發(fā)導(dǎo)致返回一個代理對象。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction
強調(diào): 這2個地方雖然都有后置增強的作用,但是@Async
所使用的AsyncAnnotationBeanPostProcessor
不是SmartInstantiationAwareBeanPostProcessor
的實現(xiàn)類,所以此處會導(dǎo)致@Transactional
和@Async
處理循環(huán)依賴時候的不一致性。對于循環(huán)依賴后續(xù)會有單獨章節(jié)進行分享。
以上就是Springboot中EnableAspectJAutoProxy的作用是什么,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。