SpringAOP源碼讀書筆記
1、首先配置類裏面需要加入註解EnableAspectJAutoProxy,後面的(proxyTargetClass = true)涉及到動態代理的類型後面會解釋
Configuration和ComponentScan以及Component註解這邊就不贅述了;
package com.aop; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy;import org.springframework.context.annotation.ImportResource; import org.springframework.stereotype.Component; @Configuration @Component("app") @ComponentScan("com.aop") @EnableAspectJAutoProxy//(proxyTargetClass = true) public class AopConfig { }
2、我們進入到EnableAspectJAutoProxy裏面可以看出這個類裏面通過@Import的形式註入了一個類:AspectJAutoProxyRegistrar;
@Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy {
3、進入到這個類發現他實現了我們大名鼎鼎的ImportBeanDefinitionRegistrar接口,熟悉Spring代碼的同學都知道;Spring初始化期間,會調用實現了ImportBeanDefinitionRegistrar的類裏面的registerBeanDefinitions方法,所以我們看這個方法:registerAspectJAnnotationAutoProxyCreatorIfNecessary
packageorg.springframework.context.annotation; import org.springframework.aop.config.AopConfigUtils; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata;
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { 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); } } } }
4、一直跟蹤這個函數我們會發現最終會執行到這個函數裏面:registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);會把AnnotationAwareAspectJAutoProxyCreator註冊到beanDefinitionMap裏面,名稱是:org.springframework.aop.config.internalAutoProxyCreator
@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; } RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
public static final String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
5、到這裏我們需要來看Spring實例化的過程了:首先會有一個測試類;annotationConfigApplicationContext.register(AopConfig.class);及其之前的代碼就不再解釋了,這邊就是創建了一個bean工廠(DefaultListableBeanFactory類型的),然後會向工廠裏面註冊我們的配置類以及6個類;
package com.aop; import com.config.AppConfig; import com.luban.dao.UserDao; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class TestAop { public static void main(String[] args) { AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(); annotationConfigApplicationContext.register(AopConfig.class); annotationConfigApplicationContext.refresh(); AopDao dao = (AopDao) annotationConfigApplicationContext.getBean("aopdao"); dao.test(); } }
6、我們來看annotationConfigApplicationContext.refresh();裏面執行的代碼邏輯(此處中間的邏輯只簡單的說明一下,主要看我們的AOP是如何實現的)
refresh方法裏面會執行invokeBeanFactoryPostProcessors(beanFactory);之前的方法都是做了一些初始化,這二個方法裏面完成了Bean的掃描並放到了beanDefinitionMap裏面;這個方法會在處理完Import的類以後結束;有關於Spring中間的實例化過程會在後面的文章中分享;讓我們看AOP的過程;
invokeBeanFactoryPostProcessors(beanFactory);
7、在對象創建完成以後會執行一個方法:這個方法傳入的參數是bean的name和實例化以後的對象以及BeanDefinition;在這個方法裏面會執行後置處理器的before和after方法,這邊會遍歷我們環境中的所有的後置處理器;其中有一個後置處理器是我們上面第4步的時候註冊進去的;看下面截圖:
exposedObject = initializeBean(beanName, exposedObject, mbd);
@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; } @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
當遍歷到這個後置處理器的時候,在postProcessAfterInitialization方法裏面,會通過wrapIfNecessary方法返回一個對象,進入到這個方法可以看出裏面調用了
@Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
進入到這個方法可以看出裏面調用了
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
來看一下createProxy方法:方法裏面前面的isProxyTargetClass()就是判斷配置類裏面的下面的這個註解後面是為true還是false
@EnableAspectJAutoProxy//(proxyTargetClass = true)
看這個方法裏面最後面一句:
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(getProxyClassLoader()); }
public Object getProxy(@Nullable ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); }
protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); }
下面這邊厲害了,請看代碼:這邊就解釋了為社麽SpringAOP動態代理有的時候用的是JDK,有的時候用的是CGLIB
@Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } //如果對象所屬的類是接口 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { //采用的是JDK動態代理 return new JdkDynamicAopProxy(config); } //采用的是CGLIB代理 return new ObjenesisCglibAopProxy(config); } else { //采用的是JDK動態代理 return new JdkDynamicAopProxy(config); } }
SpringAOP源碼讀書筆記