第二周spring内容

≯℡__Kan透↙ 提交于 2020-01-19 04:42:32

spring通过ioc创建bean的三种方式

一、使用自动装配创建bean

  Spring主要从两个角度来实现自动化装配:①组件扫描;②自动装配。组件扫描指的是Spring会自动扫描指定包及其子包下的所有bean,并将其放入spring容器中进行管理,而自动装配则是指对于有相互依赖关系的bean,Spring会将其自动装配到目标bean中,如将repository层的bean自动装配到service层中。

  自动装配的方式创建bean主要是使用一个被专门用来当做配置的接口(或类)来实现的。配置接口上主要使用两个注解:@Configuration和@ComponentScan。@Configuration来标注该接口是用于定义配置的,而@ComponentScan则是用于指定扫描的bean的文件夹的,默认情况下Spring会扫描该配置接口所在包及其子包下的所有bean。
  这样Spring就可以自动创建一个SgtPeppers的实例,并且将其放到Spring容器中进行管理,另外我们也可以使用@Named注解来创建一个bean。

  上面只是讲了如何创建一个bean,而自动装配还有另一方面的概念:依赖注入。其是指Spring会将一个bean所依赖的bean自动装配进来。依赖注入是通过@Autowired或@Resource来实现的,当一个bean需要另一个bean作为其属性的时候,其只需要声明该bean的一个变量,并且对该属性使用@Autowired或@Resource标注一下即可。

二、在java中进行显示的配置

  这种方式创建bean则不需要进行组件扫描了,其是通过在配置类中通过方法显示的创建一个bean,该方法则需要使用@Bean注解进行标识。=这里需要说明的是,①在@Bean标注的方法上如果有参数,那么Spring会自动在容器中查找是否有参数类型的bean,并将其注入进来;②如果不使用参数的方式注入依赖的bean,可以使用调用方法的方式,

  这里需要注意的一点是,这种方式相对于第一种方式需要对每个bean都进行显示声明,但是其有自己的优点,对于一些额外的类库中的类,我们无法在其中加入Spring的注解,但是却要将其加入到Spring容器中进行管理,那么我们就可以通过这种方式来显示的声明这些类的bean。因而,在项目中我们可以通过将第一种方式和第二种方式结合使用来创建和管理bean。

三、xml中进行显示的配置

  在xml文件中配置bean是Spring最先使用的一种方式,在该xml文件中主要是一个<beans></beans>标签,其有一个子标签<bean></bean>,所有的bean的声明都是在<bean>子标签中声明的。<bean>标签主要有两个属性:id和class。id用来指定要声明的bean的名称,如果没指定则创建的bean的默认名称为class属性的值加上#数字,class属性则是用来指定要创建的类(包含包名)的
  以上就是Spring创建bean的三种方式的介绍,可以看出,使用xml进行显示的配置这种方式比较复杂,而且因为其使用的是字符串,这不是类型安全的,使用JavaConfig则只能创建少量的bean,但是其可以为第三方库的类创建bean,而使用隐式的bean发现机制和自动装配则可以扫描大量的bean,但其不能将第三方库的bean收录到Spring容器中,因为第三方库的代码中不能添加Spring的注解。总而言之,后两种方式是现在比较常用的方式,并且可以结合起来使用,以实现对bean的控制。

事务的传播特性

  1. PROPAGATION_REQUIRED:加入当前正要执行的事务不在另外一个事务里,那么就起一个新的事务。比如说,ServiceB.methodB的事务级别定义为PROPAGATION_REQUIRED,那么由于执行ServiceA.methodA的时候,ServiceA.methodA已经起了事务,这时调用ServiceB.methodB,ServiceB.methodB看到自己已经运行在ServiceA.methodA的事务内部,就不再起新的事务。而假如ServiceA.methodA运行的时候发现自己没有在事务中,他就会为自己分配一个事务。这样,在ServiceA.methodA或者在ServiceB.methodB内的任何地方出现异常,事务都会被回滚。即使ServiceB.methodB的事务已经被提交,但是ServiceA.methodA在接下来fail要回滚,ServiceB.methodB也要回滚。

  2. PROPAGATION_SUPPORTS:如果当前在事务中,即以事务的形式运行,如果当前不再一个事务中,那么就以非事务的形式运行。

  3. PROPAGATION_MANDATORY:必须在一个事务中运行。也就是说,他只能被一个父事务调用。否则,他就要抛出异常。

  4. PROPAGATION_REQUIRES_NEW:这个就比较绕口了。 比如我们设计ServiceA.methodA的事务级别为PROPAGATION_REQUIRED,ServiceB.methodB的事务级别为PROPAGATION_REQUIRES_NEW,那么当执行到ServiceB.methodB的时候,ServiceA.methodA所在的事务就会挂起,ServiceB.methodB会起一个新的事务,等待ServiceB.methodB的事务完成以后,他才继续执行。他与PROPAGATION_REQUIRED的事务区别在于事务的回滚程度了。因为ServiceB.methodB是新起一个事务,那么就是存在两个不同的事务。如果ServiceB.methodB已经提交,那么ServiceA.methodA失败回滚,ServiceB.methodB是不会回滚的。如果ServiceB.methodB失败回滚,如果他抛出的异常被ServiceA.methodA捕获,ServiceA.methodA事务仍然可能提交。

  5. PROPAGATION_NOT_SUPPORTED:当前不支持事务。比如ServiceA.methodA的事务级别是PROPAGATION_REQUIRED ,而ServiceB.methodB的事务级别是PROPAGATION_NOT_SUPPORTED ,那么当执行到ServiceB.methodB时,ServiceA.methodA的事务挂起,而他以非事务的状态运行完,再继续ServiceA.methodA的事务。

  6. PROPAGATION_NEVER:不能在事务中运行。假设ServiceA.methodA的事务级别是PROPAGATION_REQUIRED, 而ServiceB.methodB的事务级别是PROPAGATION_NEVER ,那么ServiceB.methodB就要抛出异常了。

  7. PROPAGATION_NEST:理解Nested的关键是savepoint。

他与PROPAGATION_REQUIRES_NEW的区别是,PROPAGATION_REQUIRES_NEW另起一个事务,将会与他的父事务相互独立, 而Nested的事务和他的父事务是相依的,他的提交是要等和他的父事务一块提交的。也就是说,如果父事务最后回滚,他也要回滚的。而Nested事务的好处是他有一个savepoint。也就是说ServiceB.methodB失败回滚,那么ServiceA.methodA也会回滚到savepoint点上,ServiceA.methodA可以选择另外一个分支,比如 ServiceC.methodC,继续执行,来尝试完成自己的事务。 但是这个事务并没有在EJB标准中定义。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!