javascript
动态代理以及对应Spring中AOP源码分析
AOP(面向切面編程)在Spring中是被廣泛應(yīng)用的(例如日志,事務(wù),權(quán)限等),而它的基本原理便是動(dòng)態(tài)代理。
我們知道動(dòng)態(tài)代理有兩種:基于JDK的動(dòng)態(tài)代理以及基于CGlib動(dòng)態(tài)代理。以下是兩種動(dòng)態(tài)代理的實(shí)現(xiàn)方式:
1 //JDK動(dòng)態(tài)代理 2 public class JDKProxy implements InvocationHandler { 3 4 private Object object;// 被代理人 5 6 //這里的目標(biāo)類(lèi)型為Object,則可以接受任意一種參數(shù)作為被代理類(lèi),實(shí)現(xiàn)了動(dòng)態(tài)代理。但是要注意下面的newProxyInstance()中的參數(shù) 7 public Object getInstance(Object object) { 8 this.object = object; 9 //與cglib的區(qū)別在于這里構(gòu)建代理對(duì)象的時(shí)候需要傳入被代理對(duì)象的接口對(duì)象,第二個(gè)參數(shù)。而cglib不需要被代理對(duì)象實(shí)現(xiàn)任何接口即可 10 return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this); 11 } 12 13 //代理對(duì)象真正調(diào)用的方法 14 @Override 15 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 16 System.out.println("doSomething---------start"); 17 method.invoke(object, args); 18 System.out.println("doSomething---------end"); 19 return null; 20 } 21 22 } 23 24 //CGlib動(dòng)態(tài)代理 25 public class CglibProxy implements MethodInterceptor { 26 private Object targetObject; 27 28 // 這里的目標(biāo)類(lèi)型為Object,則可以接受任意一種參數(shù)作為被代理類(lèi),實(shí)現(xiàn)了動(dòng)態(tài)代理 29 public Object getInstance(Object target) { 30 this.targetObject = target; 31 Enhancer enhancer = new Enhancer(); 32 enhancer.setSuperclass(target.getClass()); 33 enhancer.setCallback(this); 34 //注意該處代理的創(chuàng)建過(guò)程 35 Object proxyObj = enhancer.create(); 36 return proxyObj;// 返回代理對(duì)象 37 } 38 39 //代理對(duì)象真正調(diào)用的方法 40 @Override 41 public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { 42 Object obj = null; 43 System.out.println("doSomething---------start"); 44 obj = method.invoke(targetObject, args); 45 System.out.println("doSomething---------end"); 46 return obj; 47 } 48 49 } View Code具體兩種動(dòng)態(tài)代理的差異在網(wǎng)上有很多各個(gè)方面的比較,在這里我就不再贅述。下面我再說(shuō)說(shuō)在Spring?5.0.3.RELEASE中實(shí)現(xiàn)AOP的原理(我的github中也有詳細(xì)的源碼注釋)。
在注解版的Spring AOP當(dāng)中我們會(huì)有如下的代碼配置,其中@EnableAspectJAutoProxy便是開(kāi)啟AOP支持的關(guān)鍵。
1 @EnableAspectJAutoProxy //開(kāi)啟基于注解的AOP模式 2 @Configuration 3 @ComponentScan(value = {"com.aop"}) 4 public class AnnotationAopConfig { 5 6 @Bean("student") 7 public Student getStudent() { //把我們普通的Java Bean定義出來(lái)交給IOC容器管理 8 return new Student(); 9 } 10 11 @Bean 12 public LogAspect getLogAspect() { //定義切面類(lèi) 13 return new LogAspect(); 14 } 15 }我們跟蹤一下@EnableAspectJAutoProxy的源碼來(lái)看看它的定義,會(huì)發(fā)現(xiàn)它利用@Import導(dǎo)入了AspectJAutoProxyRegistrar.class組件:代碼塊一
由AspectJAutoProxyRegistrar.Class的定義可知其實(shí)現(xiàn)了ImportBeanDefinitionRegistrar接口,所以在IOC容器初始化的時(shí)候會(huì)調(diào)用該類(lèi)的registerBeanDefinitions方法。通過(guò)觀察該方法實(shí)現(xiàn),我們可以看到一行關(guān)鍵的代碼AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);:代碼塊二
這行代碼中所需要注冊(cè)的到底是什么東西呢?我們進(jìn)一步一探究竟。在持續(xù)跟入代碼的過(guò)程中我們可以找到這么一塊代碼:return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);:代碼塊三
觀察源碼可以得知,該方法會(huì)將AnnotationAwareAspectJAutoProxyCreator類(lèi)封裝為一個(gè)RootBeanDefinition然后添加到BeanDefinition的注冊(cè)類(lèi)當(dāng)中以AUTO_PROXY_CREATOR_BEAN_NAME。我們也可以找到關(guān)于AUTO_PROXY_CREATOR_BEAN_NAME的定義:代碼塊四
我們?cè)俜治鲆幌翧nnotationAwareAspectJAutoProxyCreator.Class的源碼,看看此類(lèi)到底有何特別之處。觀察源碼我們可以發(fā)現(xiàn)AnnotationAwareAspectJAutoProxyCreator是BeanPostPrcsessor的子類(lèi):代碼塊五
?
1 /**********************代碼塊一***********************/ 2 3 @Target(ElementType.TYPE) 4 @Retention(RetentionPolicy.RUNTIME) 5 @Documented 6 @Import(AspectJAutoProxyRegistrar.class) //導(dǎo)入AspectJAutoProxyRegistrar組件 7 public @interface EnableAspectJAutoProxy { 8 /**********************代碼塊二***********************/ 9 class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { 10 11 @Override 12 public void registerBeanDefinitions( 13 AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { 14 15 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); //如果需要的話注冊(cè)AspectJAnnotationAutoProxy 16 /**********************代碼塊三***********************/ 17 @Nullable 18 public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, 19 @Nullable Object source) { 20 21 return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); 22 } 23 /**********************代碼塊四***********************/ 24 /** 25 * The bean name of the internally managed auto-proxy creator. 26 */ 27 public static final String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator"; 28 private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, 29 @Nullable Object source) { 30 31 Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); 32 33 if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { 34 BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); 35 if (!cls.getName().equals(apcDefinition.getBeanClassName())) { 36 int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); 37 int requiredPriority = findPriorityForClass(cls); 38 if (currentPriority < requiredPriority) { 39 apcDefinition.setBeanClassName(cls.getName()); 40 } 41 } 42 return null; 43 } 44 45 RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); 46 beanDefinition.setSource(source); 47 beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); 48 beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); 49 registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);//注冊(cè) 50 return beanDefinition; 51 } 52 /**********************代碼塊五***********************/ 53 AnnotationAwareAspectJAutoProxyCreator 54 AnnotationAwareAspectJAutoProxyCreator 55 extends AspectJAwareAdvisorAutoProxyCreator 56 extends AbstractAdvisorAutoProxyCreator 57 extends AbstractAutoProxyCreator 58 extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware 59 extends ...InstantiationAwareBeanPostProcessor Ordered 60 extends BeanPostProcessor?
從以上代碼,我們可以知道@EnableAspectJAutoProxy大概做了這么一件事:將AnnotationAwareAspectJAutoProxyCreator.Class以名為“org.springframework.aop.config.internalAutoProxyCreator”的方式完成注冊(cè)BeanDefinition的操作。
然后我們?cè)倏纯催@塊內(nèi)容對(duì)Spring容器啟動(dòng)過(guò)程的影響。
我們以下面的代碼為入口進(jìn)行分析:代碼塊一
我們進(jìn)入IOC容器初始化過(guò)程看看對(duì)于進(jìn)行了切面操作的類(lèi)來(lái)說(shuō)經(jīng)歷了哪些操作,通過(guò)斷點(diǎn)我們可以跟蹤到此代碼處:PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);這里是實(shí)例化各種BeanPostProcessor,并將其實(shí)例存放在BeanFactory當(dāng)中:代碼塊二(當(dāng)中代碼我挑出重要的部分。更加詳細(xì)的Spring源碼說(shuō)明,請(qǐng)關(guān)注我的github)。
注冊(cè)了BeanPostProcessor的實(shí)例,我們看看普通Bean對(duì)象的創(chuàng)建。跟蹤源碼可知:通過(guò)finishBeanFactoryInitialization等一系列方法的調(diào)用到getBean(beanName);方法之中,在getBean(beanName);后續(xù)的調(diào)用之中又經(jīng)過(guò)了查詢(xún)緩存,實(shí)例化依賴(lài)等一系列操作來(lái)到了createBean這個(gè)方法當(dāng)中,我們可以通過(guò)代碼詳細(xì)分析其處理。我們可以找到Object beanInstance = doCreateBean(beanName, mbdToUse, args); 獲取Bean實(shí)例的地方。 再跟進(jìn)去看它的實(shí)現(xiàn):代碼塊三
我們現(xiàn)在觀察doCreateBean(beanName, mbdToUse, args); 源碼,其中實(shí)現(xiàn)了移除緩存、創(chuàng)建實(shí)例、初始化實(shí)例等一系列操作,其中在exposedObject = initializeBean(beanName, exposedObject, mbd);中變有我們需要的關(guān)鍵信息。:代碼塊四
initializeBean(beanName, exposedObject, mbd);這個(gè)方法里面有applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);和applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);兩個(gè)方法的調(diào)用。這里面的原理是獲取所有的beanPostProcessors遍歷調(diào)用其postProcessBeforeInitialization和postProcessAfterInitialization方法。這里我就不過(guò)多的贅述了。調(diào)試代碼我們可以發(fā)現(xiàn)后續(xù)的調(diào)用鏈如下AbstractAutoProxyCreator#postProcessAfterInitialization-->AbstractAutoProxyCreator#wrapIfNecessary。在這里我們就可以判斷其是否擁有增強(qiáng)器來(lái)創(chuàng)建代理對(duì)象,我們可以通過(guò)下面代碼來(lái)觀察其邏輯(增強(qiáng)器便是代理對(duì)象的各個(gè)方法封裝起來(lái)的對(duì)象):代碼塊五
進(jìn)入代理構(gòu)建入口Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));以下便是通過(guò)默認(rèn)的GClib來(lái)進(jìn)行對(duì)象的一個(gè)封裝。其代理封裝的對(duì)象如下:代碼塊六
1 /**********************代碼塊一***********************/ 2 @Test 3 public void test3() { 4 AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnotationAopConfig.class); //初始化IOC容器 5 String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames(); 6 7 Student student = (Student) applicationContext.getBean("student");//從容器中獲取對(duì)象 8 student.innerMethod(); //進(jìn)行方法調(diào)用 9 applicationContext.close(); 10 } 11 /**********************代碼塊二***********************/ 12 public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { 13 /** 14 * IOC:stepA6-1 獲取到所有已經(jīng)定義了的,需要?jiǎng)?chuàng)建實(shí)例的所有實(shí)現(xiàn)BeanPostProcessor的類(lèi) 15 * org.springframework.context.annotation.internalAutowiredAnnotationProcessor 16 * org.springframework.context.annotation.internalRequiredAnnotationProcessor 17 * org.springframework.aop.config.internalAutoProxyCreator 18 */ 19 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); 20 .... 21 /** 22 * 分離實(shí)現(xiàn)了PriorityOrdered、Ordered和rest接口的BeanPostProcessors 23 * 按順序注冊(cè)BeanPostProcessors 24 */ 25 List<String> orderedPostProcessorNames = new ArrayList<>(); 26 List<String> nonOrderedPostProcessorNames = new ArrayList<>(); 27 for (String ppName : postProcessorNames) { 28 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { //如果是PriorityOrdered的子類(lèi) 29 .... 30 } 31 else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { //AOP 匹配internalAutoProxyCreator,添加到orderedPostProcessorNames集合當(dāng)中 32 orderedPostProcessorNames.add(ppName); 33 } 34 else { 35 nonOrderedPostProcessorNames.add(ppName); 36 } 37 } 38 // 首先, 注冊(cè)實(shí)現(xiàn)PriorityOrdered接口的BeanPostProcessors 39 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); 40 registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); 41 // Next, register the BeanPostProcessors that implement Ordered. 42 List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(); 43 for (String ppName : orderedPostProcessorNames) { 44 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); //實(shí)例化internalAutoProxyCreator 45 orderedPostProcessors.add(pp); 46 if (pp instanceof MergedBeanDefinitionPostProcessor) { 47 internalPostProcessors.add(pp);//將internalAutoProxyCreator實(shí)例放進(jìn)去 48 } 49 } 50 sortPostProcessors(orderedPostProcessors, beanFactory); 51 registerBeanPostProcessors(beanFactory, orderedPostProcessors); //將BeanPostProcessor注冊(cè)到BeanFactory 52 .... 53 } 54 /**********************代碼塊三***********************/ 55 56 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 57 throws BeanCreationException { 58 .... 59 60 try { 61 // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. 62 //IOC:stepA10 給BeanPostProcessor一個(gè)機(jī)會(huì)返回一個(gè)代理實(shí)例代替Bean實(shí)例 63 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 64 if (bean != null) { 65 return bean; 66 } 67 } 68 catch (Throwable ex) { 69 throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, 70 "BeanPostProcessor before instantiation of bean failed", ex); 71 } 72 73 try { 74 Object beanInstance = doCreateBean(beanName, mbdToUse, args); //創(chuàng)建Bean實(shí)例 75 if (logger.isDebugEnabled()) { 76 logger.debug("Finished creating instance of bean '" + beanName + "'"); 77 } 78 return beanInstance; 79 } 80 catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { 81 .... 82 } 83 } 84 /**********************代碼塊四***********************/ 85 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) 86 throws BeanCreationException { 87 // Instantiate the bean. 88 BeanWrapper instanceWrapper = null; 89 if (mbd.isSingleton()) { //如果是單例,從factoryBean實(shí)例緩存中移除 90 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); 91 } 92 if (instanceWrapper == null) { 93 instanceWrapper = createBeanInstance(beanName, mbd, args);//創(chuàng)建實(shí)例 94 } 95 .... 96 //緩存bean解決循環(huán)引用 97 .... 98 // Initialize the bean instance. 99 //初始化bean實(shí)例 100 Object exposedObject = bean; 101 try { 102 populateBean(beanName, mbd, instanceWrapper); //為Bean的屬性賦值 103 exposedObject = initializeBean(beanName, exposedObject, mbd); //初始化對(duì)象 104 } 105 .... 106 } 107 /**********************代碼塊五***********************/ 108 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { 109 if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { 110 return bean; 111 } 112 if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { 113 return bean; 114 } 115 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { 116 this.advisedBeans.put(cacheKey, Boolean.FALSE); 117 return bean; 118 } 119 120 // Create proxy if we have advice. 121 //如果有增強(qiáng)器的話就創(chuàng)建代理 122 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); 123 if (specificInterceptors != DO_NOT_PROXY) { 124 this.advisedBeans.put(cacheKey, Boolean.TRUE); 125 Object proxy = createProxy( 126 bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));//創(chuàng)建AOP代理對(duì)象 127 this.proxyTypes.put(cacheKey, proxy.getClass()); 128 return proxy; 129 } 130 131 this.advisedBeans.put(cacheKey, Boolean.FALSE); 132 return bean; 133 } 134 /**********************代碼塊六***********************/ 135 private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable { 136 137 private final AdvisedSupport advised; 138 139 public DynamicAdvisedInterceptor(AdvisedSupport advised) { 140 this.advised = advised; 141 } 142 143 @Override 144 @Nullable 145 public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { 146 Object oldProxy = null; 147 boolean setProxyContext = false; 148 Object target = null; 149 TargetSource targetSource = this.advised.getTargetSource(); 150 try { 151 if (this.advised.exposeProxy) { 152 // Make invocation available if necessary. 153 oldProxy = AopContext.setCurrentProxy(proxy); 154 setProxyContext = true; 155 } 156 // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool... 157 target = targetSource.getTarget(); 158 Class<?> targetClass = (target != null ? target.getClass() : null); 159 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);//根據(jù)將要執(zhí)行的目標(biāo)方法獲取攔截器鏈 160 Object retVal; 161 // Check whether we only have one InvokerInterceptor: that is, 162 // no real advice, but just reflective invocation of the target. 163 if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { 164 // We can skip creating a MethodInvocation: just invoke the target directly. 165 // Note that the final invoker must be an InvokerInterceptor, so we know 166 // it does nothing but a reflective operation on the target, and no hot 167 // swapping or fancy proxying. 168 Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); 169 retVal = methodProxy.invoke(target, argsToUse); 170 } 171 else { 172 // We need to create a method invocation... 173 retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();//執(zhí)行攔截器鏈 174 } 175 retVal = processReturnType(proxy, target, method, retVal); 176 return retVal; 177 } 178 finally { 179 if (target != null && !targetSource.isStatic()) { 180 targetSource.releaseTarget(target); 181 } 182 if (setProxyContext) { 183 // Restore old proxy. 184 AopContext.setCurrentProxy(oldProxy); 185 } 186 } 187 } 188 }?
?
下面我們可以通過(guò)調(diào)試代碼的方式來(lái)探究攔截器的調(diào)用。在這里攔截器是通過(guò)鏈?zhǔn)秸{(diào)用的方法按照順序依次執(zhí)行,我們可以通過(guò)時(shí)序圖來(lái)很好的發(fā)現(xiàn)其調(diào)用邏輯。
好了,不知道通過(guò)源碼閱讀大家有沒(méi)有對(duì)Spring AOP有了一個(gè)全新的認(rèn)識(shí)呢?有任何疑問(wèn)歡迎留言喔~
?
轉(zhuǎn)載于:https://www.cnblogs.com/HuaiyinMarquis/p/9146779.html
總結(jié)
以上是生活随笔為你收集整理的动态代理以及对应Spring中AOP源码分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: kubernetes入门指南(一)
- 下一篇: java 基于tcp客户端服务端发送接收