思考:spring
1.何時建立代理類對象express
2.SpringAop中如何綜合運用CGLIB和JDK動態代理設計模式
@EnableAspectJAutoProxy:開啓AOP的權限
注入到Spring容器中緩存
ImportBeanDefinitionRegistrar手動註冊Bean對象框架
在前幾章中提過,實現ImportBeanDefinitionRegistrar這個接口,能夠本身手動註冊一些Bean到Spring容器中ide
AspectJAutoProxyRegistrar實現了ImportBeanDefinitionRegistrar就能夠手動註冊Bean對象函數
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //這裏手動註冊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) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)null);
}
對於AOP的實現,基本上都是靠AnnotationAwareAspectJAutoProxyCreator去完成的,它能夠根據@Point註解定義的切點來自動代理相匹配的bean。源碼分析
可是爲了配置簡便,Spring使用了自定義配置來幫助咱們自動註冊AnnotationAwareAspectJAutoProxyCreator,其註冊過程就是在這裏實現的。post
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) { 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()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { //改變Bean最重要的就是改變bean所對應的屬性className屬性 apcDefinition.setBeanClassName(cls.getName()); } } //若是已經存在自動代理建立器而且與將要建立的一致,那麼無須再次建立 return null; } else { RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", -2147483648); beanDefinition.setRole(2); registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition); return beanDefinition; } }
以上代碼實現了自動註冊AnnotationAwareAspectJAutoProxyCreator類的功能,同時這裏還涉及到了一個優先級的問題,優化
若是已經存在了自動代理建立器,並且存在的自動代理建立器與如今的不一致,那麼須要根據優先級來判斷到底使用哪個。
綜上:總結下
1.@EnableAspectJAutoProxy:開啓AOP的權限
2.@Import(AspectJAutoProxyRegistrar.class)注入到容器中,手動註冊切面類
3.AnnotationAwareAspectJAutoProxyCreator須要將這個類注入到IOC容器中
4.registerBeanDefinition註冊Bean信息內容:
##BeanId=org.springframework.aop.config.internalAutoProxyCreator
##class:AnnotationAwareAspectJAutoProxyCreator
咱們打印下注冊的Bean
1無參構造函數....說明對象初開始始化了
2執行自定義bean的init方法
beanDefinitionNames[i]:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
beanDefinitionNames[i]:org.springframework.context.annotation.internalAutowiredAnnotationProcessor
beanDefinitionNames[i]:org.springframework.context.annotation.internalRequiredAnnotationProcessor
beanDefinitionNames[i]:org.springframework.context.annotation.internalCommonAnnotationProcessor
beanDefinitionNames[i]:org.springframework.context.event.internalEventListenerProcessor
beanDefinitionNames[i]:org.springframework.context.event.internalEventListenerFactory
beanDefinitionNames[i]:myConfig
beanDefinitionNames[i]:memberServiceImpl
beanDefinitionNames[i]:payService
beanDefinitionNames[i]:loginAop
beanDefinitionNames[i]:org.springframework.aop.config.internalAutoProxyCreator //這個就是咱們分析注入的Bean
後面咱們須要瞭解SpringAOP底層是如何實現的 離不開AnnotationAwareAspectJAutoProxyCreator
下面看看AnnotationAwareAspectJAutoProxyCreator類圖結構
在類圖中,咱們看到:AnnotationAwareAspectJAutoProxyCreator的祖宗是BeanPostProcessors接口,而實現BeanPostProcessor後,當Spring加載這個Bean時會在實例化前調用其postProcessorAfterInitialization方法。
BeanPostProcessors是對咱們的Bean的初始化方法實現加強。由Java多態,可知AnnotationAwareAspectJAutoProxyCreator也是能夠實現對Bean初始化方法加強。
因此AnnotationAwareAspectJAutoProxyCreator本質就是對init方法實現加強
public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {//init方法前置處理 return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {//init方法後置處理 return bean; } }
AnnotationAwareAspectJAutoProxyCreator的前置和後置在AbstractAutoProxyCreator實現類中實現
AbstractAutoProxyCreator的BeanPostProcessor後置處理器的前置處理器:沒作任何事
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
AbstractAutoProxyCreator的BeanPostProcessor後置處理器的後置處理器:具體作事情,使用後置處理器實現代理對象的建立
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException { if (bean != null) { //根據給定的bean的class和name構建出一個key,格式:beanClassName_beanName Object cacheKey = this.getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { //若是它適合被代理,則須要封裝指定的Bean return this.wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { //若是已經處理過 if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; //無需加強 } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; //給定的bean類是否表明一個基礎設施類,基礎設施類不該被代理,或者配置了指定bean不須要自動代理 } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) { //若是存在加強方法則建立代理 Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null); //若是獲取到了加強則須要針對加強建立代理 if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //建立代理 Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } else { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } } else { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } }
函數中咱們已經看到了代理建立的雛形。固然真正開始以前還須要通過一些判斷,好比是否已經處理過或者是不是須要跳過的bean,而真正建立代理的代碼是從getAdvicesAndAdvisorsForBean開始的。
建立代理主要包含兩個步驟:
1.獲取加強方法或者加強器
2.根據獲取的加強進行代理
雖然看似簡單,可是每一個步驟中都經歷了大量複雜的邏輯。首先來看看獲取加強方法的實現邏輯
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) { List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName); return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray(); }
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { List<Advisor> candidateAdvisors = this.findCandidateAdvisors();//獲取全部的加強 List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);//尋找全部加強中適用於bean的加強並應用 this.extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = this.sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
對於指定bean的加強方法的獲取必定是包含兩個步驟的,獲取全部的加強以及尋找全部加強中適用於bean的加強並應用,那麼findCandidateAdvisors與findAdvisorsThatCanApply即是作了這兩件事情。
固然若是沒法找到對應的加強器便返回DO_NOT_PROXY,其中DO_NOT_PROXY=null
因爲咱們分析的是使用註解進行的AOP,因此對於findCandidateAdvisors的實現實際上是由AnnotationAwareAspectJAutoProxyCreator類完成 的,
咱們繼續跟蹤AnnotationAwareAspectJAutoProxyCreator的findCandidateAdvisors方法。
protected List<Advisor> findCandidateAdvisors() { //當使用註解方式配置AOP的時候並非丟棄了對XML配置的支持 //這裏調用父類方法加載配置文件中的AOP聲明 List<Advisor> advisors = super.findCandidateAdvisors(); if (this.aspectJAdvisorsBuilder != null) { advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors; }
在真正研究代碼以前能夠本身嘗試去想一想解析思路,看看本身的實現與Spring的實現是否有差異?咱們先看看函數提供的大概功能框架,讀者能夠嘗試實現這些功能點,看看是否有思路
一、獲取全部beanName,,這一步驟中全部在beanFactory中註冊的bean都會被提起出來。
二、遍歷全部beanName,並找出聲明AspectJ註解的類,進行進一步的處理
三、對標記爲AspectJ註解的類進行加強器的提取
四、將提取結果加入緩存
如今咱們進入buildAspectJAdvisors函數實現,對Spring中全部類進行分析,提取Advisor
public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = this.aspectBeanNames; if (aspectNames == null) { synchronized(this) { aspectNames = this.aspectBeanNames; if (aspectNames == null) { List<Advisor> advisors = new LinkedList(); List<String> aspectNames = new LinkedList(); //獲取全部的beanName String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false); String[] var18 = beanNames; int var19 = beanNames.length; //循環全部的beanName找出對應的加強方法 for(int var7 = 0; var7 < var19; ++var7) { String beanName = var18[var7]; //不合法的bean則略過,由子類定義規則,默認返回true if (this.isEligibleBean(beanName)) { Class<?> beanType = this.beanFactory.getType(beanName); //若是存在Aspect註解 if (beanType != null && this.advisorFactory.isAspect(beanType)) { aspectNames.add(beanName); AspectMetadata amd = new AspectMetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); //解析標記爲AspectJ註解中加強的方法 List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); .... } this.aspectBeanNames = aspectNames; return advisors; } } } if (aspectNames.isEmpty()) { return Collections.emptyList(); } else { //記錄在緩存中 List<Advisor> advisors = new LinkedList(); .... } }
至此咱們已經完成看Advisor的提取,在上面的步驟中最爲重要的也最爲繁雜的就是加強的獲取。而這一功能委託給了this.advisorFactory.getAdvisors(factory);方法去實現
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { //獲取標記爲AspectJ的類 Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); //獲取標記爲AspectJ的name String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); //驗證 this.validate(aspectClass); MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List<Advisor> advisors = new LinkedList(); Iterator var6 = this.getAdvisorMethods(aspectClass).iterator(); while(var6.hasNext()) { Method method = (Method)var6.next(); Advisor advisor = this.getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { advisors.add(advisor); } } if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { //若是尋找的加強器不爲空並且配置了加強延遲初始化,那麼須要在首位加入同步實例化加強器 Advisor instantiationAdvisor = new ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } Field[] var12 = aspectClass.getDeclaredFields(); int var13 = var12.length; for(int var14 = 0; var14 < var13; ++var14) { Field field = var12[var14]; //獲取DeclareParents註解 Advisor advisor = this.getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; }
函數中首先完成了對加強器的獲取,包括獲取註解以及根據註解生成加強的步驟,而後考慮到在配置中可能會將加強配置成延遲初始化,那麼須要在首位加入同步實例化加強器以保證加強使用以前的實例化,
最後是對DeclareParents註解的獲取,下面詳細介紹下每一個步驟:
實現步驟包括對切點的註解的獲取以及根據註解信息生成加強
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) { this.validate(aspectInstanceFactory.getAspectMetadata().getAspectClass()); //切點信息的獲取 AspectJExpressionPointcut expressionPointcut = this.getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); //根據切點信息生成加強器 return expressionPointcut == null ? null : new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName); }
切點信息的獲取。所謂獲取切點信息就是指定註解的表達式信息的獲取,如:@Around("loginAop()")
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) { //獲取方法上的註解 AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); if (aspectJAnnotation == null) { return null; } else { //使用AspectJExpressionPointcut實例封裝獲取的信息 AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class[0]); //提取獲得的註解中的表達式,如: @Pointcut("execution (* com.mayikt.service..*.*(..))")中的execution (* com.mayikt.service..*.*(..)) ajexp.setExpression(aspectJAnnotation.getPointcutExpression()); if (this.beanFactory != null) { ajexp.setBeanFactory(this.beanFactory); } return ajexp; } }
protected static AbstractAspectJAdvisorFactory.AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) { //設置敏感的註解類 Class<?>[] classesToLookFor = new Class[]{Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class}; Class[] var2 = classesToLookFor; int var3 = classesToLookFor.length; for(int var4 = 0; var4 < var3; ++var4) { Class<?> c = var2[var4]; AbstractAspectJAdvisorFactory.AspectJAnnotation<?> foundAnnotation = findAnnotation(method, c); if (foundAnnotation != null) { return foundAnnotation; } } return null; }
private static <A extends Annotation> AbstractAspectJAdvisorFactory.AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) { //獲取指定方法上的註解並使用AspectJAnnotation封裝 A result = AnnotationUtils.findAnnotation(method, toLookFor); return result != null ? new AbstractAspectJAdvisorFactory.AspectJAnnotation(result) : null; }
根據切點信息生成加強。全部的加強都由Advisor的實現類InstantiationModelAwarePointcutAdvisorImpl統一封裝
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { .... if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Pointcut preInstantiationPointcut = Pointcuts.union(aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut); this.pointcut = new InstantiationModelAwarePointcutAdvisorImpl.PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory); this.lazy = true; } else { this.pointcut = this.declaredPointcut; this.lazy = false; this.instantiatedAdvice = this.instantiateAdvice(this.declaredPointcut); } }
在封裝過程當中只是簡單的將信息封裝在類的實例中,全部的信息單純的賦值,在實例化過程當中還完成了對於加強器的初始化。由於不一樣的加強所體現的邏輯是不一樣的,
好比@Before("test()")與@After("test()")標籤的不一樣就是加強器加強的位置不一樣,因此就須要不一樣的加強器來完成不一樣的邏輯,而根據註解中的信息初始化對應的加強器就是在instantiateAdvice函數中實現的。
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return advice != null ? advice : EMPTY_ADVICE;
}
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { .... Object springAdvice; //根據不一樣的註解類型封裝不一樣的加強器 switch(aspectJAnnotation.getAnnotationType()) { case AtBefore: springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtAfter: springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtAfterReturning: springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterReturning afterReturningAnnotation = (AfterReturning)aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterReturningAnnotation.returning())) { ((AbstractAspectJAdvice)springAdvice).setReturningName(afterReturningAnnotation.returning()); } break; case AtAfterThrowing: springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); AfterThrowing afterThrowingAnnotation = (AfterThrowing)aspectJAnnotation.getAnnotation(); if (StringUtils.hasText(afterThrowingAnnotation.throwing())) { ((AbstractAspectJAdvice)springAdvice).setThrowingName(afterThrowingAnnotation.throwing()); } break; case AtAround: springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory); break; case AtPointcut: if (this.logger.isDebugEnabled()) { this.logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'"); } return null; default: throw new UnsupportedOperationException("Unsupported advice type on method: " + candidateAdviceMethod); } .... }
從函數中能夠看出,Spring會根據不一樣的註解生成不一樣的加強器,例如AtBefore會對應AspectJMethodBeforeAdvice,而在AspectJMethodBeforeAdvice中完成了加強方法的邏輯。
咱們先分析幾個經常使用的加強器實現:
咱們首先看下MethodBeforeAdviceInterceptor 類的內部實現
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable { //表明前置加強的AspectJMethodBeforeAdvice private MethodBeforeAdvice advice; public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } public Object invoke(MethodInvocation mi) throws Throwable { this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); return mi.proceed(); } }
跟蹤before方法
public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null);
}
protected Object invokeAdviceMethod(@Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex) throws Throwable {
return this.invokeAdviceMethodWithGivenArgs(this.argBinding(this.getJoinPoint(), jpMatch, returnValue, ex));
}
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable { Object[] actualArgs = args; if (this.aspectJAdviceMethod.getParameterCount() == 0) { actualArgs = null; } try { ReflectionUtils.makeAccessible(this.aspectJAdviceMethod); //激活加強方法 return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs); } catch (IllegalArgumentException var4) { throw new AopInvocationException("Mismatch on arguments to advice method [" + this.aspectJAdviceMethod + "]; pointcut expression [" + this.pointcut.getPointcutExpression() + "]", var4); } catch (InvocationTargetException var5) { throw var5.getTargetException(); } }
invokeAdviceMethodWithGivenArgs方法中的aspectJAdviceMethod正是對於前置加強的方法,在這裏實現了調用
後置加強與前置加強不同,前置加強是在攔截器鏈中放置MethodBeforeAdviceInterceptor,而在MethodBeforeAdviceInterceptor中又放置了AspectJMethodBeforeAdvice,並在調用invoke時首先串聯調用。
可是在後置加強的時候卻不同,沒有提供中間的類,而是直接在攔截器鏈中使用了中間的AspectJAfterAdvice。
public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice, Serializable { public AspectJAfterAdvice(Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) { super(aspectJBeforeAdviceMethod, pointcut, aif); } public Object invoke(MethodInvocation mi) throws Throwable { Object var2; try { var2 = mi.proceed(); } finally { //激活加強的方法 this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null); } return var2; } public boolean isBeforeAdvice() { return false; } public boolean isAfterAdvice() { return true; } }
getAdvisor方法走完了,又回到咱們的getAdvisors方法
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { //獲取標記爲AspectJ的類 Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); //獲取標記爲AspectJ的name String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); //驗證 this.validate(aspectClass); MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List<Advisor> advisors = new LinkedList(); Iterator var6 = this.getAdvisorMethods(aspectClass).iterator(); while(var6.hasNext()) { Method method = (Method)var6.next(); Advisor advisor = this.getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { advisors.add(advisor); } } if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { //若是尋找的加強器不爲空並且配置了加強延遲初始化,那麼須要在首位加入同步實例化加強器 Advisor instantiationAdvisor = new ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } Field[] var12 = aspectClass.getDeclaredFields(); int var13 = var12.length; for(int var14 = 0; var14 < var13; ++var14) { Field field = var12[var14]; //獲取DeclareParents註解 Advisor advisor = this.getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; }
protected static class SyntheticInstantiationAdvisor extends DefaultPointcutAdvisor { public SyntheticInstantiationAdvisor(final MetadataAwareAspectInstanceFactory aif) { super(aif.getAspectMetadata().getPerClausePointcut(), new MethodBeforeAdvice() { //目標方法前調用,相似Before public void before(Method method, Object[] args, @Nullable Object target) { //簡單初始化aspect aif.getAspectInstance(); } }); } }
private Advisor getDeclareParentsAdvisor(Field introductionField) { DeclareParents declareParents = (DeclareParents)introductionField.getAnnotation(DeclareParents.class); if (declareParents == null) { return null; } else if (DeclareParents.class == declareParents.defaultImpl()) { throw new IllegalStateException("'defaultImpl' attribute must be set on DeclareParents"); } else { //使用DeclareParentsAdvisor對功能進行封裝 return new DeclareParentsAdvisor(introductionField.getType(), declareParents.value(), declareParents.defaultImpl()); } }
前面的函數中已經完成了全部加強器的解析,可是對於全部的加強器來說,並不必定都適用於當前的bean,還要跳出適合的加強器,也就是知足咱們配置的通配符的加強器。
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { List<Advisor> candidateAdvisors = this.findCandidateAdvisors(); //過濾已經獲得的Advisors List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); this.extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = this.sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
繼續看findAdvisorsThatCanApply:
protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
List var4;
try {
var4 = AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
} finally {
ProxyCreationContext.setCurrentProxiedBeanName((String)null);
}
return var4;
}
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } else { List<Advisor> eligibleAdvisors = new LinkedList(); Iterator var3 = candidateAdvisors.iterator(); //首先處理引介加強 while(var3.hasNext()) { Advisor candidate = (Advisor)var3.next(); if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } boolean hasIntroductions = !eligibleAdvisors.isEmpty(); Iterator var7 = candidateAdvisors.iterator(); while(var7.hasNext()) { Advisor candidate = (Advisor)var7.next(); //對於普通bean的處理 if (!(candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; }
具體作事的方法
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) { if (advisor instanceof IntroductionAdvisor) { return ((IntroductionAdvisor)advisor).getClassFilter().matches(targetClass); } else if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pca = (PointcutAdvisor)advisor; return canApply(pca.getPointcut(), targetClass, hasIntroductions); } else { return true; } }
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
if (!pc.getClassFilter().matches(targetClass)) {
return false;
} else {
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
return true;
} else {
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher)methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
classes.add(targetClass);
Iterator var6 = classes.iterator();
while(var6.hasNext()) {
Class<?> clazz = (Class)var6.next();
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
Method[] var9 = methods;
int var10 = methods.length;
for(int var11 = 0; var11 < var10; ++var11) {
Method method = var9[var11];
if (introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) || methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
}
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
在獲取全部bean的加強器後,即可以進行代理的建立了。
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 (this.shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { //添加代理接口 this.evaluateProxyInterfaces(beanClass, proxyFactory); } } Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors); //加入加強器 proxyFactory.addAdvisors(advisors); //設置須要代理的類 proxyFactory.setTargetSource(targetSource); //定製代理 this.customizeProxyFactory(proxyFactory); //用來控制代理工廠被配置後,是否還運行修改通知,默認false,不容許修改代理的配置 proxyFactory.setFrozen(this.freezeProxy); if (this.advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(this.getProxyClassLoader()); }
對於代理類建立及處理過程,Spring委託給了proxyFactory去處理,而在此函數中主要是對proxyFactory的初始化操做,進而對真正的建立代理作準備。
這些初始化的步驟以下:
一、獲取當前類的屬性
二、添加代理接口
三、封裝Advisor並加入到proxyFactory中
四、設置要代理的類
五、固然在Spring中還爲子類提供了定製函數customizeProxyFactory,子類能夠在此函數中進行對proxyFactory的進一步封裝。
六、進行獲取代理操做
得到五個通知
建立代理類
public Object getProxy(@Nullable ClassLoader classLoader) {
return this.createAopProxy().getProxy(classLoader);
}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
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.");
} else {
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
至此,咱們已經完成 代理的建立,無論咱們以前是否閱讀過Spring源代碼,可是都是或多或少聽過Spring的代理中JDKProxy的實現和CGLIBProxy的實現。
Spring是如何選取的呢?
if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config))
從if中的判斷條件能夠看到3個方面影響Spring的判斷
Optimize:用來控制CGLIB建立過程的代理是否使用激進的優化策略。除非徹底瞭解AOP代理如何優化處理,不然不推薦用戶使用這個配置。目前這個屬性僅用於CGLIB代理,對於JDK動態代理(默認代理)無效。
ProxyTargetClas:這個屬性爲true時,目標類自己被代理而不是目標類的接口。若是這個屬性值設置爲true,CGLIB代理將會被建立
hasNoUserSuppliedProxyInterfaces:是否存在代理接口
一、配置@EnableAspectJAutoProxy:開啓AOP權限
二、@Import(AspectJAutoProxyRegistrar.class):往IOC容器中注入SpringAOP切面類
三、registerAspectJAnnotationAutoProxyCreatorIfNecessary():註冊切面類
四、AnnotationAwareAspectJAutoProxyCreator.class:註冊到IOC容器中,【AOP的入口】
五、AnnotationAwareAspectJAutoProxyCreator:祖宗是BeanPostProcessor接口,而實現BeanPostProcessor接口後,當Spring加載這個Bean會在實例化前調用其後置處理器實現加強
六、postProcessAfterInitialization:後置處理器【AOP實現核心邏輯】
####6.一、wrapIfNecessary()判斷該對象是否在AOP的掃包範圍內,真正建立代理類的地方
#########6.1.一、getAdvicesAndAdvisorsForBean建立代理對象包括獲取加強方法和根據獲取的加強進行代理
#########6.1.二、createAopProxy()判斷被代理類是否實現了接口,若是有實現了接口的化,是採用JDK動態代理,不然狀況下就使用CGLIB代理
####6.二、根據條件判斷使用JdkDynamicAopProxy或者JdkDynamicAopProxy方法實現代理
####6.三、最終執行目標方法的時候,就會進入到JdkDynamicAopProxy 的invoke方法或者JdkDynamicAopProxy的intercept方法【後面講解】
####6.五、底層使用集合存放使用通知,而後再使用責任鏈設計模式循環的調用【後面講解】
本文參考:
參考書籍:Spring源碼深度解析