事务源码(二)中,已经分析了beanDefinition的加载,下面来创建对应beanDefinition的bean。
1、PropertySourcesPlaceholderConfigurer 创建占位符处理的bean
PropertySourcesPlaceholderConfigurer实现了BeanFactoryPostProcessor、PriorityOrdered接口,在IOC容器刷新过程中,invokeBeanFactoryPostProcessors处理实现了BeanFactoryPostProcessor接口的bean,实例化核心伪代码 PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors1 public static void invokeBeanFactoryPostProcessors( 2 ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { 3 4 // 将已经执行过的BFPP存储在processedBeans中,防止重复执行 5 Set<String> processedBeans = new HashSet<>(); 6 7 // 找到所有实现BeanFactoryPostProcessor接口的类 8 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); 9 10 // 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor 11 List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); 12 13 // 遍历postProcessorNames,将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开 14 for (String ppName : postProcessorNames) { 15 // 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor到priorityOrderedPostProcessors 16 // 此处通过 getBean->doGetBean->createBean->DoCreateBean创建PropertySourcesPlaceholderConfigurer对象 17 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); 18 } 19 20 // 对实现了PriorityOrdered接口的BeanFactoryPostProcessor进行排序 21 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); 22 23 // 遍历实现了PriorityOrdered接口的BeanFactoryPostProcessor,执行postProcessBeanFactory方法 24 // 对于 PropertySourcesPlaceholderConfigurer 来说,是遍历每一个beanDefinition中的占位符 25 invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); 26 37 }
2、AspectJAwareAdvisorAutoProxyCreator 创建自动动态代理创建器bean
AspectJAwareAdvisorAutoProxyCreator实现了BeanPostProcessor接口,在IOC容器刷新过程中,registerBeanPostProcessors(beanFactory)方法处理实现BeanPostProcessor接口的bean,创建详情在AOP源码(三):创建AOP相关的Bean中有描述,此处不再赘述。
3、AspectJExpressionPointcutAdvisor 创建事务通知Advisor
Advisor与其他bean之间的依赖关系:在AOP源码(三):创建AOP相关的Bean中提到Advisor的创建是在创建首个普通bean标签的对象实例化之前处理的,本次案例中就是在创建dataSource实例化之前处理的,即AbstractAutowireCapableBeanFactory#createBean-》AbstractAutowireCapableBeanFactoryresolveBeforeInstantiation处理的。
AspectJExpressionPointcutAdvisor的创建时机已明确,那么Advisor中的属性对象是在何时触发创建的呢?在事务源码(二):beanDefinition的准备-配置文件加载中提到pointcut-ref、advice-ref被设置在Advisor的beanDefinition的propertyValues属性中,而propertyValues中内容是在bean实例化完成之后,完成bean属性填充时需要用到,按照这个思路看看Advisor在属性填充做了什么事情?
AbstractAutowireCapableBeanFactory#populateBean bean属性填充,核心伪代码1 // 填充属性 2 protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { 3 4 //如果mdb有PropertyValues就获取其PropertyValues 5 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); 6 7 //如果pvs不为null 8 if (pvs != null) { 9 //应用给定的属性值,解决任何在这个bean工厂运行时其他bean的引用 (RuntimeBeanReference) 10 applyPropertyValues(beanName, mbd, bw, pvs); 11 } 12 }
1、Advisor属性填充核心流程图
2、Advisor属性填充核心伪代码
AbstractAutowireCapableBeanFactory#applyPropertyValues 使用propertyValues属性完成bean的填充核心伪代码1 // 解析Value 2 public Object resolveValueIfNecessary(Object argName, @Nullable Object value) { 3 4 // 如果value是RuntimeBeanReference实例,创建bean对象并返回 5 if (value instanceof RuntimeBeanReference) { 6 //将value强转成RuntimeBeanReference对象 7 RuntimeBeanReference ref = (RuntimeBeanReference) value; 8 //解析出对应ref所封装的Bean元信息(即Bean名,Bean类型)的Bean对象: 9 return resolveReference(argName, ref); 10 } 11 12 // 如果value是RuntimeBeanNameReference实例,获取引用的Bean名称字符串 13 else if (value instanceof RuntimeBeanNameReference) { 14 //从value中获取引用的Bean名 15 String refName = ((RuntimeBeanNameReference) value).getBeanName(); 16 //对refName进行解析,然后重新赋值给refName 17 refName = String.valueOf(doEvaluate(refName)); 18 19 //返回经过解析且经过检查其是否存在于Bean工厂的引用Bean名【refName】 20 return refName; 21 } 22 23 }
AspectJExpressionPointcutAdvisor创建完成,在缓存singletonObject查看创建详情,pointcut属性已填充完成,但advice属性确为null。在上面的分析中,propertyValues中key为adviceBeanName的value为RuntimeBeanNameReference类型,只返回了advice-ref的属性值myAdvice,并未对创建Advice相关的bean。
那么Advice是在哪里创建的呢?
我们接着往下分析,在Spring中若对哪个方法开启了事务,则这个方法所在的类必须要被代理,利用AOP的环绕通知、异常通知来处理事务的开启、提交和回滚操作。在AOP源码(四):创建被代理类的代理对象中提到,在创建被代理类的代理对象createProxy时,会添加一个ExoseInvocationInterceptor的Advice,组装AOP执行链,ExoseInvocationInterceptor的Advice用作AOP执行流程 - 责任链控制器。在创建ProductDao或ProductService的bean对象,创建代理对象时会不会创建TransactionInterceptor的Advice对象,并将该Advice对象设置进Advisor中呢?4、TransactionInterceptor 创建事务通知Advice
被代理类的代理对象,是在初始化被代理类的后置处理器applyBeanPostProcessorsAfterInitialization中创建的。4.1、Advice创建核心流程图
4.2、Advice创建
1、创建Advice的时机
AbstractAutoProxyCreator# wrapIfNecessary -> AbstractAdvisorAutoProxyCreator# getAdvicesAndAdvisorsForBean -> AbstractAdvisorAutoProxyCreator# findEligibleAdvisors -> AbstractAdvisorAutoProxyCreator# extendAdvisors 拓展Advisor核心伪代码1 // 拓展通知-> 添加 ExposeInvocationInterceptor、TransactionIntercecptor 2 protected void extendAdvisors(List<Advisor> candidateAdvisors) { 3 AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors); 4 }-> AspectJProxyUtils# makeAdvisorChainAspectJCapableIfNecessary 获取事务执行链核心伪代码
1 // 获取事务执行链 2 public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) { 3 4 // advisors通知器如果为空,则说明不需要代理 5 if (!advisors.isEmpty()) { 6 // 判断是否为Before/After/Around/AfterReturning/AfterThrowing等通知 7 boolean foundAspectJAdvice = false; 8 for (Advisor advisor : advisors) { 9 // 判断Advisor中是否包含Advice 10 if (isAspectJAdvice(advisor)) { 11 foundAspectJAdvice = true; 12 break; 13 } 14 } 15 // advisors中包含Advice,并且不包含ExposeInvocationInterceptor,添加 16 if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) { 17 advisors.add(0, ExposeInvocationInterceptor.ADVISOR); 18 return true; 19 } 20 } 21 return false; 22 }
-> AspectJProxyUtils# isAspectJAdvice
1 // 判断Advisor中是否包含Advice 2 private static boolean isAspectJAdvice(Advisor advisor) { 3 // advisor是InstantiationModelAwarePointcutAdvisor类型 4 // advisor中持有的Advice是AbstractAspectJAdvice类型 5 // advisosr是PointcutAdvisor类型,并且 持有的pointcut是AspectJExpressionPointcut类型 6 return (advisor instanceof InstantiationModelAwarePointcutAdvisor || 7 advisor.getAdvice() instanceof AbstractAspectJAdvice || 8 (advisor instanceof PointcutAdvisor && 9 ((PointcutAdvisor) advisor).getPointcut() instanceof AspectJExpressionPointcut)); 10 }
-> AbstractBeanFactoryPointcutAdvisor# getAdvice 获取advice对象
1 public Advice getAdvice() { 2 // 获取当前Advisor的advice对象 3 Advice advice = this.advice; 4 // advice不为空,直接返回 5 if (advice != null) { 6 return advice; 7 } 8 9 // 判断当前Advice是否为一个单例的 10 if (this.beanFactory.isSingleton(this.adviceBeanName)) { 11 12 // 创建advice对象 13 advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class); 14 // 将创建的Advice对象设置进Advisor的advice属性 15 this.advice = advice; 16 // 返回transactionInterceptor对象 17 return advice; 18 } 19 }在创建bean标签的首个被代理类的代理对象时,获取拦截器执行链时,会判断当前Advisor中的Advice是否为空,若不为空,直接返回Advisor中的Advice对象;若为空,创建Advice对象,并将对象设置进Advisor的advice属性中,完成创建过程。
Advisor中的advice属性创建的入口找到了,接下来看看Advice是如何创建的。
2、创建Advice核心伪代码
TransactionInterceptor中包含两个属性,NameMatchTransactionAttributeSource、transcationManager,transcationManager的bean,在缓存中获取;NameMatchTransactionAttributeSource需要在填充属性时创建bean信息。
1、Advice实例化
2、属性填充
Advice实例化完成,其中有关method的事务信息NameMatchTransactionAttributeSource在beanDefinition的propertyValues中。在属性填充时,完成属性的赋值。 创建NameMatchTransactionAttributeSource对象,核心伪代码 AbstractAutowireCapableBeanFactory# populateBean -> AbstractAutowireCapableBeanFactory# applyPropertyValues -> BeanDefinitionValueResolver# resolveValueIfNecessary 属性填充创建transactionAttributeSource对象1 // 解析propertyValues中value为BeanDefinition的属性 2 public Object resolveValueIfNecessary(Object argName, @Nullable Object value) { 3 // value为BeanDefinition类型 4 if (value instanceof BeanDefinition) { 5 6 7 // 将value强转为BeanDefinition对象 8 BeanDefinition bd = (BeanDefinition) value; 9 // 拼装内部Bean名:"(inner bean)#"+bd的身份哈希码的十六进制字符串形式 10 String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR + 11 ObjectUtils.getIdentityHexString(bd); 12 //根据innerBeanName和bd解析出内部Bean对象,创建bean 13 return resolveInnerBean(argName, innerBeanName, bd); 14 } 15 }
-> BeanDefinitionValueResolver# resolveInnerBean 创建bean对象
1 private Object resolveInnerBean(Object argName, String innerBeanName, BeanDefinition innerBd) { 2 //定义一个用于保存innerBd与beanDefinition合并后的BeanDefinition对象的变量 3 RootBeanDefinition mbd = null; 4 try { 5 //获取innerBd与beanDefinition合并后的BeanDefinition对象 6 mbd = this.beanFactory.getMergedBeanDefinition(innerBeanName, innerBd, this.beanDefinition); 7 8 // 获取唯一的beanName 9 String actualInnerBeanName = innerBeanName; 10 // 如果mbd要求时必须是单例的 11 if (mbd.isSingleton()) { 12 //调整innerBeanName,直到该beanName在工厂中唯一。最后将结果赋值给actualInnerBeanName 13 actualInnerBeanName = adaptInnerBeanName(innerBeanName); 14 } 15 16 // 创建actualInnerBeanName的Bean对象 17 Object innerBean = this.beanFactory.createBean(actualInnerBeanName, mbd, null); 18 19 //返回actualInnerBeanName的Bean对象 20 return innerBean; 21 }
NameMatchTransactionAttributeSource创建完成后,设置进Advice中。至此,事务相关对象的都已创建完成。
标签:事务,对象,Spring,Advice,Advisor,bean,源码,创建,advice From: https://www.cnblogs.com/RunningSnails/p/17020456.html