Spring
Spring是一个基于分层架构的开源框架,为J2EE企业应用程序提供一站式的解决方案。
Spring是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。
框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。
它是一个全面的、企业应用开发一站式的解决方案,贯穿表现层、业务层、持久层,但是Spring仍然可以和其他的框架无缝整合。
Spring框架的开发不是为了替代现有的优秀第三方框架,而是通过集成的方式把它们都连接起来。以下框架为在开发中集成的优秀框架:
权限(shiro)、缓存(Ehcache、Redis)、持久层框架(Hibernate、Mybatis)、定时任务(quartz、spring-task)、Web框架(Spring-MVC、Struts)、RPC框架(Dubbo)等
IOC
IOC/DI:控制反转,本质是将原来程序中对象创建、依赖的代码,反转交由容器去协助实现以达到统一管理对象的目的。
Spring中的IOC容器,它的主要作用是完成对象的创建和依赖的管理注入等等。Spring Bean的创建是典型的工厂模式,IOC容器的具体实现就是一系列的Bean工厂,它为开发者管理对象间的依赖关系提供了很多便利和基础服务。

BeanFactory加载Bean的核心实现
以下是BeanFactory加载Bean的核心代码实现:
//AbstractApplicationContext.refresh
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识
prepareRefresh();
//告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从子类的refreshBeanFactory()方法启动
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//为BeanFactory配置容器特性,例如类加载器、事件处理器等
prepareBeanFactory(beanFactory);
try {
//为容器的某些子类指定特殊的BeanPost事件处理器
postProcessBeanFactory(beanFactory);
//调用所有注册的BeanFactoryPostProcessor的Bean
invokeBeanFactoryPostProcessors(beanFactory);
//为BeanFactory注册BeanPost事件处理器。BeanPostProcessor是Bean后置处理器,用于监听容器触发的事件
registerBeanPostProcessors(beanFactory);
//初始化信息源,和国际化相关
initMessageSource();
//初始化容器事件传播器
initApplicationEventMulticaster();
//调用子类的某些特殊Bean初始化方法
onRefresh();
//为事件传播器注册事件监听器
registerListeners();
//初始化所有剩余的单例Bean
finishBeanFactoryInitialization(beanFactory);
//初始化容器的生命周期事件处理器,并发布容器的生命周期事件
finishRefresh();
}
catch (BeansException ex) {
//销毁以创建的单态Bean
destroyBeans();
//取消refresh操作,重置容器的同步标识
cancelRefresh(ex);
throw ex;
}
}
}
这段代码主要包含这样几个步骤:
- 构建 BeanFactory
- 注册可能感兴趣的事件
- 创建 Bean 实例对象
- 触发被监听的事件
构建 BeanFactory
在这个方法中,先判断BeanFactory是否存在,如果存在则先销毁beans并关闭beanFactory,接着创建DefaultListableBeanFactory,并调用loadBeanDefinitions(beanFactory)装载bean定义。
//AbstractRefreshableApplicationContext.refreshBeanFactory
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {//如果已经有容器,销毁容器中的bean,关闭容器
destroyBeans();
closeBeanFactory();
}
try {
//创建IoC容器
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//对IoC容器进行定制化,如设置启动参数,开启注解的自动装配等
customizeBeanFactory(beanFactory);
//调用载入Bean定义的方法,主要这里又使用了一个委派模式,在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
其中载入Bean定义的loadBeanDefinitions方法是后续创建Bean实例对象的关键前提步骤,它的主要内容是加载、解析 Bean 的定义,然后存储到Spring IOC容器(BeanFactory)中。以下是部分关键代码:
//BeanDefinitionReaderUtils.registerBeanDefinition:将解析的BeanDefinitionHolder注册到容器中
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
//获取解析的BeanDefinition的名称
String beanName = definitionHolder.getBeanName();
//向IoC容器注册BeanDefinition
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
//如果解析的BeanDefinition有别名,向容器为其注册别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String aliase : aliases) {
registry.registerAlias(beanName, aliase);
}
}
}
//DefaultListableBeanFactory.registerBeanDefinition
public class DefaultListableBeanFactory
extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
//...
this.beanDefinitionNames.add(beanName);
//...
this.beanDefinitionMap.put(beanName, beanDefinition);
//...
}
}
注意:BeanDefinitionRegistry的具体实现类其实是以上构建的BeanFactory(DefaultListableBeanFactory), 而最终加载、解析的Bean定义会存储到BeanFactory的成员beanDefinitionMap、beanDefinitionNames中。
注册可能感兴趣的事件
创建好 BeanFactory 后,接下去添加一些 Spring 本身需要的一些工具类,这个操作在 AbstractApplicationContext 的 prepareBeanFactory 方法完成。
接下来的postProcessBeanFactory、invokeBeanFactoryPostProcessors、registerBeanPostProcessors是对 Spring 的功能进行扩展。其中postProcessBeanFactory、invokeBeanFactoryPostProcessors主要是让你现在可以对已经构建的 BeanFactory 的配置做修改,而registerBeanPostProcessors就是让你可以对以后再创建 Bean 的实例对象时添加一些自定义的操作。
而initMessageSource、initApplicationEventMulticaster、registerListeners是初始化监听事件和对系统的其他监听者的注册,监听者必须是 ApplicationListener 的子类。
//BeanFactoryPostProcessor.postProcessBeanFactory:在 invokeBeanFactoryPostProcessors 方法中主要是获取实现 BeanFactoryPostProcessor 接口的子类的Bean实例。并调用它的 postProcessBeanFactory 方法
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}
//BeanPostProcessor.postProcessBeforeInitialization、BeanPostProcessor.postProcessAfterInitialization
//registerBeanPostProcessors 方法也是可以获取用户定义的实现了 BeanPostProcessor 接口的子类,并把它们注册到 BeanFactory 对象中的 beanPostProcessors 变量中。BeanPostProcessor 中声明了两个方法:postProcessBeforeInitialization、postProcessAfterInitialization 分别用于在 Bean 对象初始化时执行,其中可以定义用户自己的操作。
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;
Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}
创建 Bean 实例对象
Bean 的实例化是在 BeanFactory 中完成的。其中核心代码在 preInstantiateSingletons 方法中:
//AbstractApplicationContext.finishBeanFactoryInitialization
//对单态模式Bean进行预实例化处理
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//这是Spring3以后新加的代码,为容器指定一个转换服务(ConversionService)在对某些Bean属性进行转换时使用
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
//为了类型匹配,停止使用临时的类加载器
beanFactory.setTempClassLoader(null);
//缓存容器中所有注册的BeanDefinition元数据,以防被修改
beanFactory.freezeConfiguration();
//对单态模式Bean进行预实例化处理
beanFactory.preInstantiateSingletons();
}
//DefaultListableBeanFactory.preInstantiateSingletons
//对单态模式Bean进行预实例化处理
public void preInstantiateSingletons() throws BeansException {
//...
//在对单态模式Bean进行预实例化处理过程中,必须多线程同步,以确保数据一致性
synchronized (this.beanDefinitionMap) {
for (String beanName : this.beanDefinitionNames) {
//获取指定名称的Bean定义
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//Bean不是抽象的,是单态模式的,且lazy-init属性配置为false
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//如果指定名称的bean是创建容器的Bean
if (isFactoryBean(beanName)) {
//...
} else {
//调用getBean方法,触发容器对Bean实例化和依赖注入过程
getBean(beanName);
}
}
}
}
}
触发被监听的事件
在getBean实例化Bean之后,调用AbstractAutowireCapableBeanFactory.initializeBean方法实现为容器创建的Bean实例对象执行BeanPostProcessor后置处理器。
//初始容器创建的Bean实例对象,为其执行BeanPostProcessor后置处理器
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
//...
Object wrappedBean = bean;
//对BeanPostProcessor后置处理器的postProcessBeforeInitialization
//回调方法的调用,为Bean实例初始化前做一些处理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//调用Bean实例对象初始化的方法,这个初始化方法是在Spring Bean定义配置文件中通过init-method属性指定的
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
//对BeanPostProcessor后置处理器的postProcessAfterInitialization回调方法的调用,为Bean实例初始化之后做一些处理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
//调用BeanPostProcessor后置处理器实例对象初始化之前的处理方法
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
//调用Bean实例所有的后置处理中的初始化前处理方法,为Bean实例对象在初始化之前做一些自定义的处理操作
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
//调用BeanPostProcessor后置处理器实例对象初始化之后的处理方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
//调用Bean实例所有的后置处理中的初始化后处理方法,为Bean实例对象在初始化之后做一些自定义的处理操作
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
AOP
AOP(Aspect Oriented Programming)是针对方法调用编程的思路。AOP将每一个方法调用(连接点)作为编程的入口,针对方法调用进行编程。从执行的逻辑上来看,就是将之前的程序横向切割成若干的面,即Aspect.每个面被称为切面。
动态代理(CGLIB和JDK)
Spring AOP是通过动态代理实现的。AOP代理由Spring的IOC容器负责生成、管理,创建代理的规则为:
- 默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了
- 当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB
AOP的核心逻辑是在AnnotationAwareAspectJAutoProxyCreator类里面实现,而AnnotationAwareAspectJAutoProxyCreator其实是BeanPostProcessor后置处理器,因为它实现了BeanPostProcessor接口,具体后置处理内容就是为每个需要代理的Bean创建代理,该部分逻辑在AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator中。
//AbstractAutoProxyCreator.postProcessAfterInitialization public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = this.getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { //为需要代理的Bean生成代理 return this.wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } //AbstractAutoProxyCreator.wrapIfNecessary //提取当前bean 的所有增强方法,然后获取到适合的当前bean 的增强方法,然后对增强方法进行排序,如果需要代理则调用createProxy方法,创建代理,同时织入增强方法。 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (beanName != null && this.targetSourcedBeans.contains(beanName)) { return bean; } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) { Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } else { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } } else { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } } //AbstractAutoProxyCreator.createProxy //创建Bean代理时,首先创建代理工厂proxyFactory,然后获取当前bean 的增强器advisors,把当前获取到的增强器注册到代理工厂proxyFactory,然后设置当前的代理工厂的代理目标对象为当前bean,最后根据配置创建JDK的动态代理工厂,或者CGLIB的动态代理工厂,通过具体的动态代理工厂proxyFactory创建代理对象并返回。 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(); proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) { if (this.shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { this.evaluateProxyInterfaces(beanClass, proxyFactory); } } Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); this.customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (this.advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(this.getProxyClassLoader()); }动态代理工厂配置为JDK代理
//JdkDynamicAopProxy.getProxy public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource()); } Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); } //JdkDynamicAopProxy.invoke //JDK动态代理核心内容,主要是织入拦截器链 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; TargetSource targetSource = this.advised.targetSource; Class<?> targetClass = null; Object target = null; Class var10; try { if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { Boolean var20 = this.equals(args[0]); return var20; } if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { Integer var18 = this.hashCode(); return var18; } if (method.getDeclaringClass() != DecoratingProxy.class) { Object retVal; if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) { retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); return retVal; } if (this.advised.exposeProxy) { oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } //获得目标对象的类 target = targetSource.getTarget(); if (target != null) { targetClass = target.getClass(); } //获取可以应用到此方法上的Interceptor列表 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); //判断拦截器链是否为空,如果是空的话直接调用切点方法, //如果拦截器不为空的话那么便创建ReflectiveMethodInvocation类,把拦截器方法都封装在里面,执行拦截器链和连接点方法 if (chain.isEmpty()) { Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); } else { MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); retVal = invocation.proceed(); } Class<?> returnType = method.getReturnType(); if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { retVal = proxy; } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) { throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method); } Object var13 = retVal; return var13; } var10 = AopProxyUtils.ultimateTargetClass(this.advised); } finally { if (target != null && !targetSource.isStatic()) { targetSource.releaseTarget(target); } if (setProxyContext) { AopContext.setCurrentProxy(oldProxy); } } return var10; }
拦截器
@Aspect
@Component
public class AopInterceptor {
@Pointcut("execution(public * com.ck.aopTest.dao.impl.*.get*(..))")
private void aopTest() {
}
@Before("aopTest()")
public void before() {
System.out.println("调用dao方法前拦截" + new Date().getTime());
}
@After("aopTest()" + "&&args(user)")
public void after(UserModel user) {
System.out.println(user.getName());
System.out.println("调用dao方法之后拦截" + new Date().getTime());
}
@Around("aopTest()")
public void around(ProceedingJoinPoint pdj) {
System.out.println("调用dao之前的环绕拦截" + new Date().getTime());
try {
pdj.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("调用dao之后的环绕拦截" + new Date().getTime());
}
}
织入(AspectJ)
//ReflectiveMethodInvocation.proceed
//逐一执行拦截器链方法,执行完拦截器链后,最后执行连接点方法并返回值
protected final List<?> interceptorsAndDynamicMethodMatchers;
public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.invokeJoinpoint();
} else {
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
} else {
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
}
Bean管理
Spring Bean是被实例的,组装的及被Spring 容器管理的Java对象。Spring容器会自动完成bean对象的实例化。创建应用对象之间的协作关系的行为称为:装配(wiring),这就是依赖注入的本质。
Bean的创建
Bean的创建过程由Spring容器对对象实例、组装的过程。
只有被注册的类型才会被Spring管理,通过@Component,@Repository,@Controller,@Service,@Configration这些注解可以将要使用的对象的类型注册到Spring容器中。
被注册的类型被实例化为对象之后,还需要通过组装将对象、属性、方法关联到一起,才能使用。属性组装时通过@Autowired(根据类型)、@Resource(根据名称)这些注解完成。
Bean的生命周期
Bean的作用域有singleton(单例)、prototype(非单例)、(session、request、global session)(不常用,Web作用域,基于Web容器(Servlet)或框架(Portlet))。
singleton(单例)
当一个bean的作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。
prototype(非单例)
prototype作用域部署的bean,每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)都会产生一个新的bean实例。
不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。 清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。
事务
Spring的声明式事务管理是建立在 代理+AOP 基础上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。 大致执行流程如下:
- 创建事务状态对象,获取一个新的连接,重置连接的autoCommit、fetchSize、timeout等属性
- 把连接绑定到ThreadLocal变量
- 根据传播特性配置决定是否挂起当前事务(把当前事务状态对象,连接等信息封装成SuspendedResources对象,可用于恢复)
- 根据传播特性配置决定是否创建新的事务(创建事务状态对象,重新获取新的连接,重置新连接的autoCommit、fetchSize、timeout等属性,同时,保存SuspendedResources对象,用于事务的恢复,把新的连接绑定到ThreadLocal变量(覆盖操作))
- 捕获到异常,回滚ThreadLocal中的连接,恢复连接参数,关闭连接,恢复SuspendedResources
- 提交ThreadLocal变量中的连接,还原连接参数,关闭连接,连接归还数据源
其核心实现逻辑如下:
//TransactionInterceptor.invoke
//事务处理的AOP Interceptor
public Object invoke(final MethodInvocation invocation) throws Throwable {
Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
return this.invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed();
}
});
}
//TransactionAspectSupport.invokeWithinTransaction
//事务处理的核心代码
public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
//事务状态对象ThreadLocal容器
private static final ThreadLocal<TransactionAspectSupport.TransactionInfo> transactionInfoHolder = new NamedThreadLocal("Current aspect-driven transaction");
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final TransactionAspectSupport.InvocationCallback invocation) throws Throwable {
final TransactionAttribute txAttr = this.getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
final PlatformTransactionManager tm = this.determineTransactionManager(txAttr);
final String joinpointIdentification = this.methodIdentification(method, targetClass);
if (txAttr != null && tm instanceof CallbackPreferringPlatformTransactionManager) {
//...
} else {
//创建并开始事务
TransactionAspectSupport.TransactionInfo txInfo = this.createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal = null;
try {
retVal = invocation.proceedWithInvocation();
} catch (Throwable var15) {
this.completeTransactionAfterThrowing(txInfo, var15);
throw var15;
} finally {
this.cleanupTransactionInfo(txInfo);
}
//提交事务
this.commitTransactionAfterReturning(txInfo);
return retVal;
}
}
}
//TransactionAspectSupport.createTransactionIfNecessary
//首先根据配置的事务传播特性取得(创建或获取)一个事务
protected TransactionAspectSupport.TransactionInfo createTransactionIfNecessary(PlatformTransactionManager tm, TransactionAttribute txAttr, final String joinpointIdentification) {
if (txAttr != null && ((TransactionAttribute)txAttr).getName() == null) {
txAttr = new DelegatingTransactionAttribute((TransactionAttribute)txAttr) {
public String getName() {
return joinpointIdentification;
}
};
}
TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
status = tm.getTransaction((TransactionDefinition)txAttr);
} else if (this.logger.isDebugEnabled()) {
this.logger.debug("Skipping transactional joinpoint [" + joinpointIdentification + "] because no transaction manager has been configured");
}
}
return this.prepareTransactionInfo(tm, (TransactionAttribute)txAttr, joinpointIdentification, status);
}
//AbstractPlatformTransactionManager.getTransaction
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
//获取事务对象
Object transaction = this.doGetTransaction();
boolean debugEnabled = this.logger.isDebugEnabled();
if (definition == null) {
definition = new DefaultTransactionDefinition();
}
if (this.isExistingTransaction(transaction)) {
return this.handleExistingTransaction((TransactionDefinition)definition, transaction, debugEnabled);
} else if (((TransactionDefinition)definition).getTimeout() < -1) {
throw new InvalidTimeoutException("Invalid transaction timeout", ((TransactionDefinition)definition).getTimeout());
} else if (((TransactionDefinition)definition).getPropagationBehavior() == 2) {
throw new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'");
} else if (((TransactionDefinition)definition).getPropagationBehavior() != 0 && ((TransactionDefinition)definition).getPropagationBehavior() != 3 && ((TransactionDefinition)definition).getPropagationBehavior() != 6) {
if (((TransactionDefinition)definition).getIsolationLevel() != -1 && this.logger.isWarnEnabled()) {
this.logger.warn("Custom isolation level specified but no actual transaction initiated; isolation level will effectively be ignored: " + definition);
}
boolean newSynchronization = this.getTransactionSynchronization() == 0;
return this.prepareTransactionStatus((TransactionDefinition)definition, (Object)null, true, newSynchronization, debugEnabled, (Object)null);
} else {
AbstractPlatformTransactionManager.SuspendedResourcesHolder suspendedResources = this.suspend((Object)null);
if (debugEnabled) {
this.logger.debug("Creating new transaction with name [" + ((TransactionDefinition)definition).getName() + "]: " + definition);
}
try {
boolean newSynchronization = this.getTransactionSynchronization() != 2;
DefaultTransactionStatus status = this.newTransactionStatus((TransactionDefinition)definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
//开始事务
this.doBegin(transaction, (TransactionDefinition)definition);
this.prepareSynchronization(status, (TransactionDefinition)definition);
return status;
} catch (RuntimeException var7) {
this.resume((Object)null, suspendedResources);
throw var7;
} catch (Error var8) {
this.resume((Object)null, suspendedResources);
throw var8;
}
}
}
//DataSourceTransactionManager.doGetTransaction
//获取事务状态对象
protected Object doGetTransaction() {
DataSourceTransactionManager.DataSourceTransactionObject txObject = new DataSourceTransactionManager.DataSourceTransactionObject();
txObject.setSavepointAllowed(this.isNestedTransactionAllowed());
ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.getResource(this.dataSource);
txObject.setConnectionHolder(conHolder, false);
return txObject;
}
//DataSourceTransactionManager.doBegin
//开始事务
protected void doBegin(Object transaction, TransactionDefinition definition) {
DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)transaction;
Connection con = null;
try {
if (txObject.getConnectionHolder() == null || txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
Connection newCon = this.dataSource.getConnection();
if (this.logger.isDebugEnabled()) {
this.logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
}
txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
}
txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
con = txObject.getConnectionHolder().getConnection();
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
if (con.getAutoCommit()) {
txObject.setMustRestoreAutoCommit(true);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
}
con.setAutoCommit(false);
}
txObject.getConnectionHolder().setTransactionActive(true);
int timeout = this.determineTimeout(definition);
if (timeout != -1) {
txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
}
if (txObject.isNewConnectionHolder()) {
TransactionSynchronizationManager.bindResource(this.getDataSource(), txObject.getConnectionHolder());
}
} catch (Throwable var7) {
if (txObject.isNewConnectionHolder()) {
DataSourceUtils.releaseConnection(con, this.dataSource);
txObject.setConnectionHolder((ConnectionHolder)null, false);
}
throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", var7);
}
}
//TransactionAspectSupport.commitTransactionAfterReturning
//提交事务
protected void commitTransactionAfterReturning(TransactionAspectSupport.TransactionInfo txInfo) {
if (txInfo != null && txInfo.hasTransaction()) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
}
//DataSourceTransactionManager.doCommit
protected void doCommit(DefaultTransactionStatus status) {
DataSourceTransactionManager.DataSourceTransactionObject txObject = (DataSourceTransactionManager.DataSourceTransactionObject)status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
this.logger.debug("Committing JDBC transaction on Connection [" + con + "]");
}
try {
con.commit();
} catch (SQLException var5) {
throw new TransactionSystemException("Could not commit JDBC transaction", var5);
}
}
事务的传播特性
- PROPAGATION_REQUIRED(常用)
- 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
- PROPAGATION_REQUIRES_NEW(常用)
- 新建事务,如果当前存在事务,把当前事务挂起。
- PROPAGATION_NESTED(常用)
- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
- PROPAGATION_SUPPORTS
- 支持当前事务,如果当前没有事务,就以非事务方式执行。
- PROPAGATION_MANDATORY
- 使用当前的事务,如果当前没有事务,就抛出异常。
- PROPAGATION_NOT_SUPPORTED
- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- PROPAGATION_NEVER
- 以非事务方式执行,如果当前存在事务,则抛出异常。
【整理中】扩展
- 以非事务方式执行,如果当前存在事务,则抛出异常。
参考文献
1000行代码读懂Spring(一)- 实现一个基本的IoC容器
Spring:源码解读Spring IOC原理
Spring多种加载Bean方式简析
Spring技术内幕——深入解析Spring架构与设计原理(二)AOP
Spring 框架的设计理念与设计模式分析
BeanPostProcessor与AB测试
Spring思维导图,让spring不再难懂(一)
Spring思维导图,让Spring不再难懂(ioc篇)
Spring思维导图,让Spring不再难懂(aop篇)
Spring事务-说说Propagation及其实现原理