初识Spring+AspectJ+spring之事务管理

一、初识Spring

 

1.Spring是分层的JavaSE/EE full-stack(一站式) 轻量级开源框架

EE的三层结构:web层、业务层、数据访问层(持久层,集成层)

2.Spring的核心:IOC(控制反转)、AOP(面向切面编程)

3.学习Spring需要的入门准备(①下载Spring开发包 ②创建web工程引入相应的jar包 ③创建Spring配置文件④在配置中配置类⑤创建测试类)

Spring的入门级案例:

1.创建一个接口

package org.llj.springdemo;
public interface  HelloService {
	public void sayHello();
}

2.创建该接口的实现类

public class HelloServiceImpl implements HelloService {
	private String info;
	public void setInfo(String info) {
		this.info = info;
	}
	@Override
	public void sayHello() {
		System.out.println("hello spring"+info);
	}
}

3.配置配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<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"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	<!-- 通过bean 标签设置类的信息,为类起一个标识 -->
	<bean id="userService" class="org.llj.springdemo.HelloServiceImpl">
	<!-- 通过property标签注入属性 -->
	<property name="info" value="哈哈哈哈哈"></property>
	</bean>
</beans>

4.编写测试类:

public class ServiceTest {
	
	@Test
	//传统方式的测试
	public void demo1(){
		HelloService helloService=new HelloServiceImpl();
		helloService.sayHello();
	}
	@Test
	//采用spring框架测试
	public void demo2(){
		org.springframework.context.ApplicationContext applicationContext
		=new ClassPathXmlApplicationContext("applicationContext.xml");
		HelloService helloService=(HelloService) applicationContext.getBean("userService");
		helloService.sayHello();
	}
	@Test
	public void demo3(){
		org.springframework.context.ApplicationContext applicationContext
		=new FileSystemXmlApplicationContext("applicationContext.xml");
		HelloService helloService=(HelloService) applicationContext.getBean("userService");
		helloService.sayHello();
	}
}

4.DI:依赖注入:在Spring创建对象的过程中,把对象依赖的属性注入到类中.

5.IOC装配bean的方式(三种)

①构造方法实例化:

创建要实例化的类

package org.llj.springdemo2;
/**
 * 使用无参数的构造方法实例化
 * @author lenovo
 *
 */
public class bean1 {
}

加载配置文件

<!--默认情况使用的是无参数的构造方法-->
	<!-- <bean id="bean1" class="org.llj.springdemo2.bean1"></bean> -->

编写测试类

@Test
	public void demo1(){
		//1.加载类
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext
				("ApplicationContext.xml");
		bean1 bean1=(org.llj.springdemo2.bean1) applicationContext.getBean("bean1");
		System.out.println(bean1);
	}

②静态工厂实例化

package org.llj.springdemo2;
/**
 * 使用静态工厂实例化
 * @author lenovo
 *
 */
public class bean2 {
	
}
package org.llj.springdemo2;

public class bean2Factory {
	public static bean2 getBean2(){
		System.out.println("静态工厂实例化");
		return new bean2();
	}
}

加载配置文件:

 <!--第二种,使用静态工厂实例化  -->
	 <bean id="bean2" class="org.llj.springdemo2.bean2Factory" 
	     factory-method="getBean2"></bean>

测试:

@Test
	public void demo2(){
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext
				("ApplicationContext.xml");
		bean2 bean2=(org.llj.springdemo2.bean2) applicationContext.getBean("bean2");
		System.out.println(bean2);
	}

③实例工厂实例化

package org.llj.springdemo2;
/**
 * 使用实例工厂的方法实例化
 * @author lenovo
 *
 */
public class bean3 {

}
package org.llj.springdemo2;
/**
 * 使用实例工厂实例化
 * @author lenovo
 *
 */
public class bean3Factory {
	public  bean3 getBean3(){
		System.out.println("实例工厂实例化");
		return new bean3();
	}
}

配置文件:

<!-- 第三种,使用实例工厂实例化 -->
	 <bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>
	 <bean id="bean3Factory" class="org.llj.springdemo2.bean3Factory" ></bean>

测试:

@Test
	public void demo3(){
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext
				("ApplicationContext.xml");
		bean3 bean3=(org.llj.springdemo2.bean3) applicationContext.getBean("bean3");
		System.out.println(bean3);
	}

6.bean中属性注入:

①构造器的方法注入:

<bean id="car" class="org.llj.springdemo5.Car">
	 <constructor-arg name="name" value="宝马"></constructor-arg>
	 <constructor-arg name="price" value="1000000"></constructor-arg>
	 
	  <!-- 可以用位置索引的方式 -->
	  <constructor-arg index="0" value="奔驰"></constructor-arg>
	  <constructor-arg index="1" value="500000"></constructor-arg>
	 </bean>

②setter方法注入:

<bean id="car2" class="org.llj.springdemo5.Car2">
	 property 标签中name就是属性名称,value就是属性值 ref表示引用的其他对象
	 	<property name="name" value="兰博基尼"></property>
	 	<property name="price" value="50000000"></property>
	 </bean>
	 
	 <bean id="car2" class="org.llj.springdemo5.Car2" p:name="宝马" p:price="400000"></bean>

③名称空间p注入:

<!-- p的名称空间写法 -->
	  <bean id="person" class="org.llj.springdemo5.Person" p:name="娟儿" p:car-ref="car2">
 
 		 	
	 </bean>

④spel写法

 <bean id="person" class="org.llj.springdemo5.Person">
	 value的#号后的大括号如果有单引号,说明是常量;如果没有单引号,说明是引用类型
	 	<property name="name" value="#{'小超'}"></property>
	 	<property name="car" value="#{car2}"></property>
	 </bean>

⑤集合注入

<!-- demo6 List集合的属性注入 -->
	 <bean id="collectionBean" class="org.llj.springdemo6.CollectionBean">
	 	<property name="list">
	 		<list>
	 			<value>梅</value>
	 			<value>玲</value>
	 		</list>
	 	</property>
	 	<!-- set集合注入 -->
	 	<property name="set">
	 		<set>
	 			<value>花花</value>
	 			<value>红军</value>
	 		</set>
	 	</property>
	 	<!-- map集合注入 -->
	 	<property name="map">
	 		<map>
	 			<entry key="小牛" value="456"></entry>
	 			<entry key="小猫" value="789"></entry>
	 		</map>
	 	</property>

⑥propeties注入:

<property name="properties">
	 		<props>
	 			<prop key="username" >root</prop>
	 			<prop key="password">123</prop>
	 		</props>
	 	</property>
	 </bean>

7.IOC注解方式装配bean

 

Spring的框架中提供了与@Component注解等效的三个注解:

@Repository 用于对DAO实现类进行标注

@Service 用于对Service实现类进行标注

@Controller 用于对Controller实现类进行标注

普通属性;

@Value(value="itcast")

private String info;

 对象属性:

@Autowired:自动装配默认使用类型注入.

@Autowired

  @Qualifier("userDao")       --- 按名称进行注入.

 @Autowired

    @Qualifier("userDao")      

private UserDao userDao;

等价于

@Resource(name="userDao")

       private UserDao userDao;

8.spring整合JUNIT测试

 

1.程序中有Junit环境.

2.导入一个jar包.spring与junit整合jar包.

* spring-test-3.2.0.RELEASE.jar

3.测试代码:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext2.xml")
public class springTest {
	@Autowired
	private UserService userservice;
	@Test
	public void demo1(){
		userservice.sayhello();
	}
}

二、spring中的AOP

AOP的底层实现:

1.JDK动态代理

public class JDKProxy implements InvocationHandler{
	private UserDao userDao;

	public JDKProxy(UserDao userDao) {
		super();
		this.userDao = userDao;
	}

	public UserDao createProxy(){
		//第一个参数为类装载器,第二个参数是真实类所拥有的接口,第三个数组则是当前类
		UserDao proxy=(UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
				userDao.getClass().getInterfaces(), this);
		return proxy;
	}

	//调用目标对象的任意一个方法,都相当于调用了Invoke方法
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// TODO Auto-generated method stub
		if("add".equals(method.getName())){
			//记录日志
			System.out.println("日志记录======================");
			//执行add方法
			Object result=method.invoke(userDao, args);
			return result;
		}else {
			return method.invoke(userDao, args);
		}
	
	}
}

2.CGLIB动态代理

public class CGLibProxy implements MethodInterceptor {
	private ProductDao productDao;

	public CGLibProxy(ProductDao productDao) {
		super();
		this.productDao = productDao;
	}
	
	public ProductDao createProxy(){
		//使用CGLib生成代理
		//1.创建核心类:Enhancer
		Enhancer enhancer=new Enhancer();
		//2.为其设置父类
		enhancer.setSuperclass(productDao.getClass());
		//3.设置回调
		enhancer.setCallback(this);
		//4.创建代理
		return (ProductDao) enhancer.create();
	}

	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		if("add".equals(method.getName())){
			System.out.println("日志记录=================");
			Object object=methodProxy.invokeSuper(proxy, args);
			return object;
		}
		return methodProxy.invokeSuper(proxy, args);
	}
}

Spring框架,如果类实现了接口,就使用JDK的动态代理生成代理对象,如果这个类没有实现任何接口,使用CGLIB生成代理对象.

Spring中AspectJ的支持

 

AspectJ增强:

@Before 前置通知,相当于BeforeAdvice

@AfterReturning 后置通知,相当于AfterReturningAdvice

@Around 环绕通知,相当于MethodInterceptor

@AfterThrowing抛出通知,相当于ThrowAdvice

@After 最终final通知,不管是否异常,该通知都会执行

@DeclareParents 引介通知,相当于IntroductionInterceptor (不要求掌握)

1.基于注解的

<!--自动生成代理  -->
	<aop:aspectj-autoproxy />
	<bean id="userDao" class="org.llj.spring.demo1.UserDao"></bean>
	<bean id="myAspect" class="org.llj.spring.demo1.MyAspect"></bean>
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

/**
 * 切面类,就是切点与增强的结合
 * @author lenovo
 *
 */
@Aspect
public class MyAspect {
	@Before("execution(* org.llj.spring.demo1.UserDao.add(..))")
	public void before(JoinPoint joinPoint){
		System.out.println("这是一个前置增强……"+joinPoint);
	}
	@AfterReturning(value="execution(* org.llj.spring.demo1.UserDao.delete(..))",returning="returnVal")
	public void after(Object returnVal){
		System.out.println("这是一个后置增强……"+returnVal);
	}
	@Around("MyAspect.mypointcut()")
	public Object around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
		System.out.println("环绕前增强");
		Object obj=proceedingJoinPoint.proceed();
		System.out.println("环绕后增强");
		return obj;
	}
	@AfterThrowing(value="MyAspect.mypointcut()",throwing="e")
	public void throwing(Throwable e){
		System.out.println("不好了。出异常了"+e.getMessage());
	}
	@After("MyAspect.mypointcut()")
	public void after(){
		System.out.println("最终通知……");
	}
	@Pointcut("execution(* org.llj.spring.demo1.UserDao.find(..))")
	private void mypointcut(){
		
	}
}

二、基于XML的

package org.llj.spring.demo2;

import org.aspectj.lang.ProceedingJoinPoint;

public class MyAspectXML {
	public void before(){
		System.out.println("前置通知……");
	}
	public void aferReturning(Object returnVal){
		System.out.println("后置通知……"+returnVal);
	}
	//环绕通知
	public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
		System.out.println("环绕前通知……");
		Object result=proceedingJoinPoint.proceed();
		System.out.println("环绕后通知……");
		return result;
	}
	//异常通知
	public void afterThrowing(Throwable e){
		System.out.println("出异常了……"+e.getMessage());
	}
	//最终通知
	public void after(){
		System.out.println("这是最终通知……");
	}
}
<!-- 定义被增强的类 -->
	<bean id="productDao" class="org.llj.spring.demo2.ProductDao"></bean>
	
	<!--定义切面  -->
	<bean id="myAspectxml" class="org.llj.spring.demo2.MyAspectXML"></bean>
	
	<!--定义aop配置  -->
	<aop:config>
		<!--定义切点  -->
		<aop:pointcut expression="execution(* org.llj.spring.demo2.ProductDao.add(..))" id="mypointcut"/>
		<aop:aspect ref="myAspectxml">
			<!--前置通知  -->
			<!-- <aop:before method="before" pointcut-ref="mypointcut"/> -->
			<!-- 后置通知 -->
			<!-- <aop:after-returning method="aferReturning" pointcut-ref="mypointcut"
			returning="returnVal"
			/> -->
			<!-- 环绕通知 -->
			<!-- <aop:around method="around" pointcut-ref="mypointcut"/> -->
			<!-- 异常通知 -->
			<!-- <aop:after-throwing method="afterThrowing" pointcut-ref="mypointcut" throwing="e"/> -->
			<!--最终通知  -->
			<aop:after method="after" pointcut-ref="mypointcut"/>
		</aop:aspect>
	</aop:config>

Spring的jdbcTemplate

1.jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///spring_day02
jdbc.user=root
jdbc.password=123

2.spring 提供了三种连接池(以下)

①.配置spring默认的连接池

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
		<property name="url" value="jdbc:mysql:///spring_day02"></property>
		<property name="username" value="root"></property>
		<property name="password" value="123"></property>
	</bean>

②.配置dbcp连接池

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
		<property name="url" value="jdbc:mysql:///spring_day02"></property>
		<property name="username" value="root"></property>
		<property name="password" value="123"></property>
	</bean>

③.-配置c3p0连接池 

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driver}"></property>
		<property name="jdbcUrl" value="${jdbc.url}"></property>
		<property name="user" value="${jdbc.user}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean>

3.定义jdbcTemplate摸板类

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	<bean id="userDao" class="org.llj.spring.demo2.UserDao">
		<property name="jdbcTemplate" ref="jdbcTemplate"></property>
	</bean>
<context:property-placeholder location="classpath:jdbc.properties"/>

JdbcTemplate的CRUD的操作

import java.awt.List;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
/**
 * jdbcDaoSupport这个类中已经定义了模板,并且有一个set方法,所以这边继承JdbcDaoSupport之后就
 * 不需要在定义模板
 * @author lenovo
 *
 */
public class UserDao extends JdbcDaoSupport {
	

	public void add(User user){
		String sql="insert into user values(null,? )";
		this.getJdbcTemplate().update(sql,user.getName());
	}
	public void update(User user){
		String sql="update user set name = ? where id = ?";
		this.getJdbcTemplate().update(sql, user.getName(),user.getId());
	}
	public void delete(User user){
		String sql="delete from user where id = ?";
		this.getJdbcTemplate().update(sql, user.getId());
	}
	public String findNameById(int id){
		String sql="select name from user where id = ?";
		return this.getJdbcTemplate().queryForObject(sql, String.class, id);
	}
	public User findById(int id){
		String sql="select * from user where id = ?";
		User user=(User)this.getJdbcTemplate().queryForObject(sql, new UserRowMapper(),id);
		return user;
	}
	public java.util.List<User> findAll(){
		String sql="select * from user";
		return this.getJdbcTemplate().query(sql, new UserRowMapper());
	}
	class UserRowMapper implements RowMapper<User>{
		/**
		 * rs:结果集
		 * rowNum:行号
		 */
		@Override
		public User mapRow(ResultSet rs, int rowNum) throws SQLException {
			User user=new User();
			user.setId(rs.getInt("id"));
			user.setName(rs.getString("name"));
			return user;
		}
		
	}

}

测试方法:

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class springTest {
	@Autowired
	@Qualifier("userDao")
	private UserDao userDao;
	
	@Test
	public void demo1(){
		User user=new User();
		user.setName("娟儿");
		userDao.add(user);
	}
	@Test
	public void demo2(){
		User user=new User();
		user.setId(1);
		user.setName("珑珠");
		userDao.update(user);
	}
	@Test
	public void demo3(){
		User user=new User();
		user.setId(1);
		userDao.delete(user);
	}
	@Test
	public void demo4(){
		String name=userDao.findNameById(2);
		System.out.println(name);
	}
	@Test
	public void  demo5(){
		User user=userDao.findById(2);
		System.out.println(user);
	}
	@Test
	public void demo6(){
		List<User> list=userDao.findAll();
		for (User user : list) {
			System.out.println(user);
		}
	}

}

 

三、Spring之事务管理

 

Spring的事务管理主要分成两类:

1.编程式事务管理(手动编写代码完成事务的管理)

2.声明式事务管理 (不需要手动编写,配置 )

事务操作的环境搭建:

1.需要有相应的数据库。

2.创建一个动态web项目:导入相应的jar;引入配置文件

3.创建类:XXXService;XXXDao

4.在Spring中注册业务层类和持久层类:

<!--业务层类  -->
	<bean id="accountService" class="org.llj.spring.demo1.AccountServiceImpl">
		<!--在业务层注入Dao  -->
		<property name="accountDao" ref="accountDao"></property>
		<!--在业务层注入事务管理的模板  -->
		<property name="transactionTemplate" ref="transactionTemplate"></property>
	</bean>
	
	<!-- 持久层类 -->
	<bean id="accountDao" class="org.llj.spring.demo1.AccountDaoImpl">
		<!--注入连接池对象,通过连接池对象创建模板  -->
		<property name="dataSource" ref="dataSource"></property>
	</bean>

5.OK,编写测试类,测试环境是否搭建成功。

Spring的事务管理

不管哪种方式都需要事务管理器(TransactionManager)

<!-- 配置事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<!--需要注入连接池,通过连接池获得连接  -->
		<property name="dataSource" ref="dataSource"></property>
	</bean>

一.手动编写的方式完成事务管理

1.注册事务模板:(TransactionTemplate)

<!-- 事务管理的模板 -->
	<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
		<property name="transactionManager" ref="transactionManager"></property>
	</bean>

2.在业务层注入模板类:(模板管理事务)

<!--业务层类  -->
	<bean id="accountService" class="org.llj.spring.demo1.AccountServiceImpl">
		<!--在业务层注入Dao  -->
		<property name="accountDao" ref="accountDao"></property>
		<!--在业务层注入事务管理的模板  -->
		<property name="transactionTemplate" ref="transactionTemplate"></property>
	</bean><property name="transactionTemplate" ref="transactionTemplate"></property>
	</bean>

3.在业务层代码上使用模板:(以下是我的业务层代码)

package org.llj.spring.demo1;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

public class AccountServiceImpl implements AccountService {
	private AccountDao accountDao;
	private TransactionTemplate transactionTemplate;
	
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
		this.transactionTemplate = transactionTemplate;
	}
	@Override
	public void transfer(final String from, final String to, final Double money) {
		transactionTemplate.execute(new TransactionCallbackWithoutResult() {	
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus arg0) {
				// TODO Auto-generated method stub
				accountDao.out(from, money);
				int i=10/0;
				accountDao.in(to, money);
			}
		});
	}

}
transactionTemplate.execute(new TransactionCallbackWithoutResult() {	
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus arg0) {
				// TODO Auto-generated method stub
				accountDao.out(from, money);
				int i=10/0;
				accountDao.in(to, money);
			}
		});
	}

}

二.原始的声明式事务管理:

1.创建业务层代理对象(飘蓝的为属性设置,如果不写,则系统默认)

<!-- 配置生成代理对象 -->
	<bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
		<!-- 目标对象 -->
		<property name="target" ref="accountService"/>
		<!-- 注入事务管理器 -->
		<property name="transactionManager" ref="transactionManager"/>
		<!-- 事务的属性设置 -->
		<property name="transactionAttributes">
			<props>
				<prop key="transfer">PROPAGATION_REQUIRED</prop>
			</props>
		</property>
	</bean><prop key="transfer">PROPAGATION_REQUIRED</prop>
			</props>
		</property>
	</bean>

2.编写测试类(注意注入的是代理对象)

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class springTest2 {
	@Autowired
	@Qualifier("accountServiceProxy")
	private AccountService accountService;
	
	@Test
	public void demo1(){
		accountService.transfer("aaa", "bbb", 100d);
	}

}"accountServiceProxy")
	private AccountService accountService;
	
	@Test
	public void demo1(){
		accountService.transfer("aaa", "bbb", 100d);
	}

}

三.声明式事务管理(基于切面)

1.导入所需的jar包,引入配置文件(aop、tx的约束)

2.事务管理(定义增强)

<!--定义一个增强  -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
	<!--增强事务的属性配置  -->
	<tx:attributes>
	<!-- 
	isolation="DEFAULT":  事务的隔离级别
	propagation="REQUIRED" 事务的传播行为
	read-only="false"     事务是否只读,默认为否
	no-rollback-for=""    发生哪些异常不回滚
	no-rollback-for=""    发生哪些异常回滚
	这些不设置的话,他会有一个默认值
	 -->
		<tx:method name="transfer" />
	</tx:attributes>
	</tx:advice>

3.定义切点和通知

<!--aop 配置定义切面和切点的信息  -->
	<aop:config>
	<!--定义切点:哪些类的哪些方法用于增强  -->
		<aop:pointcut expression="execution(* org.llj.spring.demo3.AccountService+.*(..))" id="mypointcut"/>
	<!--定义切面:  -->
		<aop:advisor advice-ref="txAdvice" pointcut-ref="mypointcut"/>	
	</aop:config>

4.测试(不需要注入代理对象,注入service对象即可)

四.基于注解的事务管理

1.注解事务:

<!--开启标签的事务管理  -->
	<tx:annotation-driven transaction-manager="transactionManager"/>

2.在service 上使用注解

@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,readOnly=false)
public class AccountServiceImpl implements AccountService {
	private AccountDao accountDao;
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	@Override
	public void transfer(String from,  String to,  Double money) {
				accountDao.out(from, money);
				//int i=10/0;
				accountDao.in(to, money);	
	}
}
public class AccountServiceImpl implements AccountService {
	private AccountDao accountDao;
	public void setAccountDao(AccountDao accountDao) {
		this.accountDao = accountDao;
	}
	@Override
	public void transfer(String from,  String to,  Double money) {
				accountDao.out(from, money);
				//int i=10/0;
				accountDao.in(to, money);	
	}
}

以上为spring中的几种事务管理;其中手动编写的方式代码量大,代码具有入侵性

原始的声明式事务管理需要为每一个管理事务的类生成代理,需要为每个类都进行配置。

基于aspect的声明式事务管理是重点。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值