</div>
<div class="operating">
</div>
</div>
</div>
</div>
<article class="baidu_pl">
<div id="article_content" class="article_content clearfix csdn-tracking-statistics" data-pid="blog" data-mod="popu_307" data-dsm="post">
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css">
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css">
<div class="htmledit_views" id="content_views">
<p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">以下问题,用于复习面试也是可以的。</p><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>IOC和DI是什么?</li><li>Spring IOC 的理解,其初始化过程?</li><li>BeanFactory 和 FactoryBean的区别?</li><li>BeanFactory和ApplicationContext的区别?</li><li>ApplicationContext 上下文的生命周期?</li><li>Spring Bean 的生命周期?</li><li>Spring AOP的实现原理?</li><li>Spring 是如何管理事务的,事务管理机制?</li><li>Spring 的不同事务传播行为有哪些,干什么用的?</li><li>Spring 中用到了那些设计模式?</li><li>Spring MVC 的工作原理?</li><li>Spring如何解决循环依赖?</li><li>Spring 如何保证 Controller 并发的安全?</li></ul><h1 class="clickable-header top-level-header" style="font-size:2.25em;line-height:1.2;border-bottom:1px solid rgb(238,238,238);color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t0"></a>IOC和DI是什么?</h1><span class="icon-arrow-up back-to-top" style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><span style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t1"></a>IoC (Inversion of Control) 控制反转什么是控制反转?</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">控制反转是就是应用本身不负责依赖对象的创建和维护,依赖对象的创建及维护是由外部容器负责的,这样控制权就有应用转移到了外部容器,控制权的转移就是控制反转。</p><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t2"></a>DI (Dependency Injection) 依赖注入什么是依赖注入?</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">依赖注入是指:在程序运行期间,由外部容器动态地将依赖对象注入到组件中 如:一般,通过构造函数注入或者setter注入。</p><h1 class="clickable-header top-level-header" style="font-size:2.25em;line-height:1.2;border-bottom:1px solid rgb(238,238,238);color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t3"></a>Spring IOC 的理解,其初始化过程?</h1><span class="icon-arrow-up back-to-top" style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><span style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a href="http://blog.csdn.net/u010723709/article/details/47046211" rel="nofollow" style="color:rgb(65,131,196);" target="_blank">http://blog.csdn.net/u010723709/article/details/47046211</a></p><h2 class="clickable-header" style="line-height:1.225;font-size:1.75em;border-bottom:1px solid rgb(238,238,238);color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t4"></a>IOC 容器的初始化分为三个过程实现:</h2><ol style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>Resource资源定位,这个Resouce指的是BeanDefinition的资源定位,这个过程就是容器找数据的过程。</li><li>BeanDefinition的载入过程,这个载入过程是把用户定义好的Bean表示成Ioc容器内部的数据结构,而这个容器内部的数据结构就是BeanDefition。</li><li>向IOC容器注册这些BeanDefinition的过程,这个过程就是将前面的BeanDefition保存到HashMap中的过程。</li></ol><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t5"></a>Resource定位</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">我们一般使用外部资源来描述Bean对象,所以IOC容器第一步就是需要定位Resource外部资源。Resource的定位其实就是BeanDefinition的资源定位,它是由ResourceLoader通过统一的Resource接口来完成的,这个Resource对各种形式的BeanDefinition的使用都提供了统一接口。</p><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t6"></a>载入</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">第二个过程就是BeanDefinition的载入,BeanDefinitionReader读取,解析Resource定位的资源,也就是将用户定义好的Bean表示成IOC容器的内部数据结构也就是BeanDefinition,在IOC容器内部维护着一个BeanDefinition Map的数据结构,通过这样的数据结构,IOC容器能够对Bean进行更好的管理。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">在配置文件中每一个都对应着一个BeanDefinition对象。</p><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t7"></a>注册</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">第三个过程则是注册,即向IOC容器注册这些BeanDefinition,这个过程是通过BeanDefinitionRegistery接口来实现的。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">在IOC容器内部其实是将第二个过程解析得到的BeanDefinition注入到一个HashMap容器中,IOC容器就是通过这个HashMap来维护这些BeanDefinition的。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">上面提到的过程一般是不包括Bean的依赖注入的实现,Bean的载入和依赖注入是两个独立的过程,依赖注入是发生在应用第一次调用getBean向容器所要Bean时。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">当然我们可以通过设置预处理,即对某个Bean设置lazyinit属性,那么这个Bean的依赖注入就会在容器初始化的时候完成。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">经过这 (Resource定位,载入,注册)三个步骤,IOC容器的初始化过程就已经完成了。</p><h1 class="clickable-header top-level-header" style="font-size:2.25em;line-height:1.2;border-bottom:1px solid rgb(238,238,238);color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t8"></a>BeanFactory 和 FactoryBean的区别?</h1><span class="icon-arrow-up back-to-top" style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><span style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li><strong>BeanFactory</strong>是个Factory,也就是IOC容器或对象工厂,在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的,提供了实例化对象和拿对象的功能。</li><li><strong>FactoryBean</strong>是个Bean,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。</li></ul><h1 class="clickable-header top-level-header" style="font-size:2.25em;line-height:1.2;border-bottom:1px solid rgb(238,238,238);color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t9"></a>BeanFactory和ApplicationContext的区别?</h1><span class="icon-arrow-up back-to-top" style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><span style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t10"></a>BeanFactory</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">是Spring里面最低层的接口,提供了最简单的容器的功能,只提供了实例化对象和拿对象的功能。</p><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t11"></a>两者装载bean的区别</h3><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li><strong>BeanFactory</strong>:在启动的时候不会去实例化Bean,中有从容器中拿Bean的时候才会去实例化;</li><li><strong>ApplicationContext</strong>:在启动的时候就把所有的Bean全部实例化了。它还可以为Bean配置lazy-init=true来让Bean延迟实例化;</li></ul><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t12"></a>我们该用BeanFactory还是ApplicationContent</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><strong>BeanFactory</strong> 延迟实例化的优点:</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">应用启动的时候占用资源很少,对资源要求较高的应用,比较有优势;</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">缺点:速度会相对来说慢一些。而且有可能会出现空指针异常的错误,而且通过bean工厂创建的bean生命周期会简单一些</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><strong>ApplicationContext</strong> 不延迟实例化的优点:</p><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>所有的Bean在启动的时候都加载,系统运行的速度快;</li><li>在启动的时候所有的Bean都加载了,我们就能在系统启动的时候,尽早的发现系统中的配置问题</li><li>建议web应用,在启动的时候就把所有的Bean都加载了。</li></ul><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">缺点:把费时的操作放到系统启动中完成,所有的对象都可以预加载,缺点就是消耗服务器的内存</p><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t13"></a>ApplicationContext其他特点</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">除了提供BeanFactory所支持的所有功能外,ApplicationContext还有额外的功能</p><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>默认初始化所有的Singleton,也可以通过配置取消预初始化。</li><li>继承MessageSource,因此支持国际化。</li><li>资源访问,比如访问URL和文件(ResourceLoader);</li><li>事件机制,(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层;</li><li>同时加载多个配置文件。</li><li>消息发送、响应机制(ApplicationEventPublisher);</li><li>以声明式方式启动并创建Spring容器。</li></ul><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">由于ApplicationContext会预先初始化所有的Singleton Bean,于是在系统创建前期会有较大的系统开销,但一旦ApplicationContext初始化完成,程序后面获取Singleton Bean实例时候将有较好的性能。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">也可以为bean设置lazy-init属性为true,即Spring容器将不会预先初始化该bean。</p><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t14"></a>spring的AOP(常用的是拦截器)</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">一般拦截器都是实现HandlerInterceptor,其中有三个方法preHandle、postHandle、afterCompletion</p><ol style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>preHandle:执行controller之前执行</li><li>postHandle:执行完controller,return modelAndView之前执行,主要操作modelAndView的值</li><li>afterCompletion:controller返回后执行</li></ol><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t15"></a>spring载入多个上下文</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">不同项目使用不同分模块策略,spring配置文件分为</p><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>applicationContext.xml(主文件,包括JDBC配置,hibernate.cfg.xml,与所有的Service与DAO基类)</li><li>applicationContext-cache.xml(cache策略,包括hibernate的配置)</li><li>applicationContext-jmx.xml(JMX,调试hibernate的cache性能)</li><li>applicationContext-security.xml(acegi安全)</li><li>applicationContext-transaction.xml(事务)</li><li>moduleName-Service.xml</li><li>moduleName-dao.xml</li></ul><h1 class="clickable-header top-level-header" style="font-size:2.25em;line-height:1.2;border-bottom:1px solid rgb(238,238,238);color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t16"></a>ApplicationContext 上下文的生命周期?</h1><span class="icon-arrow-up back-to-top" style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><span style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">PS:可以借鉴Servlet的生命周期,实例化、初始init、接收请求service、销毁destroy;</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">Spring上下文中的Bean也类似,【Spring上下文的生命周期】</p><ol style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>实例化一个Bean,也就是我们通常说的new;</li><li>按照Spring上下文对实例化的Bean进行配置,也就是IOC注入</li><li>如果这个Bean实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的是Spring配置文件中Bean的ID;</li><li>如果这个Bean实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(),传递的是Spring工厂本身(可以用这个方法获取到其他Bean);</li><li>如果这个Bean实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文,该方式同样可以实现步骤4,但比4更好,以为ApplicationContext是BeanFactory的子接口,有更多的实现方法;</li><li>如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用After方法,也可用于内存或缓存技术;</li><li>如果这个Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法;</li><li>如果这个Bean关联了BeanPostProcessor接口,将会调用postAfterInitialization(Object obj, String s)方法;</li></ol><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">注意:以上工作完成以后就可以用这个Bean了,那这个Bean是一个single的,所以一般情况下我们调用同一个ID的Bean会是在内容地址相同的实例</p><ol style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean接口,会调用其实现的destroy方法</li><li>最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法</li></ol><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">以上10步骤可以作为面试或者笔试的模板,另外这里描述的是应用Spring上下文Bean的生命周期,如果应用Spring的工厂也就是BeanFactory的话去掉第5步就Ok了;</p><h1 class="clickable-header top-level-header" style="font-size:2.25em;line-height:1.2;border-bottom:1px solid rgb(238,238,238);color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t17"></a>Spring Bean 的生命周期?</h1><span class="icon-arrow-up back-to-top" style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><span style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">Spring框架中,一旦把一个Bean纳入Spring IOC容器之中,这个Bean的生命周期就会交由容器进行管理,一般担当管理角色的是BeanFactory或者ApplicationContext,认识一下Bean的生命周期活动,对更好的利用它有很大的帮助:</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">下面以BeanFactory为例,说明一个Bean的生命周期活动。</p><ol style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>Bean的建立, 由BeanFactory读取Bean定义文件,并生成各个实例;</li><li>Setter注入,执行Bean的属性依赖注入;</li><li>BeanNameAware的setBeanName(), 如果实现该接口,则执行其setBeanName方法;</li><li>BeanFactoryAware的setBeanFactory(),如果实现该接口,则执行其setBeanFactory方法;</li><li>BeanPostProcessor的processBeforeInitialization(),如果有关联的processor,则在Bean初始化之前都会执行这个实例的processBeforeInitialization()方法;</li><li>InitializingBean的afterPropertiesSet(),如果实现了该接口,则执行其afterPropertiesSet()方法;</li><li>Bean定义文件中定义init-method;</li><li>BeanPostProcessors的processAfterInitialization(),如果有关联的processor,则在Bean初始化之前都会执行这个实例的processAfterInitialization()方法;</li><li>DisposableBean的destroy(),在容器关闭时,如果Bean类实现了该接口,则执行它的destroy()方法;</li><li>Bean定义文件中定义destroy-method,在容器关闭时,可以在Bean定义文件中使用“destory-method”定义的方法;</li></ol><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">如果使用ApplicationContext来维护一个Bean的生命周期,则基本上与上边的流程相同,只不过在执行BeanNameAware的setBeanName()后,若有Bean类实现了org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,然后再进行BeanPostProcessors的processBeforeInitialization() 实际上,ApplicationContext除了向BeanFactory那样维护容器外,还提供了更加丰富的框架功能,如Bean的消息,事件处理机制等</p><h1 class="clickable-header top-level-header" style="font-size:2.25em;line-height:1.2;border-bottom:1px solid rgb(238,238,238);color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t18"></a>Spring AOP的实现原理?</h1><span class="icon-arrow-up back-to-top" style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><span style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">所谓AOP,即Aspect orientied program,就是面向方面(切面)的编程。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><strong>特点</strong></p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">让关注点代码与业务代码分离,可以动态地添加和删除在切面上的逻辑而不影响原来的执行代码。</p><ol style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>模块之间的耦合度;</li><li>统容易扩展;</li><li>的代码复用;</li></ol><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t19"></a>AOP核心概念</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">1、横切关注点</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">2、切面(aspect)</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">类是对物体特征的抽象,切面就是对横切关注点的抽象,面向切面编程,就是指 对很多功能都有的重复的代码抽取,再在运行的时候往业务方法上动态植入“切面类代码”。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">3、连接点(joinpoint)</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">4、切入点(pointcut)</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">切入点在AOP中的通知和切入点表达式关联,指定拦截哪些类的哪些方法, 给指定的类在运行的时候动态的植入切面类代码。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">5、通知(advice)</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">6、目标对象</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">被一个或者多个切面所通知的对象。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">7、织入(weave)</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">将切面应用到目标对象并导致代理对象创建的过程</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">8、引入(introduction)</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">9、AOP代理(AOP Proxy)</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">在Spring AOP中有两种代理方式,JDK动态代理和CGLIB代理。</p><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t20"></a>使用注解</h3><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>@Aspect指定一个类为切面类;</li><li>@Pointcut(“execution(* cn.itcast.e_aop_anno.<em>.</em>(..))”) 指定切入点表达式;</li><li>@Before(“pointCut_()”)前置通知: 目标方法之前执行;</li><li>@After(“pointCut_()”)后置通知:目标方法之后执行(始终执行);</li><li>@AfterReturning(“pointCut_()”)返回后通知: 执行方法结束前执行(异常不执行);</li><li>@AfterThrowing(“pointCut_()”)异常通知: 出现异常时候执行;</li><li>@Around(“pointCut_()”)环绕通知:环绕目标方法执行;</li></ul><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a href="https://www.cnblogs.com/guzhou-ing/p/6445159.html" rel="nofollow" style="color:rgb(65,131,196);" target="_blank">https://www.cnblogs.com/guzhou-ing/p/6445159.html</a></p><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t21"></a>AOP的实现原理</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a href="http://www.importnew.com/24305.html" rel="nofollow" style="color:rgb(65,131,196);" target="_blank">http://www.importnew.com/24305.html</a></p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。</p><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t22"></a>Spring对AOP的支持</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a href="https://www.cnblogs.com/hongwz/p/5764917.html" rel="nofollow" style="color:rgb(65,131,196);" target="_blank">https://www.cnblogs.com/hongwz/p/5764917.html</a></p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><strong>Spring创建代理的规则为</strong>:</p><ol style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li><strong>默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了</strong></li><li><strong>当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB</strong></li></ol><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">AOP编程其实是很简单的事情,程序员只需要参与三个部分:</p><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>定义普通业务组件</li><li>定义切入点,一个切入点可能横切多个业务组件</li><li>定义增强处理,增强处理就是在AOP框架为普通业务组件织入的处理动作</li></ul><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">所以进行AOP编程的关键就是定义切入点和定义增强处理,一旦定义了合适的切入点和增强处理,AOP框架将自动生成AOP代理</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">即:代理对象的方法=增强处理+被代理对象的方法。</p><h1 class="clickable-header top-level-header" style="font-size:2.25em;line-height:1.2;border-bottom:1px solid rgb(238,238,238);color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t23"></a>Spring 是如何管理事务的,事务管理机制?</h1><span class="icon-arrow-up back-to-top" style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><span style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"></span><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">事务管理可以帮助我们保证数据的一致性,对应企业的实际应用很重要。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">Spring的事务机制包括声明式事务和编程式事务。</p><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li><strong>编程式事务管理</strong>:Spring推荐使用TransactionTemplate,实际开发中使用声明式事务较多。</li><li><strong>声明式事务管理</strong>:将我们从复杂的事务处理中解脱出来,获取连接,关闭连接、事务提交、回滚、异常处理等这些操作都不用我们处理了,Spring都会帮我们处理。</li></ul><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><strong>声明式事务管理使用了AOP面向切面编程实现的,本质就是在目标方法执行前后进行拦截。在目标方法执行前加入或创建一个事务,在执行方法执行后,根据实际情况选择提交或是回滚事务</strong>。</p><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t24"></a>如何管理的</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">Spring事务管理主要包括3个接口,Spring的事务主要是由它们(<strong>PlatformTransactionManager,TransactionDefinition,TransactionStatus</strong>)三个共同完成的。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><strong>1. PlatformTransactionManager</strong>:事务管理器–主要用于平台相关事务的管理</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">主要有三个方法:</p><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>commit 事务提交;</li><li>rollback 事务回滚;</li><li>getTransaction 获取事务状态。</li></ul><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><strong>2. TransactionDefinition</strong>:事务定义信息–用来定义事务相关的属性,给事务管理器PlatformTransactionManager使用</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">这个接口有下面四个主要方法:</p><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>getIsolationLevel:获取隔离级别;</li><li>getPropagationBehavior:获取传播行为;</li><li>getTimeout:获取超时时间;</li><li>isReadOnly:是否只读(保存、更新、删除时属性变为false–可读写,查询时为true–只读)</li></ul><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">事务管理器能够根据这个返回值进行优化,这些事务的配置信息,都可以通过配置文件进行配置。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><strong>3. TransactionStatus</strong>:事务具体运行状态–事务管理过程中,每个时间点事务的状态信息。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">例如它的几个方法:</p><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>hasSavepoint():返回这个事务内部是否包含一个保存点,</li><li>isCompleted():返回该事务是否已完成,也就是说,是否已经提交或回滚</li><li>isNewTransaction():判断当前事务是否是一个新事务</li></ul><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><strong>声明式事务的优缺点</strong>:</p><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li><strong>优点</strong>:不需要在业务逻辑代码中编写事务相关代码,只需要在配置文件配置或使用注解(@Transaction),这种方式没有侵入性。</li><li><strong>缺点</strong>:声明式事务的最细粒度作用于方法上,如果像代码块也有事务需求,只能变通下,将代码块变为方法。</li></ul><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a href="http://blog.csdn.net/jie_liang/article/details/77600742" rel="nofollow" style="color:rgb(65,131,196);" target="_blank">http://blog.csdn.net/jie_liang/article/details/77600742</a></p><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t25"></a>事务的4个特性:</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><strong>原子性(Atomicity)</strong></p><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li><strong>原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚</strong>,因此事务的操作如果成功就必须要完全应用到数据库,如果操作失败则不能对数据库有任何影响。</li></ul><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><strong>一致性(Consistency)</strong></p><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li><strong>一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态</strong>。</li></ul><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><strong>隔离性(Isolation)</strong></p><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li><strong>隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离</strong>。</li></ul><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。</p><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><strong>关于事务的隔离性数据库提供了多种隔离级别,稍后会介绍到</strong>。 <strong>持久性(Durability)</strong></p><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li><strong>持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作</strong>。</li></ul><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t26"></a>事务的隔离级别</h3><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><strong>从理论上来说, 事务应该彼此完全隔离, 以避免并发事务所导致的问题,然而, 那样会对性能产生极大的影响, 因为事务必须按顺序运行, 在实际开发中, 为了提升性能, 事务会以较低的隔离级别运行, 事务的隔离级别可以通过隔离事务属性指定</strong>。</p><ol style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li><strong><font color=red>ISOLATION_DEFAULT</font></strong>: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应</li><li><strong><font color=red>ISOLATION_READ_UNCOMMITTED</font></strong>: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。</li><li><strong><font color=red>ISOLATION_READ_COMMITTED</font></strong>: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据</li><li><strong><font color=red>ISOLATION_REPEATABLE_READ</font></strong>: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。</li><li><strong><font color=red>ISOLATION_SERIALIZABLE</font></strong> 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。</li></ol><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>事务的隔离级别要得到底层数据库引擎的支持, 而不是应用程序或者框架的支持.</li><li>Oracle 支持的 2 种事务隔离级别:READ_COMMITED , SERIALIZABLE</li><li>Mysql 支持 4 中事务隔离级别.</li></ul><h3 class="clickable-header" style="line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><a name="t27"></a>事务回滚属性</h3><ul style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><li>默认情况下只有未检查异常(RuntimeException和Error类型的异常)会导致事务回滚. 而受检查异常不会.</li><li>事务的回滚规则可以通过@Transactional 注解的 rollbackFor 和 noRollbackFor 属性来定义,这两个属性被声明为 Class[] 类型的, 因此可以为这两个属性指定多个异常类。</li><li>rollbackFor: 遇到时必须进行回滚</li><li>noRollbackFor: 一组异常类,遇到时必须不回滚</li></ul><p style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';">不推荐使用的手动回滚事务的方法:</p><div class="language-java highlighter-rouge" style="color:rgb(51,51,51);font-family:Arial, 'Hiragino Sans GB', '冬青黑', 'Microsoft YaHei', '微软雅黑', SimSun, '宋体', Helvetica, Tahoma, 'Arial sans-serif';"><div class="highlight"><pre class="highlight" style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:13.6px;line-height:1.45;background:rgb(247,247,247);" name="code" onclick="hljs.copyCode(event)"><code style="font-family:Consolas, 'Liberation Mono', Menlo, Courier, monospace;font-size:13.6px;background:transparent 0px 0px;border:0px;line-height:inherit;" class="hljs css"><span class="n" style="color:rgb(51,51,51);"><span class="hljs-selector-tag">TransactionAspectSupport</span></span><span class="o" style="font-weight:700;"><span class="hljs-selector-class">.</span></span><span class="na" style="color:#008080;"><span class="hljs-selector-class">currentTransactionStatus</span></span><span class="o" style="font-weight:700;">()<span class="hljs-selector-class">.</span></span><span class="na" style="color:#008080;"><span class="hljs-selector-class">setRollbackOnly</span></span><span class="o" style="font-weight:700;">();</span>