public void afterPropertiesSet() { if (this.target == null) { throw new IllegalArgumentException("Property 'target' is required"); } if (this.target instanceof String) { throw new IllegalArgumentException("'target' needs to be a bean reference, not a bean name as value"); } if (this.proxyClassLoader == null) { this.proxyClassLoader = ClassUtils.getDefaultClassLoader(); } //TransactionProxyFactoryBean使用ProxyFactory 完成AOP的年基本功能,ProxyFactory 提供代理对象,并将transactionInterceptor设置为target的拦截器 ProxyFactory proxyFactory = new ProxyFactory();
if (this.preInterceptors != null) { for (Object interceptor : this.preInterceptors) { proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor)); } }
// Add the main interceptor (typically an Advisor). spring加入通知器的地方,可以加入2种通知器,分别是DefaultPointcutAdvisor、TransactionAttributeSourceAdvisor,Proxyfactory的基类,ADvisedSupport中,维护了一个用来持有advice的linkedList,通过对这个list的增删改等操作,用来管理配置给Proxyfactory的通知器 proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));
if (this.postInterceptors != null) { for (Object interceptor : this.postInterceptors) { proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor)); } }
if (this.proxyInterfaces != null) { //设置使用哪个接口作为代理 proxyFactory.setInterfaces(this.proxyInterfaces); } else if (!isProxyTargetClass()) { // Rely on AOP infrastructure to tell us what interfaces to proxy. proxyFactory.setInterfaces( ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader)); } //设置代理对象 this.proxy = proxyFactory.getProxy(this.proxyClassLoader); }
//至于怎创建的代理对象要到proxyFactory看看: public Object getProxy(ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); } createAopProxy()在其基类ProxyCreatorSupport中实现 createAopProxy(): protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } //使用 DefaultAopProxyfactory来创建AopProxy对象,proxyFactory本身是ProxyConfig的子类,所以使用this return getAopProxyFactory().createAopProxy(this); }
TransactionAttributeSourcePointcut这个切点实现了StaticMethodMatcherPointcut,有一个matches(Method method, Class targetClass)函数,在此函数中调用getTransactionAttributeSource得到配置属性,并且判断是否当前方法被拦截: TransactionAttributeSourcePointcut的matches
1 2 3 4 5 6
public boolean matches(Method method, Class targetClass) { //调用transactionInterceptor的getTransactionAttributeSource(),见TransactionAttributeSourcePointcut 得内部类TransactionAttributeSourcePointcut的匿名实现。 TransactionAttributeSource tas = getTransactionAttributeSource(); //判断是否是被拦截的方法 return (tas == null || tas.getTransactionAttribute(method, targetClass) != null); }
//配置事物属性的方法 public void setProperties(Properties transactionAttributes) { TransactionAttributeEditor tae = new TransactionAttributeEditor(); Enumeration propNames = transactionAttributes.propertyNames(); while (propNames.hasMoreElements()) { String methodName = (String) propNames.nextElement(); String value = transactionAttributes.getProperty(methodName); tae.setAsText(value); TransactionAttribute attr = (TransactionAttribute) tae.getValue(); addTransactionalMethod(methodName, attr); } } //将被拦截的方法的名字为key,配置的属性为value放入到nameMap中去。 public void addTransactionalMethod(String methodName, TransactionAttribute attr) { if (logger.isDebugEnabled()) { logger.debug("Adding transactional method [" + methodName + "] with attribute [" + attr + "]"); } this.nameMap.put(methodName, attr); }
//根据方法名字活模式取配置的事物属性 public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) { // look for direct name match String methodName = method.getName(); //以名字为key TransactionAttribute attr = this.nameMap.get(methodName);
if (attr == null) { // Look for most specific name match. String bestNameMatch = null; for (String mappedName : this.nameMap.keySet()) { //isMatch使用模糊或者通配符的方式匹配 if (isMatch(methodName, mappedName) && (bestNameMatch == null || bestNameMatch.length() <= mappedName.length())) { attr = this.nameMap.get(mappedName); bestNameMatch = mappedName; } } } //返回取得的属性值 return attr; }
public Object invoke(final MethodInvocation invocation) throws Throwable { // Work out the target class: may be <code>null</code>. // The TransactionAttributeSource should be passed the target class // as well as the method, which may be from an interface. //目标对象 Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// If the transaction attribute is null, the method is non-transactional. //取得事物的配置属性,通过TransactionAttributeSource得到 final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(invocation.getMethod(), targetClass); //根据TransactionProxyFactoryBean的配置信息获取具体的事物处理器 final PlatformTransactionManager tm = determineTransactionManager(txAttr); final String joinpointIdentification = methodIdentification(invocation.getMethod(), targetClass);
// 这里获取不同的PlatformTransactionManager ,因为回调方式不同,CallbackPreferringPlatformTransactionManager的需要回调函数实现事物的回调与提交,而非CallbackPreferringPlatformTransactionManager不需要,DatasourceTransactionManager就不是CallbackPreferringPlatformTransactionManager if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) { // Standard transaction demarcation with getTransaction and commit/rollback calls. //创建事物,并且把创建过程得到的信息放到TransactionInfo 中去,TransactionInfo 是封装事物状态的类 TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); Object retVal = null; try { // This is an around advice: Invoke the next interceptor in the chain. // This will normally result in a target object being invoked. //继续走拦截器链,知道目标方法被调用。 retVal = invocation.proceed(); } catch (Throwable ex) { // target invocation exception //如果调用过程出现异常需要根据具体情况判断是提交或者回滚。 completeTransactionAfterThrowing(txInfo, ex); throw ex; } finally { //把线程绑定的TransactionInfo 置为oldTransactionInfo cleanupTransactionInfo(txInfo); } //使用事物处理器对事物进行提交 commitTransactionAfterReturning(txInfo); return retVal; }
else { // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in. //使用回调的方式 try { Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, new TransactionCallback<Object>() { public Object doInTransaction(TransactionStatus status) { TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status); try { return invocation.proceed(); } catch (Throwable ex) { if (txAttr.rollbackOn(ex)) { // A RuntimeException: will lead to a rollback. //导致事物回滚 if (ex instanceof RuntimeException) { throw (RuntimeException) ex; } else { throw new ThrowableHolderException(ex); } } else { // A normal return value: will lead to a commit. //正常的处理,进行事物提交 return new ThrowableHolder(ex); } } finally { cleanupTransactionInfo(txInfo); } } });
// Check result: It might indicate a Throwable to rethrow. if (result instanceof ThrowableHolder) { throw ((ThrowableHolder) result).getThrowable(); } else { return result; } } catch (ThrowableHolderException ex) { throw ex.getCause(); } } }