思考: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源码深度解析