Spring AOP
Spring JDBC
Spring 使用 AOP对事务进行实现
Spring 声明式事务实现:
- XML方式
XML文件中配置数据库连接池、事务管理器、事务增强、aop:事务管理器中 ref引用 dataSource数据源;事务增强中 transaction-manager用到事务管理器,并且设置哪些方法、是否只读;aop中:配置切入点表达式并通过pointcut-ref引入、advice-ref引入事务通知 - 注解方式
① 设置注解方式实现事务:
<tx:annotation-driven transaction-manager=“txManager”/>
② Service层的类或者方法上使用@Transactional注解:
若放在方法上,则对于此方法添加事务
若放在类上,则对于此类中全部方法都有事务
程序中事务的控制:用户——》action——》service——》dao
(一个程序运行成功,service要是成功,dao写入数据库成功)
事务控制放在service层
事务管理:
- 编程式事务 conn.setAutoCommit(false)
- Spring对于事务管理,声明式事务
配置事务,AOP
0 .eg: 没有事务操作时
模拟: 调用Dao,两次操作,一次成功,一次失败,没有事务时没有回滚,即使失败的操作也会对数据库产生影响
开发步骤:
1.后台:数据库、service、dao、entity
2.Dao使用 JdbcTemplate
3.对象的创建使用 IOC容器
0.1 UserDao.java
public class UserDao{
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate){
this.jdbcTemplate=jdbcTemplate;
}
public void save(User user) throws Exception{ //添加方法
String sql="insert into user(username,age) values(?,?)";
jdbcTemplate.update(sql,new Object[]{user.getUsername(),user.getAge()});
}
}
0.2 UserService.java
public class UserService{
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
public void save(User user) throws Exception{
userDao.save(user);
//出异常
int i=1/0;
userDao.save(user);
}
}
0.3 bean.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" 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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 创建连接池对象 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
<property name="user" value="root"></property>
<property name="password" value="12345"></property>
</bean>
<!-- JdbcTemplate工具类 -->
<!-- 创建jdbcTemplate对象(将dataSource注入) -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- dao -->
<!-- 创建UserDao对象(将jdbcTemplate注入) -->
<bean id="userDao" class="com.asd.spring.UserDao">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- service-->
<bean id="userService" class="com.asd.spring.UserService">
<property name="userDao" ref="userDao"></property>
</bean>
</beans>
Test.java
public class Test{
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml");
@Test
public void test() throws Exception{
UserService userService=(UserService)applicationContext.getBean("userService");
User user=new User();
user.setUsername("测试");
user.setAge(9);
userService.save(user);
}
}
一、 XML方式配置事务
( bean.xml中:配置事务管理器、事务增强、aop:事务管理器中 ref引用 dataSource数据源;事务增强中 transaction-manager用到事务管理器,并且设置哪些方法、是否只读;aop中:配置切入点表达式并通过pointcut-ref引入、advice-ref引入事务通知。)
1.1 UserDao.java
public class UserDao{
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate){
this.jdbcTemplate=jdbcTemplate;
}
public void save(User user) throws Exception{ //添加方法
String sql="insert into user(username,age) values(?,?)";
jdbcTemplate.update(sql,new Object[]{user.getUsername(),user.getAge()});
}
}
1.2 UserService.java
public class UserService{
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
public void save(User user) throws Exception{
userDao.save(user);
//出异常
int i=1/0;
userDao.save(user);
}
}
1.3 bean.xml
(配置事务管理器、事务增强、aop:事务管理器中 ref引用 dataSource数据库连接池;事务增强中 transaction-manager用到事务管理器,并且设置哪些方法、是否只读;aop中:配置切入点表达式并通过pointcut-ref引入、advice-ref引入事务通知。)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" 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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 创建连接池对象 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
<property name="user" value="root"></property>
<property name="password" value="12345"></property>
</bean>
<!-- JdbcTemplate工具类 -->
<!-- 创建jdbcTemplate对象(将dataSource注入) -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- dao -->
<!-- 创建UserDao对象(将jdbcTemplate注入) -->
<bean id="userDao" class="com.asd.spring.UserDao">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- service-->
<bean id="userService" class="com.asd.spring.UserService">
<property name="userDao" ref="userDao"></property>
</bean>
<!-- Spring对于事务的管理 -->
<!-- 1.配置事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 2.配置事务管理增强(即如何管理) -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get" read-only="true"/>
<tx:method name="*" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- 3.配置AOP,拦截什么方法(切入点表达式)+增强 -->
<aop:config>
<aop:pointcut id="pt" expression="execution(* com.asd.spring.UserService.save(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config>
</beans>
Test.java
public class Test{
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml");
@Test
public void test() throws Exception{
UserService userService=(UserService)applicationContext.getBean("userService");
User user=new User();
user.setUsername("测试2");
user.setAge(9);
userService.save(user);
}
}
二、 注解方式实现声明式事务
(bean.xml中:开启注解扫描、创建数据库连接池 dataSource、配置事务管理器 txManager、配置事务注解:配置事务管理器时 ref引用 dataSource; 配置事务注解时 transaction-manager使用 txManager。UserService.java中:使用@Service、@Resource注解将 userDao注入进来,此时不需要用 setUserDao方法注入了;在方法或者类上使用@Transactional来添加事务。UserDao.java中:使用@Repository、@Resource注解将 jdbcTemplate注入进来,此时不需要用 setJdbcTemplate进行注入了。)
2.1 UserDao.java
(使用@Repository、@Resource注解将 jdbcTemplate注入进来,此时不需要用 setJdbcTemplate进行注入了。)
@Repository
public class UserDao{
@Resource
private JdbcTemplate jdbcTemplate;
public void save(User user) throws Exception{ //添加方法
String sql="insert into user(username,age) values(?,?)";
jdbcTemplate.update(sql,new Object[]{user.getUsername(),user.getAge()});
}
}
2.2 UserService.java
(使用@Service、@Resource注解将 userDao注入进来,此时不需要用 setUserDao方法注入了;在方法或者类上使用@Transactional来添加事务。)
@Service
@Transactional
public class UserService{
@Resource
private UserDao userDao;
// @Transactional
public void save(User user) throws Exception{
userDao.save(user);
//出异常
int i=1/0;
userDao.save(user);
}
}
2.3 bean.xml
(配置事务管理器、事务增强、aop:事务管理器中 ref引用 dataSource数据源;事务增强中 transaction-manager用到事务管理器,并且设置哪些方法、是否只读;aop中:配置切入点表达式并通过pointcut-ref引入、advice-ref引入事务通知。)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" 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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 开启注解扫描 -->
<context:component-scan base-package="com.asd"></context:component-scan>
<!-- 创建连接池对象 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property>
<property name="user" value="root"></property>
<property name="password" value="12345"></property>
</bean>
<!-- JdbcTemplate工具类 -->
<!-- 创建jdbcTemplate对象(将dataSource注入) -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- Spring对于事务的管理 -->
<!-- 1.配置事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 2.注解方式实现事务,指定注解方式实现事务 -->
<tx:annotation-driven transaction-manager="txManager"/>
</beans>
Test.java
public class Test{
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("bean.xml");
@Test
public void test() throws Exception{
UserService userService=(UserService)applicationContext.getBean("userService");
User user=new User();
user.setUsername("测试3");
user.setAge(9);
userService.save(user);
}
}