Spring_four

Posted leccoo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring_four相关的知识,希望对你有一定的参考价值。

Spring_four

基于XML的AOP实现事务控制

坐标xml

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context</artifactId>
  5. <version>5.0.2.RELEASE</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework</groupId>
  9. <artifactId>spring-test</artifactId>
  10. <version>5.0.2.RELEASE</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>commons-dbutils</groupId>
  14. <artifactId>commons-dbutils</artifactId>
  15. <version>1.4</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>mysql</groupId>
  19. <artifactId>mysql-connector-java</artifactId>
  20. <version>5.1.6</version>
  21. </dependency>
  22. <dependency>
  23. <groupId>c3p0</groupId>
  24. <artifactId>c3p0</artifactId>
  25. <version>0.9.1.2</version>
  26. </dependency>
  27. <dependency>
  28. <groupId>junit</groupId>
  29. <artifactId>junit</artifactId>
  30. <version>4.12</version>
  31. </dependency>
  32. <dependency>
  33. <groupId>org.aspectj</groupId>
  34. <artifactId>aspectjweaver</artifactId>
  35. <version>1.8.7</version>
  36. </dependency>
  37. </dependencies>

技术图片

删除AccountServiceTest测试类上的@Qualifier的注解,不产生代理对象

  1. /**
  2. * 使用Junit单元测试:测试我们的配置
  3. */
  4. @RunWith(SpringJUnit4ClassRunner.class)
  5. @ContextConfiguration(locations = "classpath:applicationContext.xml")
  6. public class AccountServiceTest
  7. @Autowired
  8. private AccountService as;
  9. @Test
  10. public void testTransfer()
  11. as.transfer("aaa","bbb",100f);

此时事务没有控制住


【配置文件】添加spring的aop

applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:aop="http://www.springframework.org/schema/aop"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/aop
  8. http://www.springframework.org/schema/aop/spring-aop.xsd">
  9. <!-- 配置Service -->
  10. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl">
  11. <!-- 注入dao -->
  12. <property name="accountDao" ref="accountDao"></property>
  13. <!--注入事务管理器
  14. <property name="txManager" ref="txManager"></property>-->
  15. </bean>
  16. <!--配置Dao对象-->
  17. <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl">
  18. <!-- 注入QueryRunner -->
  19. <property name="runner" ref="runner"></property>
  20. <!-- 注入ConnectionUtils -->
  21. <property name="connectionUtils" ref="connectionUtils"></property>
  22. </bean>
  23. <!--配置QueryRunner-->
  24. <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
  25. <!--<constructor-arg name="ds" ref="dataSource"></constructor-arg>-->
  26. </bean>
  27. <!-- 配置数据源 -->
  28. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  29. <!--连接数据库的必备信息-->
  30. <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
  31. <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  32. <property name="user" value="root"></property>
  33. <property name="password" value="root"></property>
  34. </bean>
  35. <!-- 配置Connection的工具类 ConnectionUtils -->
  36. <bean id="connectionUtils" class="com.it.utils.ConnectionUtils">
  37. <!-- 注入数据源-->
  38. <property name="dataSource" ref="dataSource"></property>
  39. </bean>
  40. <!-- 配置事务管理器-->
  41. <bean id="txManager" class="com.it.utils.TransactionManager">
  42. <!-- 注入ConnectionUtils -->
  43. <property name="connectionUtils" ref="connectionUtils"></property>
  44. </bean>
  45. <aop:config>
  46. <aop:pointcut id="pc" expression="execution(* com.it.service..*.*(..))"></aop:pointcut>
  47. <aop:aspect ref="txManager">
  48. <!--配置前置通知:开启事务-->
  49. <aop:before method="beginTransaction" pointcut-ref="pc"></aop:before>
  50. <!--配置后置通知:提交事务-->
  51. <aop:after-returning method="commitTransaction" pointcut-ref="pc"></aop:after-returning>
  52. <!--配置异常通知:回滚事务-->
  53. <aop:after-throwing method="rollbackTransaction" pointcut-ref="pc"></aop:after-throwing>
  54. <!--配置最终通知:释放连接-->
  55. <aop:after method="closeTransaction" pointcut-ref="pc"></aop:after>
  56. </aop:aspect>
  57. </aop:config>
  58. </beans>

【注解】添加spring的aop

可以使用【前置通知】、【后置通知】、【异常通知】、【最终通知】

坐标

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context</artifactId>
  5. <version>5.0.2.RELEASE</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework</groupId>
  9. <artifactId>spring-test</artifactId>
  10. <version>5.0.2.RELEASE</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>commons-dbutils</groupId>
  14. <artifactId>commons-dbutils</artifactId>
  15. <version>1.4</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>mysql</groupId>
  19. <artifactId>mysql-connector-java</artifactId>
  20. <version>5.1.6</version>
  21. </dependency>
  22. <dependency>
  23. <groupId>c3p0</groupId>
  24. <artifactId>c3p0</artifactId>
  25. <version>0.9.1.2</version>
  26. </dependency>
  27. <dependency>
  28. <groupId>junit</groupId>
  29. <artifactId>junit</artifactId>
  30. <version>4.12</version>
  31. </dependency>
  32. <dependency>
  33. <groupId>org.aspectj</groupId>
  34. <artifactId>aspectjweaver</artifactId>
  35. <version>1.8.7</version>
  36. </dependency>
  37. </dependencies>

配置AccountServiceImpl.java的注解

  1. @Service
  2. public class AccountServiceImpl implements AccountService
  3. @Autowired
  4. private AccountDao accountDao;

配置AccountDaoImpl.java的注解

  1. @Repository
  2. public class AccountDaoImpl implements AccountDao
  3. @Autowired
  4. private QueryRunner runner;
  5. @Autowired
  6. private ConnectionUtils connectionUtils;

配置ConnectionUtils.java的注解

  1. @Component
  2. public class ConnectionUtils
  3. private ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
  4. @Autowired
  5. private DataSource dataSource;

配置TransactionManager.java的注解

  1. @Component
  2. @Aspect // 切面
  3. public class TransactionManager
  4. @Autowired
  5. private ConnectionUtils connectionUtils;
  6. @Pointcut(value = "execution(* com.it.service..*.*(..))") // 切入点
  7. public void pc();
  8. /**
  9. * 开启事务
  10. */
  11. @Before(value = "pc()")
  12. public void beginTransaction()
  13. try
  14. System.out.println("前置通知");
  15. connectionUtils.getThreadConnection().setAutoCommit(false);
  16. catch (Exception e)
  17. e.printStackTrace();
  18. /**
  19. * 提交事务
  20. */
  21. @AfterReturning(value = "pc()")
  22. public void commit()
  23. try
  24. System.out.println("后置通知");
  25. connectionUtils.getThreadConnection().commit();
  26. catch (Exception e)
  27. e.printStackTrace();
  28. /**
  29. * 回滚事务
  30. */
  31. @AfterThrowing(value = "pc()")
  32. public void rollback()
  33. try
  34. System.out.println("异常通知");
  35. connectionUtils.getThreadConnection().rollback();
  36. catch (Exception e)
  37. e.printStackTrace();
  38. /**
  39. * 释放连接
  40. */
  41. @After(value = "pc()")
  42. public void release()
  43. try
  44. System.out.println("最终通知");
  45. connectionUtils.getThreadConnection().close();//把连接还回连接池中
  46. connectionUtils.removeConnection();
  47. catch (Exception e)
  48. e.printStackTrace();

配置spring容器

配置applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:aop="http://www.springframework.org/schema/aop"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/aop
  9. http://www.springframework.org/schema/aop/spring-aop.xsd
  10. http://www.springframework.org/schema/context
  11. http://www.springframework.org/schema/context/spring-context.xsd">
  12. <!--开启注解支持的组件扫描-->
  13. <context:component-scan base-package="com.it"></context:component-scan>
  14. <!--开启aop的注解支持-->
  15. <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  16. <!--配置QueryRunner-->
  17. <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
  18. <!--<constructor-arg name="ds" ref="dataSource"></constructor-arg>-->
  19. </bean>
  20. <!-- 配置数据源 -->
  21. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  22. <!--连接数据库的必备信息-->
  23. <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
  24. <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  25. <property name="user" value="root"></property>
  26. <property name="password" value="root"></property>
  27. </bean>
  28. </beans>

text

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration(locations = "classpath:applicationContext.xml")
  3. public class AccountServiceTest
  4. @Autowired
  5. private AccountService as;
  6. @Test
  7. public void testTransfer()
  8. as.transfer("aaa","bbb",100f);

但是发现,抛出异常。

技术图片

因为注解的方式执行顺序是【前置通知】、【最终通知】、【异常通知】/【后置通知】

技术图片

我们需要使用环绕通知解决问题。

配置TransactionManager.java

  1. @Component
  2. @Aspect
  3. public class TransactionManager
  4. @Autowired
  5. private ConnectionUtils connectionUtils;
  6. @Pointcut(value = "execution(* com.it.service..*.*(..))")
  7. public void pc();
  8. /**
  9. * 开启事务
  10. */
  11. //@Before(value = "pc()")
  12. public void beginTransaction()
  13. try
  14. System.out.println("前置通知");
  15. connectionUtils.getThreadConnection().setAutoCommit(false);
  16. catch (Exception e)
  17. e.printStackTrace();
  18. /**
  19. * 提交事务
  20. */
  21. //@AfterReturning(value = "pc()")
  22. public void commit()
  23. try
  24. System.out.println("后置通知");
  25. connectionUtils.getThreadConnection().commit();
  26. catch (Exception e)
  27. e.printStackTrace();
  28. /**
  29. * 回滚事务
  30. */
  31. //@AfterThrowing(value = "pc()")
  32. public void rollback()
  33. try
  34. System.out.println("异常通知");
  35. connectionUtils.getThreadConnection().rollback();
  36. catch (Exception e)
  37. e.printStackTrace();
  38. /**
  39. * 释放连接
  40. */
  41. //@After(value = "pc()")
  42. public void release()
  43. try
  44. System.out.println("最终通知");
  45. connectionUtils.getThreadConnection().close();//把连接还回连接池中
  46. connectionUtils.removeConnection();
  47. catch (Exception e)
  48. e.printStackTrace();
  49. @Around(value="pc()")
  50. public Object around(ProceedingJoinPoint joinPoint)
  51. Object returnValue = null;
  52. try
  53. this.beginTransaction(); // 开启事务
  54. returnValue = joinPoint.proceed(joinPoint.getArgs());
  55. this.commit(); // 提交事务
  56. catch (Throwable throwable)
  57. throwable.printStackTrace();
  58. this.rollback(); // 回滚事务
  59. finally
  60. this.release(); // 释放资源
  61. return returnValue;

Spring中的JdbcTemplate

1\dbcTemplate概述

它是spring框架中提供的一个对象,是对原始Jdbc API对象的简单封装。spring框架为我们提供了很多的操作模板类。

操作关系型数据的:

JdbcTemplate (操作JDBC,操作数据库)

HibernateTemplate (操作hibernate,操作数据库)

操作nosql数据库的: RedisTemplate(操作Redis,非关系型数据库)

操作消息队列(MQ)的: JmsTemplate (操作ActiveMQ,消息队列)

* 短信平台

* 邮件平台

操作索引库的:ElasticSearchTemplate(操作ElasticSearch,全文检索)

我们今天的主角在spring-jdbc-5.0.2.RELEASE.jar中,我们在导包的时候,除了要导入这个jar包外,还需要导入一个spring-tx-5.0.2.RELEASE.jar(它是和事务相关的)。


坐标xml

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context</artifactId>
  5. <version>5.0.2.RELEASE</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework</groupId>
  9. <artifactId>spring-jdbc</artifactId>
  10. <version>5.0.2.RELEASE</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework</groupId>
  14. <artifactId>spring-tx</artifactId>
  15. <version>5.0.2.RELEASE</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>mysql</groupId>
  19. <artifactId>mysql-connector-java</artifactId>
  20. <version>5.1.6</version>
  21. </dependency>
  22. </dependencies>

创建类Account.java

  1. /**
  2. * 账户的实体类
  3. */
  4. public class Account implements Serializable
  5. private Integer id;
  6. private String name;
  7. private Float money;

创建类JdbcTemplateDemo1.java

使用spring提供的数据源

  1. /**
  2. * JdbcTemplate的最基本用法
  3. */
  4. public class JdbcTemplateDemo1
  5. public static void main(String[] args)
  6. //准备数据源:spring的内置数据源
  7. DriverManagerDataSource ds = new DriverManagerDataSource();
  8. ds.setDriverClassName("com.mysql.jdbc.Driver");
  9. ds.setUrl("jdbc:mysql://localhost:3306/itcastspring");
  10. ds.setUsername("root");
  11. ds.setPassword("root");
  12. //1.创建JdbcTemplate对象
  13. JdbcTemplate jt = new JdbcTemplate();
  14. //给jt设置数据源
  15. jt.setDataSource(ds);
  16. //2.执行操作
  17. jt.execute("insert into account(name,money)values(‘ccc‘,1000)");

2\使用spring容器创建数据源和JdbcTemplate

配置applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <!--配置JdbcTemplate-->
  7. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  8. <property name="dataSource" ref="dataSource"></property>
  9. </bean>
  10. <!-- 配置数据源-->
  11. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  12. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  13. <property name="url" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  14. <property name="username" value="root"></property>
  15. <property name="password" value="root"></property>
  16. </bean>
  17. </beans>

创建JdbcTemplateDemo2.java

  1. /**
  2. * JdbcTemplate的最基本用法
  3. */
  4. public class JdbcTemplateDemo2
  5. public static void main(String[] args)
  6. //1.获取容器
  7. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  8. //2.获取对象
  9. JdbcTemplate jt = ac.getBean("jdbcTemplate",JdbcTemplate.class);
  10. //3.执行操作
  11. jt.execute("insert into account(name,money)values(‘eee‘,2222)");
  12. /* //准备数据源:spring的内置数据源
  13. DriverManagerDataSource ds = new DriverManagerDataSource();
  14. ds.setDriverClassName("com.mysql.jdbc.Driver");
  15. ds.setUrl("jdbc:mysql://localhost:3306/eesy");
  16. ds.setUsername("root");
  17. ds.setPassword("1234");
  18. //1.创建JdbcTemplate对象
  19. JdbcTemplate jt = new JdbcTemplate();
  20. //给jt设置数据源
  21. jt.setDataSource(ds);
  22. //2.执行操作
  23. jt.execute("insert into account(name,money)values(‘ccc‘,1000)");*/

3\使用JdbcTemplate操作数据库的CRUD

创建测试类JdbcTemplateDemo3.java

  1. /**
  2. * JdbcTemplate的CRUD操作
  3. */
  4. public class JdbcTemplateDemo3
  5. public static void main(String[] args)
  6. //1.获取容器
  7. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  8. //2.获取对象
  9. JdbcTemplate jt = ac.getBean("jdbcTemplate",JdbcTemplate.class);
  10. //3.执行操作
  11. //保存
  12. // jt.update("insert into account(name,money)values(?,?)","eee",3333f);
  13. //更新
  14. // jt.update("update account set name=?,money=? where id=?","test",4567,7);
  15. //删除
  16. // jt.update("delete from account where id=?",3);
  17. //查询所有
  18. // List<Account> accounts = jt.query("select * from account where money > ?",new AccountRowMapper(),1000f);
  19. // List<Account> accounts = jt.query("select * from account where money > ?",new BeanPropertyRowMapper<Account>(Account.class),1000f);
  20. // for(Account account : accounts)
  21. // System.out.println(account);
  22. //
  23. //查询一个
  24. // List<Account> accounts = jt.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),1);
  25. // System.out.println(accounts.isEmpty()?"没有内容":accounts.get(0));
  26. // Account account = jt.queryForObject("select * from account where id = ?", new BeanPropertyRowMapper<Account>(Account.class),1);
  27. // System.out.println(account);
  28. //查询返回一行一列(使用聚合函数)
  29. // Long count = jt.queryForObject("select count(*) from account where money > ?",Long.class,1000f);
  30. // System.out.println(count);
  31. /**
  32. * 定义Account的封装策略(解决实体的属性和数据库的字段名称不一致)
  33. */
  34. class AccountRowMapper implements RowMapper<Account>
  35. /**
  36. * 把结果集中的数据封装到Account中,然后由spring把每个Account加到集合中
  37. * @param rs
  38. * @param rowNum
  39. * @return
  40. * @throws SQLException
  41. */
  42. public Account mapRow(ResultSet rs, int rowNum) throws SQLException
  43. Account account = new Account();
  44. account.setId(rs.getInt("id"));
  45. account.setName(rs.getString("name"));
  46. account.setMoney(rs.getFloat("money"));
  47. return account;

4\ JdbcTemplate操作Dao

创建AccountDao接口

  1. /**
  2. * 账户的持久层接口
  3. */
  4. public interface AccountDao
  5. /**
  6. * 根据Id查询账户
  7. * @param accountId
  8. * @return
  9. */
  10. Account findAccountById(Integer accountId);
  11. /**
  12. * 根据名称查询账户
  13. * @param accountName
  14. * @return
  15. */
  16. Account findAccountByName(String accountName);
  17. /**
  18. * 更新账户
  19. * @param account
  20. */
  21. void updateAccount(Account account);

创建接口的实现类AccountDaoImpl.java

  1. /**
  2. * 账户的持久层实现类
  3. */
  4. public class AccountDaoImpl implements AccountDao
  5. JdbcTemplate jdbcTemplate;
  6. public void setJdbcTemplate(JdbcTemplate jdbcTemplate)
  7. this.jdbcTemplate = jdbcTemplate;
  8. public Account findAccountById(Integer accountId)
  9. List<Account> accounts = jdbcTemplate.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),accountId);
  10. return accounts.isEmpty()?null:accounts.get(0);
  11. public Account findAccountByName(String accountName)
  12. List<Account> accounts = jdbcTemplate.query("select * from account where name = ?",new BeanPropertyRowMapper<Account>(Account.class),accountName);
  13. if(accounts.isEmpty())
  14. return null;
  15. if(accounts.size()>1)
  16. throw new RuntimeException("结果集不唯一");
  17. return accounts.get(0);
  18. public void updateAccount(Account account)
  19. jdbcTemplate.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());

applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <!-- 配置账户的持久层-->
  7. <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl">
  8. <property name="jdbcTemplate" ref="jdbcTemplate"></property>
  9. </bean>
  10. <!--配置JdbcTemplate-->
  11. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  12. <property name="dataSource" ref="dataSource"></property>
  13. </bean>
  14. <!-- 配置数据源-->
  15. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  16. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  17. <property name="url" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  18. <property name="username" value="root"></property>
  19. <property name="password" value="root"></property>
  20. </bean>
  21. </beans>

test

  1. /**
  2. * JdbcTemplate的最基本用法
  3. */
  4. public class JdbcTemplateDemo4
  5. public static void main(String[] args)
  6. //1.获取容器
  7. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
  8. //2.获取对象
  9. AccountDao accountDao = ac.getBean("accountDao",AccountDao.class);
  10. Account account = accountDao.findAccountById(1);
  11. System.out.println(account);
  12. account.setMoney(30000f);
  13. accountDao.updateAccount(account);

5\ Spring提供JdbcDaoSupport的使用

使用AccountDaoImpl继承JdbcDaoSupport,实现AccountDao

  1. /**
  2. * 账户的持久层实现类
  3. */
  4. public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao
  5. public Account findAccountById(Integer accountId)
  6. List<Account> accounts = super.getJdbcTemplate().query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),accountId);
  7. return accounts.isEmpty()?null:accounts.get(0);
  8. public Account findAccountByName(String accountName)
  9. List<Account> accounts = super.getJdbcTemplate().query("select * from account where name = ?",new BeanPropertyRowMapper<Account>(Account.class),accountName);
  10. if(accounts.isEmpty())
  11. return null;
  12. if(accounts.size()>1)
  13. throw new RuntimeException("结果集不唯一");
  14. return accounts.get(0);
  15. public void updateAccount(Account account)
  16. super.getJdbcTemplate().update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());

applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <!-- 配置账户的持久层-->
  7. <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl">
  8. <!--<property name="jdbcTemplate" ref="jdbcTemplate"></property>-->
  9. <property name="dataSource" ref="dataSource"></property>
  10. </bean>
  11. <!--配置JdbcTemplate
  12. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  13. <property name="dataSource" ref="dataSource"></property>
  14. </bean>
  15. -->
  16. <!-- 配置数据源-->
  17. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  18. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  19. <property name="url" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  20. <property name="username" value="root"></property>
  21. <property name="password" value="root"></property>
  22. </bean>
  23. </beans>

test

  1. /**
  2. * JdbcTemplate的最基本用法
  3. */
  4. public class JdbcTemplateDemo5
  5. public static void main(String[] args)
  6. //1.获取容器
  7. ApplicationContext ac = new
  8. ClassPathXmlApplicationContext("applicationContext.xml");
  9. //2.获取对象
  10. AccountDao accountDao = ac.getBean("accountDao",AccountDao.class);
  11. Account account = accountDao.findAccountById(1);
  12. System.out.println(account);
  13. account.setMoney(30000f);
  14. accountDao.updateAccount(account);

6\ 使用JdbcDaoSupport的注解开发

创建AccountDao接口

  1. /**
  2. * 账户的持久层接口
  3. */
  4. public interface AccountDao
  5. /**
  6. * 根据Id查询账户
  7. * @param accountId
  8. * @return
  9. */
  10. Account findAccountById(Integer accountId);
  11. /**
  12. * 根据名称查询账户
  13. * @param accountName
  14. * @return
  15. */
  16. Account findAccountByName(String accountName);
  17. /**
  18. * 更新账户
  19. * @param account
  20. */
  21. void updateAccount(Account account);

创建AccountDaoImpl2实现AccountDao

  1. /**
  2. * 账户的持久层实现类
  3. */
  4. @Repository("accountDao")
  5. public class AccountDaoImpl2 extends JdbcDaoSupport implements AccountDao
  6. @Autowired // 放置到属性上,也可以放置到set方法上(将spring容器中创建的对象,通过set方法的形参传递给该方法)
  7. public void setDi(DataSource dataSource)
  8. super.setDataSource(dataSource);
  9. public Account findAccountById(Integer accountId)
  10. List<Account> accounts = jdbcTemplate.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),accountId);
  11. return accounts.isEmpty()?null:accounts.get(0);
  12. public Account findAccountByName(String accountName)
  13. List<Account> accounts = jdbcTemplate.query("select * from account where name = ?",new BeanPropertyRowMapper<Account>(Account.class),accountName);
  14. if(accounts.isEmpty())
  15. return null;
  16. if(accounts.size()>1)
  17. throw new RuntimeException("结果集不唯一");
  18. return accounts.get(0);
  19. public void updateAccount(Account account)
  20. jdbcTemplate.update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());

applicationContext-anno.xml

重新创建applicationContext-anno.xml演示,表示使用注解

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context.xsd">
  9. <context:component-scan base-package="com.it"></context:component-scan>
  10. <!-- 配置数据源-->
  11. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  12. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  13. <property name="url" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  14. <property name="username" value="root"></property>
  15. <property name="password" value="root"></property>
  16. </bean>
  17. </beans>

test

  1. /**
  2. * JdbcTemplate的最基本用法,使用注解
  3. */
  4. public class JdbcTemplateDemo5
  5. public static void main(String[] args)
  6. //1.获取容器
  7. ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext-anno.xml");
  8. //2.获取对象
  9. AccountDao accountDao = ac.getBean("accountDao",AccountDao.class);
  10. Account account = accountDao.findAccountById(1);
  11. System.out.println(account);
  12. account.setMoney(30000f);
  13. accountDao.updateAccount(account);

Spring中的事务控制

1.1 Spring事务控制我们要明确的

第一:JavaEE体系进行分层开发,事务处理位于业务层,Spring提供了分层设计业务层的事务处理解决方案。

第二:spring框架为我们提供了一组事务控制的接口 。具体在后面的第二小节介绍。这组接口是在spring-tx-5.0.2.RELEASE.jar中。

第三:spring的事务控制都是基于AOP的,它既可以使用编程的方式实现,也可以使用配置的方式(声明式)实现。我们学习的重点是使用配置(声明式事务处理)的方式实现。

1.2 Spring中事务控制的API介绍

1.2.1 PlatformTransactionManager

此接口是spring的事务管理器,它里面提供了我们常用的操作事务的方法,如下图:

技术图片

我们在开发中都是使用它的实现类:

真正管理事务的对象

org.springframework.jdbc.datasource.DataSourceTransactionManager 使用Spring JDBC或myBatis 进行持久化数据时使用

org.springframework.orm.hibernate5.HibernateTransactionManager 使用Hibernate版本进行持久化数据时使用

JpaTransactionManager,使用Jpa操作持久化数据时使用

1.2.2 TransactionDefinition

它是事务的定义信息对象,里面有如下方法:

技术图片

1:事务的隔离级别

2技术图片

2:事务的传播行为

REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。一般的选择(默认值)

SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务)

MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常

REQUERS_NEW:新建事务,如果当前在事务中,把当前事务挂起,从新开启一个新的事务。

NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起

NEVER:以非事务方式运行,如果当前存在事务,抛出异常

NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行REQUIRED类似的操作。

3:事务超时时间

默认值是-1,没有超时限制。如果有,以秒为单位、会进行设置,在事务提交/回滚后多长时间,事务失效。

4:是否是只读事务

建议查询时设置为只读。

增删改设置可写。

1.2.3TransactionStatus(了解)

此接口提供的是事务具体的运行状态,方法介绍如下图:

技术图片


Spring的编程式事务处理

坐标xml

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-context</artifactId>
  5. <version>5.0.2.RELEASE</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework</groupId>
  9. <artifactId>spring-jdbc</artifactId>
  10. <version>5.0.2.RELEASE</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework</groupId>
  14. <artifactId>spring-tx</artifactId>
  15. <version>5.0.2.RELEASE</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework</groupId>
  19. <artifactId>spring-test</artifactId>
  20. <version>5.0.2.RELEASE</version>
  21. </dependency>
  22. <dependency>
  23. <groupId>mysql</groupId>
  24. <artifactId>mysql-connector-java</artifactId>
  25. <version>5.1.6</version>
  26. </dependency>
  27. <dependency>
  28. <groupId>org.aspectj</groupId>
  29. <artifactId>aspectjweaver</artifactId>
  30. <version>1.8.7</version>
  31. </dependency>
  32. <dependency>
  33. <groupId>junit</groupId>
  34. <artifactId>junit</artifactId>
  35. <version>4.12</version>
  36. </dependency>
  37. </dependencies>

AccountDao.java

  1. /**
  2. * 账户的持久层接口
  3. */
  4. public interface AccountDao
  5. /**
  6. * 根据Id查询账户
  7. * @param accountId
  8. * @return
  9. */
  10. Account findAccountById(Integer accountId);
  11. /**
  12. * 根据名称查询账户
  13. * @param accountName
  14. * @return
  15. */
  16. Account findAccountByName(String accountName);
  17. /**
  18. * 更新账户
  19. * @param account
  20. */
  21. void updateAccount(Account account);

AccountDaoImpl.java

  1. /**
  2. * 账户的持久层实现类
  3. */
  4. public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao
  5. public Account findAccountById(Integer accountId)
  6. List<Account> accounts = this.getJdbcTemplate().query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),accountId);
  7. return accounts.isEmpty()?null:accounts.get(0);
  8. public Account findAccountByName(String accountName)
  9. List<Account> accounts = this.getJdbcTemplate().query("select * from account where name = ?",new BeanPropertyRowMapper<Account>(Account.class),accountName);
  10. if(accounts.isEmpty())
  11. return null;
  12. if(accounts.size()>1)
  13. throw new RuntimeException("结果集不唯一");
  14. return accounts.get(0);
  15. public void updateAccount(Account account)
  16. this.getJdbcTemplate().update("update account set name=?,money=? where id=?",account.getName(),account.getMoney(),account.getId());

AccountService.java

  1. /**
  2. * 账户的业务层接口
  3. */
  4. public interface AccountService
  5. /**
  6. * 根据id查询账户信息
  7. * @param accountId
  8. * @return
  9. */
  10. Account findAccountById(Integer accountId);
  11. /**
  12. * 转账
  13. * @param sourceName 转成账户名称
  14. * @param targetName 转入账户名称
  15. * @param money 转账金额
  16. */
  17. void transfer(String sourceName, String targetName, Float money);

AccountServiceImpl.java

  1. /**
  2. * 账户的业务层实现类
  3. *
  4. * 事务控制应该都是在业务层
  5. */
  6. public class AccountServiceImpl implements AccountService
  7. private AccountDao accountDao;
  8. public void setAccountDao(AccountDao accountDao)
  9. this.accountDao = accountDao;
  10. public Account findAccountById(Integer accountId)
  11. return accountDao.findAccountById(accountId);
  12. public void transfer(String sourceName, String targetName, Float money)
  13. System.out.println("transfer....");
  14. //2.1根据名称查询转出账户
  15. Account source = accountDao.findAccountByName(sourceName);
  16. //2.2根据名称查询转入账户
  17. Account target = accountDao.findAccountByName(targetName);
  18. //2.3转出账户减钱
  19. source.setMoney(source.getMoney()-money);
  20. //2.4转入账户加钱
  21. target.setMoney(target.getMoney()+money);
  22. //2.5更新转出账户
  23. accountDao.updateAccount(source);
  24. int i=1/0;
  25. //2.6更新转入账户
  26. accountDao.updateAccount(target);

applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context.xsd">
  9. <!-- 配置账户的业务层-->
  10. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl">
  11. <property name="accountDao" ref="accountDao"></property>
  12. </bean>
  13. <!-- 配置账户的持久层-->
  14. <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl">
  15. <property name="dataSource" ref="dataSource"></property>
  16. </bean>
  17. <!-- 配置数据源-->
  18. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  19. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  20. <property name="url" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  21. <property name="username" value="root"></property>
  22. <property name="password" value="root"></property>
  23. </bean>
  24. </beans>

test

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @ContextConfiguration(locations = "classpath:applicationContext.xml")
  3. public class AccountServiceTest
  4. @Autowired
  5. private AccountService as;
  6. @Test
  7. public void testTransfer()
  8. as.transfer("aaa", "bbb", 100f);

编程式事务控制

Jdbc的操作,需要配置Jdbc的事务管理器

配置applicationContext.xml

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

配置事务管理模板

配置applicationContext.xml

  1. <!-- 二:配置事务管理的模板 -->
  2. <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
  3. <property name="transactionManager" ref="transactionManager"/>
  4. </bean>

在业务层注入事务管理模板

配置applicationContext-tx1.xml

  1. <!-- 配置账户的业务层-->
  2. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl">
  3. <property name="accountDao" ref="accountDao"></property>
  4. <property name="transactionTemplate" ref="transactionTemplate"/>
  5. </bean>

AccountServiceImpl.java

  1. public class AccountServiceImpl implements AccountService
  2. // 注入事务管理的模板
  3. private TransactionTemplate transactionTemplate;
  4. public void setTransactionTemplate(TransactionTemplate transactionTemplate)
  5. this.transactionTemplate = transactionTemplate;
  6. private AccountDao accountDao;
  7. public void setAccountDao(AccountDao accountDao)
  8. this.accountDao = accountDao;
  9. public Account findAccountById(Integer accountId)
  10. return accountDao.findAccountById(accountId);
  11. public void transfer(final String sourceName, final String targetName, final Float money)
  12. System.out.println("transfer....");
  13. transactionTemplate.execute(new TransactionCallbackWithoutResult()
  14. @Override
  15. protected void doInTransactionWithoutResult(TransactionStatus transactionStatus)
  16. System.out.println(transactionStatus.isNewTransaction() + " "+transactionStatus.isCompleted());
  17. //2.1根据名称查询转出账户
  18. Account source = accountDao.findAccountByName(sourceName);
  19. //2.2根据名称查询转入账户
  20. Account target = accountDao.findAccountByName(targetName);
  21. //2.3转出账户减钱
  22. source.setMoney(source.getMoney()-money);
  23. //2.4转入账户加钱
  24. target.setMoney(target.getMoney()+money);
  25. //2.5更新转出账户
  26. accountDao.updateAccount(source);
  27. // int i=1/0;
  28. //2.6更新转入账户
  29. accountDao.updateAccount(target);
  30. );

Spring的声明式事务处理(**)

配置applicationContext.xml

同时去掉:TransactionTemplate的操作

技术图片

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans.xsd
  9. http://www.springframework.org/schema/context
  10. http://www.springframework.org/schema/context/spring-context.xsd
  11. http://www.springframework.org/schema/aop
  12. http://www.springframework.org/schema/aop/spring-aop.xsd
  13. http://www.springframework.org/schema/tx
  14. http://www.springframework.org/schema/tx/spring-tx.xsd">
  15. <!-- 配置账户的业务层-->
  16. <bean id="accountService" class="com.it.service.impl.AccountServiceImpl">
  17. <property name="accountDao" ref="accountDao"></property>
  18. </bean>
  19. <!-- 配置账户的持久层-->
  20. <bean id="accountDao" class="com.it.dao.impl.AccountDaoImpl">
  21. <property name="dataSource" ref="dataSource"></property>
  22. </bean>
  23. <!-- 配置数据源-->
  24. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  25. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  26. <property name="url" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  27. <property name="username" value="root"></property>
  28. <property name="password" value="root"></property>
  29. </bean>
  30. <!-- spring中基于XML的声明式事务控制配置步骤
  31. 1、配置事务管理器
  32. 2、配置事务的通知
  33. 此时我们需要导入事务的约束 tx名称空间和约束,同时也需要aop的
  34. 使用tx:advice标签配置事务通知
  35. 属性:
  36. id:给事务通知起一个唯一标识
  37. transaction-manager:给事务通知提供一个事务管理器引用
  38. 3、配置AOP中的通用切入点表达式
  39. 4、建立事务通知和切入点表达式的对应关系
  40. 5、配置事务的属性
  41. 是在事务的通知tx:advice标签的内部
  42. -->
  43. <!-- 一:配置事务管理器 -->
  44. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  45. <property name="dataSource" ref="dataSource"></property>
  46. </bean>
  47. <!-- 二:配置事务的通知-->
  48. <tx:advice id="txAdvice" transaction-manager="transactionManager">
  49. <!-- 配置事务的属性
  50. isolation:用于指定事务的隔离级别。默认值是DEFAULT,表示使用数据库的默认隔离级别。
  51. propagation:用于指定事务的传播行为。默认值是REQUIRED,表示一定会有事务,增删改的选择。查询方法可以选择SUPPORTS。
  52. read-only:用于指定事务是否只读。只有查询方法才能设置为true。默认值是false,表示读写。
  53. timeout:用于指定事务的超时时间,默认值是-1,表示永不超时。如果指定了数值,以秒为单位。
  54. rollback-for:用于指定一个异常,当产生该异常时,事务回滚,产生其他异常时,事务不回滚。没有默认值。表示任何异常都回滚。
  55. no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时事务回滚。没有默认值。表示任何异常都回滚。
  56. 测试:no-rollback-for="java.lang.ArithmeticException",遇到算数异常不回滚
  57. -->
  58. <tx:attributes>
  59. <tx:method name="*" propagation="REQUIRED" read-only="false"/>
  60. <tx:method name="find*" propagation="SUPPORTS" read-only="true"></tx:method>
  61. </tx:attributes>
  62. </tx:advice>
  63. <!-- 三:配置aop-->
  64. <aop:config>
  65. <!-- 配置切入点表达式-->
  66. <aop:pointcut id="pc" expression="execution(* com.it.service..*.*(..))"></aop:pointcut>
  67. <!--建立切入点表达式和事务通知的对应关系 -->
  68. <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"></aop:advisor>
  69. </aop:config>
  70. </beans>

注解

配置AccountDaoImpl.java

  1. @Repository
  2. public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao
  3. @Autowired
  4. public void setDi(DataSource dataSource)
  5. super.setDataSource(dataSource);

配置AccountServiceImpl.java

  1. @Service
  2. @Transactional(readOnly = true)
  3. public class AccountServiceImpl implements AccountService
  4. @Autowired
  5. private AccountDao accountDao;
  6. public Account findAccountById(Integer accountId)
  7. return accountDao.findAccountById(accountId);
  8. @Transactional(readOnly = false,propagation = Propagation.REQUIRED)
  9. public void transfer( String sourceName, String targetName, Float money)
  10. System.out.println("transfer....");
  11. //2.1根据名称查询转出账户
  12. Account source = accountDao.findAccountByName(sourceName);
  13. //2.2根据名称查询转入账户
  14. Account target = accountDao.findAccountByName(targetName);
  15. //2.3转出账户减钱
  16. source.setMoney(source.getMoney() - money);
  17. //2.4转入账户加钱
  18. target.setMoney(target.getMoney() + money);
  19. //2.5更新转出账户
  20. accountDao.updateAccount(source);
  21. int i=1/0;
  22. //2.6更新转入账户
  23. accountDao.updateAccount(target);

注意:方法级别的事务会覆盖类级别的事务

配置applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  7. xsi:schemaLocation="http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans.xsd
  9. http://www.springframework.org/schema/context
  10. http://www.springframework.org/schema/context/spring-context.xsd
  11. http://www.springframework.org/schema/aop
  12. http://www.springframework.org/schema/aop/spring-aop.xsd
  13. http://www.springframework.org/schema/tx
  14. http://www.springframework.org/schema/tx/spring-tx.xsd">
  15. <context:component-scan base-package="com.it"></context:component-scan>
  16. <!--配置JdbcTemplate-->
  17. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  18. <property name="dataSource" ref="dataSource"></property>
  19. </bean>
  20. <!-- 配置数据源-->
  21. <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  22. <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  23. <property name="url" value="jdbc:mysql://localhost:3306/itcastspring"></property>
  24. <property name="username" value="root"></property>
  25. <property name="password" value="root"></property>
  26. </bean>
  27. <!-- spring中基于XML的声明式事务控制配置步骤
  28. 1、配置事务管理器
  29. 2、配置事务的通知,通过注解的方式
  30. -->
  31. <!-- 配置事务管理器 -->
  32. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  33. <property name="dataSource" ref="dataSource"></property>
  34. </bean>
  35. <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
  36. </beans>

Spring整体的总结:

总结:

1:IOC DI(xml和注解)

2:AOP(5种通知)(xml和注解)

3:声明式事务处理(xml和注解)

  • * DBUtils(第三方提供的)
  • * JDBCTemplate(是spring提供的)

4:spring3的新特性(纯注解开发)

  • @Configuration
  • @ConnectionScan
  • @Import
  • @Bean

自己创建的对象:使用注解

第三方创建的对象(数据源…):使用配置文件

以上是关于Spring_four的主要内容,如果未能解决你的问题,请参考以下文章