Spring提供了非常强大的Transactional注解,下面这篇文章想从源码的角度来看一下Transactional这个注解是如何工作的。
1.Spring AOP
Transactional注解的实现依赖于AOP技术,AOP是面向切面编程(Aspect-oriented programming)的缩写,是一种不同于面向对象编程(Object-oriented programming)的技术。它的好处有很多,其中的一个好处就是:在不改变现有代码的基础上,增加新的行为。网上关于AOP的文章还是比较多的,可以自行搜索阅读。
2.代码demo
为了能够弄清楚Transactional注解是如何工作的,需要一个简单的例子来追踪代码执行的过程。可以参考官方的例子。Spring Boot现在非常的智能,你几乎不需要怎么配置就能使用Transactional这个注解,引述官方文档里面的一段话:
Your application has actually zero configuration. Spring Boot will detect spring-jdbc on the classpath and h2 and will create a DataSource and a JdbcTemplate for you automatically. Because such infrastructure is now available and you have no dedicated configuration, a DataSourceTransactionManager will also be created for you: this is the component that intercepts the @Transactional annotated method
至于如何做到如此少的配置的,可以参考一些关于Spring Boot Stater的文章。
3.初探:Transactional 注解到底做了什么
想要探究这个注解如何工作,刚开始都是无从下手的。那就用最笨的办法,声明一个bean,在这个bean的某一个方法上面加上 @Transactional 注解,然后调用这个方法,看看发生了什么。
Object o = context.getBean("ttb");
if (o instanceof TransactionTestBean) {
TransactionTestBean tmp = (TransactionTestBean) o;
String s = tmp.transactionTest();
System.out.println(s);
}
复制代码
通过debug,发现这个叫ttb(不要在意名字)的bean变成了下面这个样子:
4.跟踪
通过断点,最终我们定位到cglib的处理是在方法applyBeanPostProcessorsAfterInitialization里面完成的,这个方法的代码大概是长这个样子的。
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
复制代码
可以看到这个getBeanPostProcessors里面有很多的BeanPostProcessor,其中有一个叫做InfrastructureAdvisorAutoProxyCreator的,在它执行完postProcessAfterInitialization之后,我们的bean就变成了cglib的形式了,通过进一步的跟踪,发现在AbstractAutoProxyCreator类下,有一个createProxy的方法,顺着调用的关系最后找到了在org.springframework.aop.framework包下有一个CglibAopProxy的类,类里面的getProxy方法,终于找到了和这篇文章内容有点相似的代码了,创建bean的过程初步跟踪完成。
5.小结
这篇文章只是初略的记录了spring如何创建带有 @Transactional注解的bean的,很多细节的跳过了(比如刚才那个InfrastructureAdvisorAutoProxyCreator是如何来的),后续的文章会呈现这些细节以及Transactional生成的proxy在调用业务代码之前做了什么。
打个广告,阿里巴巴集团长期接受简历,有需要内推的朋友可以将简历发送到 linlan.zcj@alibaba-inc.com。