Spring基于注解形式的 AOP的原理流程及源码解析(四)
2017-11-06 10:07
1026 查看
我们接着上篇博客继续讲。在上篇博客中,讲述的是正在实例化的Bean的beanClass和Spring容器内所有的切面Advisor进行匹配的过程。这个过程如果返回了匹配上的Advisor(一个或多个),则表明这个Bean应该被代理;如果返回的结果为空,则这个Bean不会被代理。
代码块1
AbstractAdvisorAutoProxyCreator有对切面排序的方法,不过其子类AspectJAwareAdvisorAutoProxyCreator重写了排序方法,正常应该调用其子类的方法
代码块2
常量DEFAULT_PRECEDENCE_COMPARATOR是一个AspectJPrecedenceComparator对象,查看其排序的规则:
代码块3
接着上文将,合适的切面已经找到了,而且添加了一个头节点,对切面进行了排序,接下里就需要使用切面和Bean对象动态生成代理对象了:
代码块4
通过代理工厂ProxyFactory生成代理实例:
代码块5
接下去的就是通过Bean和Advisors生成代理对象了,很多都是CGLIB的代码,很晦涩麻烦,就不讲了。
接下来将一些通过CGLIB实现AOP的其他的知识点。
通过CGLIB生成的代理对象,持有原始Bean对象,同时继承自原始BeanClass
动态生成的对象的类名上含有 $$ 符号,所以判断一个对象是不是CGLIB生成的代理对象就看其类名上是否含有$$,详情看ClassUtils.isCglibProxy(Object)方法
当通过Advisors和Bean生成代理对象时,每一个Advisor会以MethodInterceptor的形式保存在代理对象中,每调用一个原始Bean的方法,均会触发所有的Advisor方法,而不仅仅是匹配注解表达式的方法,比如toString()
JDK Proxy生成的动态代理对象类名以Proxy$+数字组成,代理对象继承自Proxy对象,实现了被代理对象的接口。数字代表着是jdk动态代理生成的第几个代理对象。
代码块1
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator { protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { List<Advisor> candidateAdvisors = findCandidateAdvisors(); //如果这一步返回的结果不是空集合,则表明有匹配上的切面Advisor List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); //对返回的切面集合做拓展 extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { //对切面集合做排序 eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; } protected void extendAdvisors(List<Advisor> candidateAdvisors) { //将ExposeInvocationInterceptor.ADVISOR实例加入到切面集合的首位元素,这个元素在生成AOP对象是要用到 AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors); } }
AbstractAdvisorAutoProxyCreator有对切面排序的方法,不过其子类AspectJAwareAdvisorAutoProxyCreator重写了排序方法,正常应该调用其子类的方法
代码块2
public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator { //按Ordered接口及@Order的序号值来作为排序的准则 protected List<Advisor> sortAdvisors(List<Advisor> advisors) { AnnotationAwareOrderComparator.sort(advisors); return advisors; } } public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator { private static final Comparator<Advisor> DEFAULT_PRECEDENCE_COMPARATOR = new AspectJPrecedenceComparator(); protected List<Advisor> sortAdvisors(List<Advisor> advisors) { List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors = new ArrayList<PartiallyComparableAdvisorHolder>(advisors.size()); for (Advisor element : advisors) { partiallyComparableAdvisors.add( //主要看DEFAULT_PRECEDE 4000 NCE_COMPARATOR它的排序规则 new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR)); } List<PartiallyComparableAdvisorHolder> sorted = PartialOrder.sort(partiallyComparableAdvisors); if (sorted != null) { List<Advisor> result = new ArrayList<Advisor>(advisors.size()); for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) { result.add(pcAdvisor.getAdvisor()); } return result; } else { return super.sortAdvisors(advisors); } } }
常量DEFAULT_PRECEDENCE_COMPARATOR是一个AspectJPrecedenceComparator对象,查看其排序的规则:
代码块3
class AspectJPrecedenceComparator implements Comparator<Advisor> { private static final int HIGHER_PRECEDENCE = -1; private static final int SAME_PRECEDENCE = 0; private static final int LOWER_PRECEDENCE = 1; public AspectJPrecedenceComparator() { this.advisorComparator = AnnotationAwareOrderComparator.INSTANCE; } public int compare(Advisor o1, Advisor o2) { //先根据@Order及Ordered的序号比较 int advisorPrecedence = this.advisorComparator.compare(o1, o2); //如果没有这两个条件,返回的优先级相同,则按另一种规则比较 //Advisor实例是InstantiationModelAwarePointcutAdvisorImpl类型,所以declaredInSameAspect符合条件 if (advisorPrecedence == SAME_PRECEDENCE && declaredInSameAspect(o1, o2)) { advisorPrecedence = comparePrecedenceWithinAspect(o1, o2); } return advisorPrecedence; } private int comparePrecedenceWithinAspect(Advisor advisor1, Advisor advisor2) { //看InstantiationModelAwarePointcutAdvisorImpl的determineAdviceType()方法 //@After,@AfterReturning,@AfterThrowing这三个注解是afterAdvice boolean oneOrOtherIsAfterAdvice = (AspectJAopUtils.isAfterAdvice(advisor1) || AspectJAopUtils.isAfterAdvice(advisor2)); //Order按@Around, @Before, @After, @AfterReturning, @AfterThrowing的顺序 int adviceDeclarationOrderDelta = getAspectDeclarationOrder(advisor1) - getAspectDeclarationOrder(advisor2); if (oneOrOtherIsAfterAdvice) { // the advice declared last has higher precedence //排序是对待织入一个Bean的多个切面进行排序,这些切面可能分布在不同的切面定义类里,也可能有多个切面定义在同一个类里 //afterAdvice有着比其他的advice更高的优先级,@After, @AfterReturning, @AfterThrowing这三个按倒序排列 //@Around, @Before这两个注解顺序排序,afterAdvice排在正常的advice前面 //排序后的顺序应该是:@AfterThrowing,@AfterReturning,@After,@Around,@Before //顺序可能不正确,大家可以自己测试下,从代码上看是如此的 if (adviceDeclarationOrderDelta < 0) { // advice1 was declared before advice2 // so advice1 has lower precedence return LOWER_PRECEDENCE; } else if (adviceDeclarationOrderDelta == 0) { return SAME_PRECEDENCE; } else { return HIGHER_PRECEDENCE; } } else { // the advice declared first has higher precedence if (adviceDeclarationOrderDelta < 0) { // advice1 was declared before advice2 // so advice1 has higher precedence return HIGHER_PRECEDENCE; } else if (adviceDeclarationOrderDelta == 0) { return SAME_PRECEDENCE; } else { return LOWER_PRECEDENCE; } } } }
接着上文将,合适的切面已经找到了,而且添加了一个头节点,对切面进行了排序,接下里就需要使用切面和Bean对象动态生成代理对象了:
代码块4
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (beanName != null && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); //找到了合适的切面数组 if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //开始创建代理对象 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } protected Object createProxy( Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } ProxyFactory proxyFactory = new ProxyFactory(); //拷贝AOP配置,@EnableAspectJAutoProxy的proxyTargetClass值等 proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } //如果有Advisor等类型的Bean,则实例化,加入Advisor数组,排在有注解生成的Advisor的前端 Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); for (Advisor advisor : advisors) { proxyFactory.addAdvisor(advisor); } proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(getProxyClassLoader()); } }
通过代理工厂ProxyFactory生成代理实例:
代码块5
public class ProxyFactory extends ProxyCreatorSupport { public Object getProxy(ClassLoader classLoader) { //createAopProxy()一般生成ObjenesisCglibAopProxy实例 return createAopProxy().getProxy(classLoader); } 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."); } //如果被代理的Class是一个接口,或者被代理类是一个Proxy代理生成的类,则生成JdkDynamicAopProxy(一般不会) if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } } }
接下去的就是通过Bean和Advisors生成代理对象了,很多都是CGLIB的代码,很晦涩麻烦,就不讲了。
接下来将一些通过CGLIB实现AOP的其他的知识点。
通过CGLIB生成的代理对象,持有原始Bean对象,同时继承自原始BeanClass
动态生成的对象的类名上含有 $$ 符号,所以判断一个对象是不是CGLIB生成的代理对象就看其类名上是否含有$$,详情看ClassUtils.isCglibProxy(Object)方法
当通过Advisors和Bean生成代理对象时,每一个Advisor会以MethodInterceptor的形式保存在代理对象中,每调用一个原始Bean的方法,均会触发所有的Advisor方法,而不仅仅是匹配注解表达式的方法,比如toString()
JDK Proxy生成的动态代理对象类名以Proxy$+数字组成,代理对象继承自Proxy对象,实现了被代理对象的接口。数字代表着是jdk动态代理生成的第几个代理对象。
相关文章推荐
- Spring基于注解形式的 AOP的原理流程及源码解析(一)
- Spring基于注解形式的 AOP的原理流程及源码解析(二)
- Spring基于注解形式的 AOP的原理流程及源码解析(三)
- Spring核心框架 - AOP的原理及源码解析
- (八)Spring核心框架 - AOP的原理及源码解析
- Spring IOC和Spring AOP的实现原理(源码主线流程)
- 深入剖析Spring Web源码(九) - 处理器映射,处理器适配器以及处理器的实现 - 基于注解控制器流程的实现
- Spring AOP源码解析——AOP动态代理原理和实现方式
- spring源码解析-AOP原理
- Spring源码解析之四 ------ AOP原理和源码分析
- Spring IOC和Spring AOP的实现原理(源码主线流程)
- Spring IOC和Spring AOP的实现原理(源码主线流程)
- Spring源码解析-基于注解依赖注入
- Spring IOC和Spring AOP的实现原理(源码主线流程)
- spring AOP 源码解析 及其实现原理
- Spring核心框架 - AOP的原理及源码解析
- 关于spring IOC和AOP的解析原理和举例
- spring源码分析之——spring aop原理
- 最简单的动态代理实例(spring基于接口代理的AOP原理)
- spring boot 源码解析14-默认错误页面处理流程, 自定义,及EnableAutoConfigurationImportSelector处理