⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 java开源笔记:spring源代码解析.htm

📁 springioc部分最新的分析
💻 HTM
📖 第 1 页 / 共 5 页
字号:
{<BR>//这里是Spring事务处理而使用的AOP拦截器,中间封装了Spring对事务处理的代码来支持声明式事务处理的实现<BR><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">private final TransactionInterceptor 
transactionInterceptor = new TransactionInterceptor();</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)"><BR>private Pointcut 
pointcut;<BR><BR>//这里Spring把TransactionManager注入到TransactionInterceptor中去<BR>public 
void setTransactionManager(PlatformTransactionManager transactionManager) 
{<BR><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">this.transactionInterceptor.setTransactionManager(transactionManager);</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR><BR>//这里把在bean配置文件中读到的事务管理的属性信息注入到TransactionInterceptor中去<BR><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">public void 
setTransactionAttributes(Properties transactionAttributes) {</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">this.transactionInterceptor.setTransactionAttributes(transactionAttributes);</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">}</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)"><BR>.........中间省略了其他一些方法.......<BR><BR>//这里创建Spring 
AOP对事务处理的Advisor<BR>protected Object createMainInterceptor() 
{<BR>this.transactionInterceptor.afterPropertiesSet();<BR>if (this.pointcut != 
null) {<BR>//这里使用默认的通知器<BR>return new DefaultPointcutAdvisor(this.pointcut, 
this.transactionInterceptor);<BR>}<BR>else {<BR>// 
使用上面定义好的TransactionInterceptor作为拦截器,同时使用TransactionAttributeSourceAdvisor<BR><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">return new 
TransactionAttributeSourceAdvisor(this.transactionInterceptor);</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>}<BR>}<BR>那什么时候Spring的TransactionInterceptor被注入到Spring 
AOP中成为Advisor中的一部分呢?我们看到在TransactionProxyFactoryBean中,这个方法在IOC初始化bean的时候被执行:<BR>public 
void afterPropertiesSet() 
{<BR>.......<BR>//TransactionProxyFactoryBean实际上使用ProxyFactory完成AOP的基本功能。<BR>ProxyFactory 
proxyFactory = new ProxyFactory();<BR><BR>if (this.preInterceptors != null) 
{<BR>for (int i = 0; i &lt; this.preInterceptors.length; i++) 
{<BR>proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(this.preInterceptors[i]));<BR>}<BR>}<BR><BR>//这里是Spring加入通知器的地方<BR>//有两种通知器可以被加入DefaultPointcutAdvisor或者<SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">TransactionAttributeSourceAdvisor</SPAN><BR>//这里把Spring处理声明式事务处理的AOP代码都放到ProxyFactory中去,怎样加入advisor我们可以参考ProxyFactory的父类AdvisedSupport()<BR>//由它来维护一个advice的链表,通过这个链表的增删改来抽象我们对整个通知器配置的增删改操作。<BR><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));</SPAN><BR><BR>if 
(this.postInterceptors != null) {<BR>for (int i = 0; i &lt; 
this.postInterceptors.length; i++) 
{<BR>proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(this.postInterceptors[i]));<BR>}<BR>}<BR><BR>proxyFactory.copyFrom(this);<BR><BR>//这里创建AOP的目标源<BR>TargetSource 
targetSource = 
createTargetSource(this.target);<BR>proxyFactory.setTargetSource(targetSource);<BR><BR>if 
(this.proxyInterfaces != null) 
{<BR>proxyFactory.setInterfaces(this.proxyInterfaces);<BR>}<BR>else if 
(!isProxyTargetClass()) 
{<BR>proxyFactory.setInterfaces(ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass()));<BR>}<BR><BR>this.proxy 
= getProxy(proxyFactory);<BR>}<BR><BR><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">Spring已经定义了一个transctionInterceptor作为拦截器或者AOP 
advice的实现,在IOC容器中定义的其他属性比如transactionManager和事务管理的属性都会传到已经定义好的TransactionInterceptor那里去进行处理。以上反映了基本的Spring 
AOP的定义过程,其中pointcut和advice都已经定义好,同时也通过通知器配置到ProxyFactory中去了。<BR>下面让我们回到TransactionProxyFactoryBean中看看</SPAN><SPAN><SPAN>TransactionAttributeSourceAdvisor是怎样定义的,这样我们可以理解具体的属性是怎样起作用,这里我们分析一下类</SPAN></SPAN><SPAN><SPAN>TransactionAttributeSourceAdvisor:</SPAN></SPAN><BR><SPAN><SPAN>public 
class TransactionAttributeSourceAdvisor extends AbstractPointcutAdvisor 
{<BR>//和其他Advisor一样,同样需要定义AOP中的用到的Interceptor和Pointcut<BR>//Interceptor使用传进来的TransactionInterceptor<BR>//而</SPAN></SPAN>对于<SPAN><SPAN>pointcut,这里定义了一个内部类,参见下面的代码 
<BR>private TransactionInterceptor transactionInterceptor;<BR><BR>private final 
TransactionAttributeSourcePointcut pointcut = new 
TransactionAttributeSourcePointcut();<BR><BR>.........<BR>//定义的PointCut内部类<BR>private 
class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut 
implements Serializable 
{<BR>.......<BR>//方法匹配的实现,使用了TransactionAttributeSource类<BR>public boolean 
matches(Method method, Class targetClass) {<BR>TransactionAttributeSource tas = 
getTransactionAttributeSource();<BR>//这里使用</SPAN></SPAN><SPAN><SPAN>TransactionAttributeSource来对配置属性进行处理</SPAN></SPAN><BR><SPAN><SPAN><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">return (tas != null &amp;&amp; 
tas.getTransactionAttribute(method, targetClass) != null);</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>........省略了equal,hashcode,tostring的代码<BR>}<BR>这里我们看看属性值是怎样被读入的:AbstractFallbackTransactionAttributeSource负责具体的属性读入任务,我们可以有两种读入方式,比如annotation和直接配置.我们下面看看直接配置的读入方式,在Spring中同时对读入的属性值进行了缓存处理,这是一个decorator模式:<BR>public 
final TransactionAttribute getTransactionAttribute(Method method, Class 
targetClass) 
{<BR>//这里先查一下缓存里有没有事务管理的属性配置,如果有从缓存中取得TransactionAttribute<BR>Object cacheKey = 
getCacheKey(method, targetClass);<BR>Object cached = 
this.cache.get(cacheKey);<BR>if (cached != null) {<BR>if (cached == 
NULL_TRANSACTION_ATTRIBUTE) {<BR>return null;<BR>}<BR>else {<BR><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">return (TransactionAttribute) 
cached;</SPAN><BR style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>}<BR>else 
{<BR>// 这里通过对方法和目标对象的信息来计算事务缓存属性<BR><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">TransactionAttribute txAtt = 
computeTransactionAttribute(method, targetClass);</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)">//把得到的事务缓存属性存到缓存中,下次可以直接从缓存中取得。<BR>if 
(txAtt == null) {<BR><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">this.cache.put(cacheKey, 
NULL_TRANSACTION_ATTRIBUTE);</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>else {<BR><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)"><FONT 
bgcolor="#FFFFFF">...........</FONT><BR>this.cache.put(cacheKey, 
txAtt);</SPAN><BR style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>return 
txAtt;<BR>}<BR>}<BR>别急,基本的处理在computeTransactionAttribute()中:<BR 
style="BACKGROUND-COLOR: rgb(255,255,255)">private TransactionAttribute 
computeTransactionAttribute(Method method, Class targetClass) {</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">//这里检测是不是public方法</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">if(allowPublicMethodsOnly() 
&amp;&amp; !Modifier.isPublic(method.getModifiers())) {</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">return null;</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">}</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)"></SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)"></SPAN><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">Method specificMethod = 
AopUtils.getMostSpecificMethod(method, targetClass);</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)"></SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">// First try is the method in the 
target class.</SPAN><BR style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">TransactionAttribute txAtt = 
findTransactionAttribute(findAllAttributes(specificMethod));</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">if (txAtt != null) {</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">return txAtt;</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">}</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">// Second try is the transaction 
attribute on the target class.</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">txAtt = 
findTransactionAttribute(findAllAttributes(specificMethod.getDeclaringClass()));</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">if (txAtt != null) {</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">return txAtt;</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">}</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">if (specificMethod != method) 
{</SPAN><BR style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">// Fallback is to look at the 
original method.</SPAN><BR style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">txAtt = 
findTransactionAttribute(findAllAttributes(method));</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">if (txAtt != null) {</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">return txAtt;</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">}</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">// Last fallback is the class of the 
original method.</SPAN><BR style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">return 
findTransactionAttribute(findAllAttributes(method.getDeclaringClass()));</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">}</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">return null;</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">}</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,255)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,255)">经过一系列的尝试我们可以通过findTransactionAttribute()通过调用findAllAttribute()得到TransactionAttribute的对象,如果返回的是null,这说明该方法不是我们需要事务处理的方法。</SPAN></SPAN><BR>在完成把需要的通知器加到ProxyFactory中去的基础上,我们看看具体的看事务处理代码怎样起作用,在TransactionInterceptor中:<BR>public 
Object invoke(final MethodInvocation invocation) throws Throwable 
{<BR>//这里得到目标对象<BR>Class targetClass = (invocation.getThis() != null ? 
invocation.getThis().getClass() : 
null);<BR><BR>//这里同样的通过判断是否能够得到TransactionAttribute来决定是否对当前方法进行事务处理,有可能该属性已经被缓存,<BR>//具体可以参考上面对getTransactionAttribute的分析,同样是通过TransactionAttributeSource<BR><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">final TransactionAttribute txAttr 
=</SPAN><BR style="BACKGROUND-COLOR: rgb(255,255,102)"><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), 
targetClass);<BR></SPAN><SPAN style="BACKGROUND-COLOR: rgb(255,255,102)">final 
String joinpointIdentification = 
methodIdentification(invocation.getMethod());</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)"><BR>//这里判断我们使用了什么TransactionManager<BR>if 
(txAttr == null || !(getTransactionManager() instanceof 
CallbackPreferringPlatformTransactionManager)) {<BR>// 
这里创建事务,同时把创建事务过程中得到的信息放到TransactionInfo中去<BR><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">TransactionInfo txInfo = 
createTransactionIfNecessary(txAttr, joinpointIdentification);</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)">Object retVal = null;<BR>try 
{<BR><SPAN style="BACKGROUND-COLOR: rgb(255,255,102)">retVal = 
invocation.proceed();</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)">}<BR>catch (Throwable ex) {<BR>// 
target invocation exception<BR><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">completeTransactionAfterThrowing(txInfo, 
ex);</SPAN><BR style="BACKGROUND-COLOR: rgb(255,255,102)">throw 
ex;<BR>}<BR>finally {<BR>cleanupTransactionInfo(txInfo);<BR>}<BR><SPAN 
style="BACKGROUND-COLOR: rgb(255,255,102)">commitTransactionAfterReturning(txInfo);</SPAN><BR 
style="BACKGROUND-COLOR: rgb(255,255,102)">return retVal;<BR>}<BR><BR>else 
{<BR><SPAN style="BACKGROUND-COLOR: rgb(255,255,102)">// 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -