spring


spring

1、IOC容器

Spring 通过读取 XML 或 Java 注解中的信息来获取哪些对象需要实例化。

Spring 提供 2 种不同类型的 IoC 容器,即 BeanFactory 和 ApplicationContext 容器。

1. BeanFactory 容器

BeanFactory 是最简单的容器,由 org.springframework.beans.factory.BeanFactory 接口定义,采用懒加载(lazy-load),所以容器启动比较快。BeanFactory 提供了容器最基本的功能。

为了能够兼容 Spring 集成的第三方框架(如 BeanFactoryAware、InitializingBean、DisposableBean),所以目前仍然保留了该接口。

简单来说,BeanFactory 就是一个管理 Bean 的工厂,它主要负责初始化各种 Bean,并调用它们的生命周期方法。

BeanFactory 接口有多个实现类,最常见的是 org.springframework.beans.factory.xml.XmlBeanFactory。使用 BeanFactory 需要创建 XmlBeanFactory 类的实例,通过 XmlBeanFactory 类的构造函数来传递 Resource 对象。如下所示。

Resource resource = new ClassPathResource("applicationContext.xml"); BeanFactory factory = new XmlBeanFactory(resource);  

2. ApplicationContext 容器

ApplicationContext 继承了 BeanFactory 接口,由 org.springframework.context.ApplicationContext 接口定义,对象在启动容器时加载。ApplicationContext 在 BeanFactory 的基础上增加了很多企业级功能,例如 AOP、国际化、事件支持等。

ApplicationContext 接口有两个常用的实现类,具体如下。

1)ClassPathXmlApplicationContext

该类从类路径 ClassPath 中寻找指定的 XML 配置文件,并完成 ApplicationContext 的实例化工作,具体如下所示。

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(String configLocation);

在上述代码中,configLocation 参数用于指定 Spring 配置文件的名称和位置,如 Beans.xml。

2)FileSystemXmlApplicationContext

该类从指定的文件系统路径中寻找指定的 XML 配置文件,并完成 ApplicationContext 的实例化工作,具体如下所示。

ApplicationContext applicationContext = new FileSystemXmlApplicationContext(String configLocation);

它与 ClassPathXmlApplicationContext 的区别是:在读取 Spring 的配置文件时,FileSystemXmlApplicationContext 不会从类路径中读取配置文件,而是通过参数指定配置文件的位置。即 FileSystemXmlApplicationContext 可以获取类路径之外的资源,如“F:/workspaces/Beans.xml”。


2、Bean 定义

Spring 配置文件支持两种格式,即 XML 文件格式和 Properties 文件格式。

  • Properties 配置文件主要以 key-value 键值对的形式存在,只能赋值,不能进行其他操作,适用于简单的属性配置。
  • XML 配置文件是树形结构,相对于 Properties 文件来说更加灵活。XML 配置文件结构清晰,但是内容比较繁琐,适用于大型复杂的项目。
元素的常用属性
属性名称 描述
id Bean 的唯一标识符,Spring 容器对 Bean 的配置和管理都通过该属性完成。id 的值必须以字母开始,可以使用字母、数字、下划线等符号。
name name 属性中可以为 Bean 指定多个名称,每个名称之间用逗号或分号隔开。Spring 容器可以通过 name 属性配置和管理容器中的 Bean。
class 该属性指定了 Bean 的具体实现类,它必须是一个完整的类名,即类的全限定名。
scope 用于设定 Bean 实例的作用域,属性值可以为 singleton(单例)、prototype(原型)、request、session 和 global Session。其默认值是 singleton
constructor-arg 元素的子元素,可以使用此元素传入构造参数进行实例化。该元素的 index 属性指定构造参数的序号(从 0 开始),type 属性指定构造参数的类型
property 元素的子元素,用于调用 Bean 实例中的 setter 方法来属性赋值,从而完成依赖注入。该元素的 name 属性用于指定 Bean 实例中相应的属性名
ref 等元素的子元索,该元素中的 bean 属性用于指定对某个 Bean 实例的引用
value 等元素的子元素,用于直接指定一个常量值
list 用于封装 List 或数组类型的依赖注入
set 用于封装 Set 类型的依赖注入
map 用于封装 Map 类型的依赖注入
entry 元素的子元素,用于设置一个键值对。其 key 属性指定字符串类型的键值,ref 或 value 子元素指定其值
init-method 容器加载 Bean 时调用该方法,类似于 Servlet 中的 init() 方法
destroy-method 容器删除 Bean 时调用该方法,类似于 Servlet 中的 destroy() 方法。该方法只在 scope=singleton 时有效
lazy-init 懒加载,值为 true,容器在首次请求时才会创建 Bean 实例;值为 false,容器在启动时创建 Bean 实例。该方法只在 scope=singleton 时有效

3、Bean作用域

<bean id="..." class="..." scope="singleton"/>
作用域
singleton 默认值,单例模式,表示在 Spring 容器中只有一个 Bean 实例,Bean 以单例的方式存在。
prototype 原型模式,表示每次通过 Spring 容器获取 Bean 时,容器都会创建一个 Bean 实例。
request 每次 HTTP 请求,容器都会创建一个 Bean 实例。该作用域只在当前 HTTP Request 内有效。
session 同一个 HTTP Session 共享一个 Bean 实例,不同的 Session 使用不同的 Bean 实例。该作用域仅在当前 HTTP Session 内有效。
application 同一个 Web 应用共享一个 Bean 实例,该作用域在当前 ServletContext 内有效。
websocket websocket 的作用域是 WebSocket ,即在整个 WebSocket 中有效。

4、Bean生命周期

  • Bean 的定义 -> Bean 的初始化 -> Bean 的使用 -> Bean 的销毁

  • Spring 根据 Bean 的作用域来选择管理方式

    1. 对于 singleton 作用域的 Bean,Spring 能够精确地知道该 Bean 何时被创建,何时初始化完成,以及何时被销毁;
    2. 对于 prototype 作用域的 Bean,Spring 只负责创建,当容器创建了 Bean 的实例后,Bean 的实例就交给客户端代码管理,Spring 容器将不再跟踪其生命周期
  • Bean生命周期意义:利用 Bean 在其存活期间的指定时刻(Bean 被初始化后和被销毁前)完成一些相关操作

  • Spring 官方提供了 3 种方法实现初始化回调和销毁回调:

    1. 实现 InitializingBean 和 DisposableBean 接口;
    2. 在 XML 中配置 init-method 和 destory-method;
    3. 使用 @PostConstruct 和 @PreDestory 注解。
  • 在一个 Bean 中有多种生命周期回调方法时,优先级为:注解 > 接口 > XML。

  • spring后置处理器(BeanPostProcessor)

    BeanPostProcessor 接口可以自定义调用初始化前后执行的操作方法。

    public interface BeanPostProcessor {
        Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
        Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
    }

Spring 容器中 Bean 的生命周期流程图

Bean的生命周期
  1. Spring 启动,查找并加载需要被 Spring 管理的 Bean,并实例化 Bean。
  2. 利用依赖注入完成 Bean 中所有属性值的配置注入。
  3. 如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。
  4. 如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。
  5. 如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
  6. 如果 Bean 实现了 BeanPostProcessor 接口,则 Spring 调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。
  7. 如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。
  8. 如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。
  9. 如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。
  10. 如果在 中指定了该 Bean 的作用域为 singleton,则将该 Bean 放入 Spring IoC 的缓存池中,触发 Spring 对该 Bean 的生命周期管理;如果在 中指定了该 Bean 的作用域为 prototype,则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。
  11. 如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法销毁 Bean;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。

5、Bean注解装配

Spring 默认不使用注解装配 Bean,因此需要在配置文件中添加 context:annotation-config/,启用注解。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
    <!--使用context命名空间,通知spring扫描指定目录,进行注解的解析 -->
    <context:component-scan
        base-package="net.biancheng" />
</beans>
注解 描述
@Component 可以使用此注解描述 Spring 中的 Bean,但它是一个泛化的概念,仅仅表示一个组件(Bean),并且可以作用在任何层次。使用时只需将该注解标注在相应类上即可。
@Repository 用于将数据访问层(DAO层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Service 通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Controller 通常作用在控制层(如 Struts2 的 Action、SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Autowired 可以应用到 Bean 的属性变量、属性的 setter 方法、非 setter 方法及构造函数等,配合对应的注解处理器完成 Bean 的自动配置工作。默认按照 Bean 的类型进行装配。
@Qualifier 与 @Autowired 注解配合使用,会将默认的按 Bean 类型装配修改为按 Bean 的实例名称装配,Bean 的实例名称由 @Qualifier 注解的参数指定。
@Resource 作用与 Autowired 相同,区别在于 @Autowired 默认按照 Bean 类型装配,而 @Resource 默认按照 Bean 实例名称进行装配。@Resource 中有两个重要属性:name 和 type。Spring 将 name 属性解析为 Bean 的实例名称,type 属性解析为 Bean 的实例类型。如果指定 name 属性,则按实例名称进行装配;如果指定 type 属性,则按 Bean 类型进行装配。如果都不指定,则先按 Bean 实例名称装配,如果不能匹配,则再按照 Bean 类型进行装配;如果都无法匹配,则抛出 NoSuchBeanDefinitionException 异常。

6、AOP

1)作用:

AOP 的作用就是保证开发者在不修改源代码的前提下,为系统中的业务组件添加某种通用功能。AOP 就是代理模式的典型应用。

2)优势:

  1. 提供声明式企业服务,特别是作为 EJB 声明式服务的替代品。最重要的是,这种服务是声明式事务管理。
  2. 允许用户实现自定义切面。在某些不适合用 OOP 编程的场景中,采用 AOP 来补充。
  3. 可以对业务逻辑的各个部分进行隔离,从而使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时也提高了开发效率。

3)Spring AOP 和 AspectJ

目前最流行的AOP框架有两种:Spring AOP 和 AspectJ

AOP框架 描述
Spring AOP Spring AOP 是基于 AOP 编程模式的一个框架,它能够有效的减少系统间的重复代码,达到松耦合的目的。Spring AOP 使用纯 Java 实现,不需要专门的编译过程和类加载器,在运行期间通过代理方式向目标类植入增强的代码。有两种实现方式:基于接口的 JDK 动态代理基于继承的 CGLIB 动态代理
AspectJ AspectJ 是一个基于 Java 语言的 AOP 框架,从 Spring 2.0 开始,Spring AOP 引入了对 AspectJ 的支持。AspectJ 扩展了 Java 语言,提供了一个专门的编译器,在编译时提供横向代码的植入。

4)APO术语

名称 说明
Joinpoint(连接点) 指那些被拦截到的点,在 Spring 中,指可以被动态代理拦截目标类的方法。
Pointcut(切入点) 指要对哪些 Joinpoint 进行拦截,即被拦截的连接点。
Advice(通知) 指拦截到 Joinpoint 之后要做的事情,即对切入点增强的内容。
Target(目标) 指代理的目标对象。
Weaving(植入) 指把增强代码应用到目标上,生成代理对象的过程。
Proxy(代理) 指生成的代理对象。
Aspect(切面) 切入点和通知的结合。

5)Advice(通知)

Advice表示通知或增强处理,共有5种类型

通知 说明
before(前置通知) 通知方法在目标方法调用之前执行
after(后置通知) 通知方法在目标方法返回或异常后调用
after-returning(返回后通知) 通知方法会在目标方法返回后调用
after-throwing(抛出异常通知) 通知方法会在目标方法抛出异常后调用
around(环绕通知) 通知方法会将目标方法封装起来

6)基于xml和注解实现AOP

基于xml实现,在xml配置切面类,需要注册切面类

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
    
    <aop:config>
    	<aop:aspect id="xml" ref="xmlAspectJ">
    		<aop:pointcut id="xmlAop" expression="execution(* com.lujiahong.spring.aop.xmlAop.*.* (..))"/>
    		<aop:before pointcut-ref="xmlAop" method="before"/>
    		<aop:after-returning pointcut-ref="xmlAop" returning="returnValue" method="afterReturning"/>
    		<aop:after-throwing pointcut-ref="xmlAop" throwing="e" method="afterThrowing"/>
    		<aop:after pointcut-ref="xmlAop" method="after"/>
    	</aop:aspect>
    </aop:config>
    
    <bean id="aboutXmlAop" class="com.lujiahong.spring.aop.xmlAop.AboutXmlAop">
    	<property name="msg" value="My name is XmlAop"/>
    </bean>
    
    <!-- 注册aop切面类 -->
    <bean id="xmlAspectJ" class="com.lujiahong.spring.aop.xmlAop.XmlAspectJ"/>
    
</beans>

基于注解实现,方式一:在 XML 文件中添加以下内容启用 @AspectJ。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

	<!-- 启用 @AspectJ -->
	<aop:aspectj-autoproxy/>
	
	<bean id="aboutAnnotationAop" class="com.lujiahong.spring.aop.annotationAop.AboutAnnotationAop">
		<property name="msg" value="My name is AboutAnnotationAop"/>
	</bean>
	
	<!-- 注册切面类 -->
	<bean id="annotationAspectJ" class="com.lujiahong.spring.aop.annotationAop.AnnotationAspectJ"/>
</beans>

基于注解实现,方式二:添加配置类,类上添加@Configure和@EnableAspectJAutoProxy注解启用@AspectJ

spring功能扩展:

  • @EnableAspectJAutoProxy开启AOP
  • @EnableTransactionManagement开启spring事务管理
  • @EnableCaching开启spring缓存
  • @EnableWebMvc 开启webMvc
@Configuration 
@EnableAspectJAutoProxy
public class Appconfig {
}

7、spring JdbcTemplate类

Spring 针对数据库开发提供了 JdbcTemplate 类,该类封装了 JDBC,支持对数据库的所有操作。

JdbcTemplate 位于 spring-jdbc-x.x.x.jar 包中,其全限定命名为 org.springframework.jdbc.core.JdbcTemplate。此外使用 JdbcTemplate 还需要导入 spring-tx-x.x.x.jar 包,该包用来处理事务和异常。

在 Spring 中,JDBC 的相关信息在配置文件中完成,其配置模板如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http:/www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd"> 
   
    <!-- 配置数据源 --> 
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!--数据库驱动-->
        <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
        <!--连接数据库的url-->
        <property name= "url" value="jdbc:mysql://localhost/xx" />
        <!--连接数据库的用户名-->
        <property name="username" value="root" />
        <!--连接数据库的密码-->
        <property name="password" value="root" />
    </bean>
    <!--配置JDBC模板-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--默认必须使用数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--配置注入类-->
    <bean id="xxx" class="xxx">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>
    ...
</beans>

本节使用 MySQL 数据库,如果您使用的是其它数据库,需要对内容进行相应的修改。

上述代码中定义了 3 个 Bean,分别是 dataSource、jdbcTemplate 和需要注入类的 Bean。其中 dataSource 对应的是 DriverManagerDataSource 类,用于对数据源进行配置;jdbcTemplate 对应 JdbcTemplate 类,该类中定义了 JdbcTemplate 的相关配置。

在 dataSource 中,定义了 4 个连接数据库的属性,如下表所示。

属性名 说明
driverClassName 所使用的驱动名称,对应驱动 JAR 包中的 Driver 类
url 数据源所在地址
username 访问数据库的用户名
password 访问数据库的密码

上表中的属性值需要根据数据库类型或者机器配置的不同进行相应设置。如果数据库类型不同,则需要更改驱动名称。如果数据库不在本地,则需要将 localhost 替换成相应的主机 IP。

在定义 JdbcTemplate 时,需要将 dataSource 注入到 JdbcTemplate 中。而在其他的类中要使用 JdbcTemplate,也需要将 JdbcTemplate 注入到使用类中(通常注入 dao 类中)。

在 JdbcTemplate 类中,提供了大量的查询和更新数据库的方法,如 query()、update() 等,如下表所示。

方法 说明
public int update(String sql) 用于执行新增、修改、删除等语句 args 表示需要传入到 query 中的参数
public int update(String sql,Object… args)
public void execute(String sql) 可以执行任意 SQL,一般用于执行 DDL 语句 action 表示执行完 SQL 语句后,要调用的函数
public T execute(String sql, PreparedStatementCallback action)
public T query(String sql, ResultSetExtractor rse) 用于执行查询语句 以 ResultSetExtractor 作为参数的 query 方法返回值为 Object,使用查询结果需要对其进行强制转型 以 RowMapper 作为参数的 query 方法返回值为 List

8、spring 事务

  1. 事务(Transaction)是面向关系型数据库(RDBMS)企业应用程序的重要组成部分,用来确保数据的完整性和一致性。

  2. 事务的四大特性(ACID):

    • 原子性(Atomicity):一个事务是一个不可分割的单位,事务中所包括的动作要么都做,要么都不做;
    • 一致性(Consistency):事务必须保证数据库从一个一致性状态变到另一个一致性状态,一致性和原子性是密切相关的;
    • 隔离性(Isolation):一个事务的执行不能被其它事务干扰,即一个事务内部的操作及使用的数据对并发的其它事务是隔离的,并发执行的各个事务之间不能相互打扰;
    • 持久性(Durability):持久性也称为永久性,指一个事务一旦提交,它对数据库中数据的改变就是永久性的,后面的其它操作和故障都不应该对其有任何影响。
  3. 编程式和声明式:

    • 编程式事务管理:通过编写代码实现的事务管理,灵活性高,但难以维护;
    • 声明式事务管理:(xml和注解两种方式实现),底层采用AOP,无需像编程式那样书写代码,只需在配置文件进行相关的规则说明即可;
  4. 事务管理接口:

    PlatformTransactionManager、TransactionDefinition、TransactionSatus是事务三个核心接口

    • PlatformTransactionManager

      public interface PlatformTransactionManager {
          //用于获取事务的状态信息(项目中,Spring将xml中配置的事务信息封装到对象TransactionDefinition中,然后通过事务管理器的getTransation()方法获得事务的状态,并对事务进行下一步的操作)
          TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
          //用于提交事务
          void commit(TransactionStatus status) throws TransactionException;
          //用于回滚事务
          void rollback(TransactionStatus status) throws TransactionException;
      }
    • TransactionDefinition

      public interface TransactionDefinition{
          //获取事务的名称
          String getName();
          //获取事务的隔离级别
          int getIslationLevel();
          //获取事务的传播行为
          int getPropagationBehavior();
          //获取事务的超时时间
          int getTimeOut();
          //获取事务是否只读
          boolean isReadOnly();
      }
      隔离级别方法 说明
      ISOLATION_DEFAULT 使用数据库默认的隔离级别
      ISOLATION_READ_UNCOMMITTED 运行读取尚未提交的更改,可能导致脏读、幻读和不可重复读
      ISOLATION_READ_COMMITTED (ORACLE默认级别)允许读取已提交的并发事务,防止脏读,可能出现幻读和不可重复读
      ISOLATION_REPEATABLE_READ (MYSQL默认级别)多次读取相同字段的结果是一致的,防止脏读和不可重复读,可能出现幻读
      ISOLATION_SERIALIZABLE 完全服从ACID的隔离级别,防止脏读、不可重复读、幻读
      传播行为名称 说明(传播行为用来控制是否创建事务以及如何创建事务)
      PROPAGATION_MANDATORY 支持当前事务,如果不存在当前事务,则引发异常
      PROPAGATION_NESTED 如果当前事务存在,则在嵌套事务中执行
      PROPAGATION_NEVER 不支持当前事务,如果当前事务存在,则引发异常
      PROPAGATION_NOT_SUPPORTED 不支持当前事务,始终以非事务方式进行
      PROPAGATION_REQUIRED 默认传播行为,支持当前事务,如果不存在,则创建一个新的
      PROPAGATION_REQUIRED_NEW 创建新事务,如果已存在事务则暂停当前事务
      PROPAGATION_SUPPORTS 支持当前事务,如果不存在事务,则以非事务的方式执行
    • TransactionStatus

      TransactionStatus提供方法:控制事务的执行和查询事务的状态

      public interface TransactionStatus extends SavepointManager{
      	//获取是否存在保存点
          boolean hasSavepoint();
          //获取事务是否完成
          boolean isCompleted();
          //获取是否是新事务
          boolean isNewTransaction();
          //获取事务是否回滚
          boolean isRollbackOnly();
          //设置事务回滚
          void setRollbackOnly();
      }

1)编程式

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!-- 配置数据源 -->
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!--数据库驱动 -->
        <property name="driverClassName"
            value="com.mysql.jdbc.Driver" />
        <!--连接数据库的url -->
        <property name="url" value="jdbc:mysql://localhost/test" />
        <!--连接数据库的用户名 -->
        <property name="username" value="root" />
        <!--连接数据库的密码 -->
        <property name="password" value="root" />
    </bean>

    <!--配置JDBC模板 -->
    <bean id="jdbcTemplate"
        class="org.springframework.jdbc.core.JdbcTemplate">
        <!--默认必须使用数据源 -->
        <property name="dataSource" ref="dataSource" />
    </bean>
	<!--spring中注入事务管理器-->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="userdao" class="net.biancheng.UserDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate" />
        <!--在指定bean中注入该事务管理器对象即可使用-->
        <property name="transactionManager" ref="transactionManager" />
    </bean>

</beans>

2)XML

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <!-- 配置数据源 -->
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!--数据库驱动 -->
        <property name="driverClassName"
            value="com.mysql.jdbc.Driver" />
        <!--连接数据库的url -->
        <property name="url" value="jdbc:mysql://localhost/test" />
        <!--连接数据库的用户名 -->
        <property name="username" value="root" />
        <!--连接数据库的密码 -->
        <property name="password" value="root" />
    </bean>

    <!-- 编写通知:对事务进行增强(通知),需要编写切入点和具体执行事务的细节 -->
    <tx:advice id="txAdvice"
        transaction-manager="transactionManager">
        <tx:attributes>
             <!-- 给切入点方法添加事务详情,name表示方法名称,*表示任意方法名称,propagation用于设置传播行为,read-only表示隔离级别,是否只读 -->
            <tx:method name="*" propagation="SUPPORTS" readOnly = "false"/>
        </tx:attributes>
    </tx:advice>

    <!-- aop编写,让Spring自动对目标生成代理,需要使用AspectJ的表达式 -->
    <aop:config>
        <!-- 切入点,execution 定义的表达式表示net.biencheng包下的所有类所有方法都应用该是事务 -->
        <aop:pointcut id="createOperation"
            expression="execution(* net.biancheng.*.*(..))" />
       
        <aop:advisor advice-ref="txAdvice"
            pointcut-ref="createOperation" />
    </aop:config>

    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <bean id="jdbcTemplate"
        class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <bean id="userdao" class="net.biancheng.UserDaoImpl">
        <property name="dataSource" ref="dataSource" />
        <property name="jdbcTemplate" ref="jdbcTemplate" />
    </bean>
</beans>

3)注解

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false,timeout=60)

常用属性说明如下:

  • propagation:设置事务的传播行为;
  • isolation:设置事务的隔离级别;
  • readOnly:设置是读写事务还是只读事务;
  • timeout:事务超时事件(单位:s)。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <!-- 配置数据源 -->
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <!--数据库驱动 -->
        <property name="driverClassName"
            value="com.mysql.jdbc.Driver" />
        <!--连接数据库的url -->
        <property name="url" value="jdbc:mysql://localhost/test" />
        <!--连接数据库的用户名 -->
        <property name="username" value="root" />
        <!--连接数据库的密码 -->
        <property name="password" value="root" />
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="jdbcTemplate"
        class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="userdao" class="net.biancheng.UserDaoImpl">
        <property name="dataSource" ref="dataSource" />
        <property name="jdbcTemplate" ref="jdbcTemplate" />
    </bean>

    <!-- 最重要的一步:注册事务管理驱动 ,注册后@Transaction起作用-->
    <tx:annotation-driven
        transaction-manager="transactionManager" />
</beans>

文章作者: LJH
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 LJH !
  目录