Spring

框架学习的步骤

1、知道框架能做什么,Mybatis==访问数据库
2、框架的语法,框架要完成一个功能,需要一定的步骤支持
3、框架的内部实现,框架内部怎么做,原理是什么?
4、通过学习,可以实现一个框架

Spring第一个核心功能——IoC

IoC(Inversion of Control) : 控制反转
是一个理论,概念,思想
描述的是:把对象的创建、赋值、管理工作都交给代码之外的容器实现
也就是对象的创建是由其他外部资源完成

控制:创建对象,对象的属性赋值,对象之间的关系管理
正转:由开发人员在代码中,使用new构造方法创建对象,开发人员主动管理对象
public static void main(String[] args){
	Student student = new Student();//正转:在代码中创建对象
}
反转:把创建对象的权限转移给代码之外的容器实现,容器来管理对象,创建对象以及给属性赋值

为什么要使用IoC

减少对代码的改动,完成不同的功能,实现解耦合。

java中创建对象有哪些方式

构造方法,new
反射
序列化
克隆
动态代理
IoC:使用容器创建对象

IoC的技术实现

DI(Dependenncy Injection)是IoC的技术实现
DI:依赖注入,只需要在程序中提供要使用的对象名称就可以
底层的实现原理是反射机制

Spring实现步骤

1、创建Maven项目
2、加入Maven依赖
			加入Spring的依赖
3、创建类(接口和实现类)
		和没有使用框架的时候一样,就是普通的类
4、创建spring需要使用的配置文件
	声明类的信息,这些类由spring创建和管理
5、测试spring创建的类

Spring Config

	这是spring的配置文件
	1、beans:是根标签,在spring中,把java对象成为bean
	2、spring-beans.xsd是约束文件,和mybatis中的dtd是一样的。

使用Spring来创建对象

//1、指定spring配置文件的名称
String config = "beans.xml";
//2、创建表示spring容器的对象,ApplicationContext
//ApplicationContext:表示了Spring容器
//ClassPathXmlApplicationContext:表示从类路径中加载spring的配置文件
ApplicationContext ac = new ClassPathXmlApplicationContext(config);

//从容器中获取某个对象,要调用对象的方法
//getBean("配置文件中bean的id值");
SomeService service = (SomeService)ac.getBean("SomeService");
service.doSome();

容器的常用方法

ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
//获取容器定义的对象的数量
int nums = ac.getBeanDefinitionCounts();
//容器中每个定义的对象的名称
String nums[] = ac.getBeanDefinitionNames();	

可以创建非自定义类

//创建一个Date类
<bean id="myDate" class="java.util.Date"/>

 Date time = (Date) ac.getBean("myDate");
        System.out.println("系统时间:" + time);

使用配置文件的方式来赋值

/*注入========赋值
简单类型:spring规定java的基本数据类型和String类型都是简单类型
di:给属性赋值
1、set注入(设值注入)。调用set方法进行赋值
*/
//(1)简单类型的set注入
  <bean id="Student01" class="com.qzj.package01.Student">
        <property name="name" value="张三" />//setName("李四")
        <property name="age" value="21"/> //setAge("21");
        //一个property只能给一个属性赋值
    </bean>
//(2)引用类型的set注入
	 <bean id="Student01" class="com.qzj.package01.Student">
        <property name="name" value="张三" />//setName("李四")
        <property name="age" value="21"/> //setAge("21");
        <property name="school" ref="School" //setSchool(new School);
    </bean>
    <bean id="School" class="xxx">
    	<property name=".." value=".."/>
    </bean>

junit

单元测试,一个工具类库,做测试方法使用的
单元:方法,一个类中有很多方法,一个方法称为单元

构造注入:spring

构造注入:spring调用类的有参构造方法,在创建对象的同时,在构造方法汇总给属性赋值。
构造注入使用<constructor-arg>标签
<constructor-arg>标签:一个<constructor-arg>表示一个参数
<constructor-arg>标签属性:
name:表示构造方法的形参名:
index:表示构造方法的参数的位置,参数从左往右位置是0,1,2
value:构造方法的形参名类型是简单类型
ref:构造方法的形参类型是应用类型,用ref

引用类型 属性自动注入

对于引用类型属性的注入,也可不在配置文件中显示的注入。可以通过为<bean/>标签
设置 autowire 属性值,为引用类型属性进行隐式自动注入(默认是不自动注入引用类型属
性)。根据自动注入判断标准的不同,可以分为两种:
byName:根据名称自动注入
byType: 根据类型自动注入

(1) byName  方式自动注入
当配置文件中被调用者 bean 的 id 值与代码中调用者 bean 类的属性名相同时,可使用
byName 方式,让容器自动 注入给调用者 bean。容器是通过调用者的属性名与配置文件的被调用者的 id 进行比较而实现自动注入的。

(2) byType  方式自动注入
*java类中引用类型的数据类型和spring容器中(配置文件)<bean>的class属性是同源关系的,
    *       这样的bean能够赋值引用类型
    * 同源就是同一类的意思
    * 1)java中引用类型的数据类型和bean的class值是一致的。
    * 2)java中引用类型的数据类型和bean的class值是父子关系的。
    * 3)java中引用类型的数据类型和bean的class值是接口和实现类关系的。

包含关系的多配置文件

total表示主配置文件,包含其他配置文件,一般不定义对象
    语法:<import resources="其他配置文件的路径"
    关键字:"classpath:" 表示类路径(class文件所在的目录),
    在spring的配置文件中要指定其他文件的位置,需要使用classpath-->
<import resource="classpath:package07/spring-student.xml"/>
<import resource="classpath:package07/spring-school.xml"/>

使用通配符

<import resource="classpath:package07/spring-*.xml"/>
1)在包含关系的配置文件中,可以使用通配符(*表示任意字符)
2)要放在同一级目录之下才可以使用通配符
3)主配置文件不能包含在内,不然会造成自己读取自己(死循环)

基于注解的di

通过注解完成对java对象的创建,属性赋值
=使用注解的步骤:
	 1)加入maven的依赖,spring-context,在你加入spring-context的同时,间接加入spring-aop
	 		使用注解会用到spring-aop
 	 2)在类中加入spring的注解(多个不同功能的注解)
 	 3)在spring的配置文件中,加入一个组件扫描器的标签,说明注解在项目中的位置

注解的实现步骤

1、加入依赖
2、创建类,在类上加入注解
3、创建spring的配置文件
声明组件扫描器的标签,指明注解位置
4、使用注解创建对象,创建容器ac

@Component

@Component:创建对象的,等同于<bean>的功能
属性:value就是对象的名称,也就是bean的id值
		value的值是唯一的,创建的对象在整个spring容器中就一个
位置:在类的上面
	@Component(value="myStudent")等同于
	<bean id="myStudent" class="com.qzj.pa01.Student" />
语法:
	@Component(value="myStudent")
	@Component("myStudent")
	@Component

组件扫描器

声明组件扫描器(component-scan)组件就是对象
工作方式:spring会去扫描遍历base-package包和子包的所有类,
        找到所有注解,按照功能去创建对象和属性赋值-->
<context:component-scan base-package="com.qzj.pa01"/>

和@Component功能一致,创建对象的注解还有:

1@Respotory(用在持久层上):放在dao的实现类上面,表示创建dao对象,dao对象是能访问数据库的
2@Service(用在业务层类上面):放在service的实现类上面,创建service对象,service对象是做业务处理,可以有事务等功能的
3@Controller(用在控制器上面):放在控制器(处理器)类的上面,创建控制类对象的,控制器对象,能够接受用户提交的参数,显示请求的处理结果
以上三个注解的用法和语法和@component是一样的,都能创建对象,但是这三个注解还有别的功能

@Value

简单类型的属性赋值
属性:value是String类型的,表示简单类型的属性值
位置:1、在属性定义上面,无需set方法,推荐使用
			2、在set方法的上面

@Autowired

引用类型的属性赋值,使用自动注入原理,支持byName,byType

@Autowired:默认使用的是byType自动注入
	属性:required,是一个boolean类型,默认true
				required=true(更合适):引用类型如果赋值失败,程序报错,终止执行
				required=false:如果失败,正常执行,引用类型为null
	位置:1)在属性定义的上面,无需set方法,推荐使用
				2)在set方法的上面
如果要使用byName方式,需要做的是
	1)在属性上面加入@Autowired
	2)在属性上面加入@Qualifier(value="beanID")
 	@Autowired(required=true)
    @Qualifier("mySchool")
    private School school;

@Resource

来自jdk的注解,spring框架提供了对这个注解的功能支持,可以使用它给引用类型赋值
使用的也是自动注入原理,支持byName和byType,	默认是byName
先使用byName自动注入,如果byName失败,再使用byType
如果要使用byName,需要
@Resource(name="mySchool")
private School school;
位置:1、在属性定义的上面,无需set方法,推荐使用
			2、在set方法上面

AOP

1、动态代理
	实现方式:JDK动态代理,使用jdk中的Proxy,Method,InvocationHandler创建代理对新挨个
		     JDK动态代理要求目标类必须实现接口
    cglib动态代理:是第三方的工具库,创建代理对象,原理是继承,通过继承目标类,创建子类
		          子类就是代理对象,要求目标类不能是final,方法也不能是final
2、动态代理的作用:
	1)在目标类源代码不改变的情况下,增加功能
	2)减少代码的重复
	3)专注业务逻辑代码
	4)解耦合,让你的业务功能和日志,事务非业务功能分离
3、AOP(Aspect Orient Programming)面向切面编程
	Aspect:   切面,给你的目标类增加的功能,就是切面,像上面的日志、事务都是切面	
		       切面的特点:一般都是非业务方法,独立使用的
	Orien:       面向,对着
	Programming: 编程
	OOP:         面向对象编程
4、怎样理解面向切面编程?
	1)需要在分析项目功能时,找出切面;
	2)合理的安排切面的执行时间(在目标方法前,还是在目标方法后)
	3)合理的安全切面执行的位置,在哪个类?哪个方法?增强功能

术语:

*Aspect:切面,表示增强的功能,就是一堆代码,完成某个功能。非业务功能,常见的切面功能
				有日志,事务,统计信息,参数检查,权限验证。
JoinPoint:连接点,连接业务方法和切面的位置,就某类中的一个业务方法
*Pointcut:切入点,指多个连接点方法的集合,多个方法
目标对象,给哪个类的方法增加功能,这个类就是目标对象
*  Advice:通知,通知表示切面功能执行的时间

切面三个关键要素

切面的功能代码====切面能干什么
切面的执行位置====使用Pointcut表示切面执行的位置
切面的执行时间====使用Advice表示时间,在目标方法之前,还是目标方法之后

aop的实现

aop是一个规范,是动态的一个规范化,一个标准
aop的技术实现框架:
1、spring:spring在内部实现了aop规范,能做aop的工作
spring主要在事务处理时使用aop,
我们项目开发中很少使用spring的aop实现,因为spring的aop比较笨重
2、aspectJ:一个开源的,专门做aop的框架,spring框架中集成了aspectJ框架,可以通过spring使用其功能
aspectJ框架实现aop有两种方式:
		1、使用xml的配置文件
		2、使用注解,我们在项目中做aop功能,一般都使用注解,aspectJ有5个注解。

学习aspectJ框架的使用

1、切面的执行时间,执行时间在规范中叫做Advice(通知、增强),
在aspectJ框架中使用注解表示,也可以使用xml配置文件中的标签
		1)@Before
		2)@AfterReturning
		3)@Around
		4)@AfterThrowing
		5)@After
2、切面执行的位置,使用的是切入点表达式。
		execution(访问权限 方法返回值 方法声明(参数) 异常类型)
		每个部分用空格分开,访问权限和异常类型可以省略
		*	表示多个字符 
		..	用在参数时表示多个参数,用在包名时表示当前包及其子包路径	
		+	用在类名后,表示当前类及子类,用在接口后,表示当前接口及实现类

举例:

//指定切入点为:任意公共方法:
	execution(public * *(..))
//任何一个以set开始的方法
	execution(* set*(..))
//定义在service包里的任意类的任意方法
	execution(* service.*.*(..))
//定义在service包或子包里的任意类的任意方法
	execution(* service..*.*(..))
//指定所有包下的service子包下所有类所有方法
	execution(* *..service.*.*(..))

前置通知

//@Aspect作用:表示当前类是切面类
//切面类:是用来给业务方法增加功能的类,这个类中有切面的功能代码
//位置:在类定义的上面
@Aspect
public class MyAspectJ{
	/*定义方法:方法是实现切面功能的。
		方法的定义要求:
		1.公共方法public
		2.方法没有返回值
		3.方法名称自定义
		4.方法可以有参数,也可以没有参数。
			如果有参数,参数不是自定义的,有几个参数类型可以使用
-----------------------------------------------------------------------------------------
	@Before:前置通知注解
	属性:value,是切入点表达式 ,表示切面的功能执行的位置。
	位道:在方法的上面
	特点:
	1.在目标方法之前先执行的
	2.不会政变目标方法的执行结果
	3.不会影响目标方法的执行。*/
    @Before(value="execution(* *..SomeServiceImpl.*(..))")
    public void isBefore(JoinPoint jp){	
------------------------------------------------------------------------------------
    	/*
    	指定通知方法中的参数: JoinPoint
		JoinPoint:业务方法,要加入切面功能的业务方法
		作用:可以在通知方法中获取方法执行时的信息,例如方法名称, 方法的参数列表。
		如果你的切面功能中需要用到方法的信息,就加入JoinPoint
		这个Joinpoint参数的值是由框架赋予,必须是 第一个位置的参数		*/
        jp.getSignature();//方法的全限定名称
        jp.getSignature().getName();//方法名
        Object args[] = jp.getArgs();//方法的参数列表
    }
}

后置通知

后置通知定义方法,方法是实现切面功能的。
方法的定义要求:
1.公共方法public
2.方法没有返回值
3.方法名称自定义
4.方法有参数的,推荐是object, 参数名自定义
/*
@AfterReturning
	属性::	1.value切入点表达式
			2. returning自定义的变量,表示目标方法的返回值的。
				自定义变量名必须和通知方法的形参名一样。
	位置:在方法定义的上面
	特点:	1.在目标方法之后执行的。
			2.能够获取到目标方法的返回值,可以根据这个返回值做不同的处理功能
			3.可以修改这个返回值
*/
@AfterReturning(value = "execution(* *..SomeServiceImpl.*(..))",
				returning = "res")
public void myAfterReturning(Object res){
	Student stu = (Student)res;
	stu.setName("李四");//如果返回值是一个引用类型,可以通过后置方法来修改返回值
}

环绕通知

环绕通知方法的定义格式
1.方法是公共的,public
2.必须有一个返回值,推荐使用object
3.方法名称自定义
4.方法有参效,固定的参数ProceedingJoinpoint
@Around:环绕通知
属性:value切入点表达式
位置:在方法的定义什么
特点:
1.它是功能最强的通知
2.在目标方法的前和后都能增强功能。
3.控制目标方法是否被调用执行
4.修改原来的目标方法的执行结果。 影响最后的调用结果
环绕通知,等同于jdk动态代理的,InvocationHandler接口
参数: ProceedingJoinPoint 就等同于Method
作用:执行目标方法的
返回值:就是目标方法的执行结果 ,可以被修改
    @Around(value = "execution(* *..SomeServiceImpl.doFirst(..))")
    public Object myAround(ProceedingJoinPoint pjp) throws Throwable {
        //实现环绕通知
       //方法之前执行,开始事务
        Object args[] =  pjp.getArgs();
        for (Object arg: args){
            if("zhangsan".equals(arg)){//控制业务方法的执行
                pjp.proceed();//执行方法
            }
        }
         //方法之前执行,提交事务
        return "abc";//改变方法的返回值
    }

异常通知

异常通知方法的定义格式
1.public
2.没有返回值
3.方法名称自定义
4.方法有个一个Exception,如果还有是JoinPoint,
/*
@AfterThrowing:异常通知
属性: 
 	 1.value 切入点表达式
	 2.throwinng 自定义的变量,表示目标方法抛出的异常对象。
 	 3.变量名必须和方法的参数名一样
特点:
	1.在目标方法抛出异常时执行的
	2.可以做异常的监控程序,监控目标方法执行时是不是有异常。
	3.如果有异常,可以发送邮件,短信进行通知
-------------------------------------------------------------------------*/
@AfterThrowing(value =execution(* *. . SomeServiceImpl . doSecond(..))",
throwing = "ex" )
public void myAfterThrowing(Exception ex) {
System.out .println("异常通知:方法发生异常时,执行: "+ex. getMessage());
//发送邮件,短信, 通知开发人员

最终通知

最终通知方法的定义格式
1.public
2.没有返回值
3.方法名称自定义
4.方法没有参数,如果有就是JoinPoint,
@After :最终通知
属性: value切入点表达式
位置:在方法的上面
特点:
	1.总是会执行
	2.在目标方法之后执行的
	3.一般用来做资源清除工作

PointCut

用途:定义和管理切入点, 如果项目中有多个重复的切入点表达式,可以使用PointCut进行代码复用。
属性:value切入点表达式
位置:在自定义的方法上面
特点:
当使用@Pointcut定义在一个方法的上面, 此时这个方法的名称就是切入点表达式的别名。
其它的通知中, value属性就可以使用这个方法名称,代替切入点表达式
@Around(value = "mypt())")
@Pointcut(value =execution(* * .. SomeserviceImpl. doThird(..))" )
public void mypt(){
	//无需代码
}

cglib代理

//目标类没有接口,使用cglib动态代理,spring框架会自动应用cglib
com.bipowernode.ba07.SomeServiceImpl$$EnhancerBySpringCGLIB$$575c8b90
*/
System.out.println("proxy:"+proxy.getClass().getName());
//通过代理的对象执行方法,实现目标方法执行时,增强了功能
proxy.doThird();
	//如果你期望目标类有接口,使用cglib代理
<aop:aspectj-autoproxy proxy -target-class= "true"/>

spring继承mybatis

步骤
1.新建maven项目
2.加入maven的依赖
	1 ) spring依赖
	2 ) mybatis依赖
	3 ) mysq1驱动
	4 ) spr ing的事务的依赖
	5 ) mybatis和spring集成的依赖: mybatis 官方体用的,用来在spring项目中创建mybatis
	的sqlSesissonF actory, dao对象的
3.创建实体类
4.创建dao接口和mapper文件
5.创建mybatis主配置文件
6.创建Service接口和实现类, 属性是dao。
7.创建spring的配置文件:声明mybati s的对象交给spring创建
	1)数据源
	2 ) sqlsess ionFactory
	3) Dao对象
	4 )声明自定义的service 
8.创建测试类,获取Service对象 ,通过service调用dao完成数据库的访问

spring的数据处理

1、什么是事务
		事务是指一组sql语句的集合,集合中有多条sql语句,我们希望这些sql语句都成功或者都失败,就是事务
2、什么时候会用到事务
		操作涉及到多个表,或者多个sql语句,insert,update,detele都成功
		比如银行转账,张三要给李四转一百块钱

select count from t_account where name='zhangsan'
select count from t_account where name='lisi'
update t_account set money-100 where name="zhangsan"
update t_account set money+100 where name="lisi"

在java中写代码控制事务,要写在service类的业务方法中
因为业务方法会调用多个dao方法,来执行多个sql语句,可以控制这几个方法执行一个事务	
jdbc访问数据库处理事务:

Connection conn;conn.commit();conn.rollback();

mybatis访问数据库处理事务

SqlSession.commit();SqlSession.rollback();
这样做的不足之处:
1、不同的数据库访问技术以及处理事务的对象方法都不一样
2、掌握多重数据库事务处理逻辑,什么时候提交回滚
3、处理事务的多种方法
总结:多种数据库的访问技术,有不同的事务处理的机制

spring创建事务处理对象-事务管理器

spring提供了处理事务的统一模型,用一个步骤,完成多种数据库访问技术的事务处理
叫做事务管理器,是一个接口与其众多实现类
PlatformTransactionManager  定义了commit、rollback
	mybatis访问=DataSourceTransactionManager
	hibernate访问=HibernateTransactionManager
需要在spring的配置文件中用bean标签声明
<bean id="xxx" class="..DataSourcesTransactionManager">

事务类型

一、事务的隔离级别
		DEFAULT:默认级别,Mysql是REPEATABLE_READ(可重复读)
						 Oracle是READ_UNCOMMITTED读已提交  
		1、read_uncommitted :读未提交,为解决任何并发问题
		2、read_committer : 读已提交,解决脏读,存在不可重复读和幻读
		3、repeatable_read : 可重复读,解决脏读、不可能重复读、存在幻读
		4、serializable : 串行化,不存在并发问题
二、事务的超时时间: 表示一个方法最长的执行时间,如果方法执行时超过了时间,事务就回滚。
 	 单位是秒, 整数值, 默认是 -1. 

三、事务的传播行为 :控制业务方法是不是有事务的, 是什么样的事务的。
	 7个传播行为,表示你的业务方法调用时,事务在方法之间是如果使用的。
		PROPAGATION_REQUIRED
		PROPAGATION_REQUIRES_NEW
		PROPAGATION_SUPPORTS
		以上三个需要掌握的

		PROPAGATION_MANDATORY
		PROPAGATION_NESTED
		PROPAGATION_NEVER
		PROPAGATION_NOT_SUPPORTED
四、事务提交事务,回滚事务的时机
 1)当你的业务方法,执行成功,没有异常抛出,当方法执行完毕,spring在方法执行后提交事务。事务管理器commit
 2)当你的业务方法抛出运行时异常或ERROR, spring执行回滚,调用事务管理器的rollback
     运行时异常的定义: RuntimeException  和他的子类都是运行时异常, 例如NullPointException , 		NumberFormatException 
 3) 当你的业务方法抛出非运行时异常, 主要是受查异常时,提交事务
    受查异常:在你写代码中,必须处理的异常。例如IOException, SQLException

总结spring的事务

  1、管理事务的是 事务管理和他的实现类
  2、spring的事务是一个统一模型
     1)指定要使用的事务管理器实现类,使用<bean>
	 2)指定哪些类,哪些方法需要加入事务的功能
	 3)指定方法需要的隔离级别,传播行为,超时

小型项目的事务(使用注解)

spring框架自己用aop实现给业务方法增加事务的功能, 使用@Transactional注解增加事务。
@Transactional注解是spring框架自己注解,放在public方法的上面,表示当前方法具有事务。可以给注解的属性赋值,表示具体的隔离级别,传播行为,异常信息等等

使用@Transactional的步骤:
	1.需要声明事务管理器对象<bean id="xx" class="DataSourceTransactionManager">
	2.开启事务注解驱动, 告诉spring框架,我要使用注解的方式管理事务。spring使用aop机制,创建@Transactional所在的类代理对象,给方法加入事务的功能。

spring给业务方法加入事务:在你的业务方法执行之前,先开启事务,在业务方法之后提交或回滚事务,使用aop的环绕通知
@Around("你要增加的事务功能的业务方法名称")
Object myAround(){
	开启事务,spring给你开启
	try{
		buy(1001,10);
		spring的事务管理器.commit();
	}catch(Exception e){
		spring的事务管理器.rollback();
	}	 
}
3.在你的方法的上面加入@Trancational
<!--声明事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" >
        <!--连接的数据库,指定数据源-->
        <property name="dataSource" ref="myDataSources"/>
    </bean>
    <!--开启事务注解驱动,告诉spring使用注解
    transaction-manager 事务管理器对象的id
    -->
    <tx:annotation-driven transaction-manager="transactionManager"  />
-------------------------------------------------------------------------
//需要添加事务的方法上方添加注解
@Transactional(
	propagation = Propagation.REQUIRED,
    isolation = Isolation.DEFAULT,
    readOnly = false,
    rollbackFor = {
    	NoEnouchException.class,NullPointerException.class
 	}
)

大型项目的事务

1)要使用的是aspectj框架,需要加入依赖
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aspects</artifactId>
	<version>5.2.5.RELEASE</version>
</dependency>
2)声明事务管理器对象	 
<bean id="xx" class="DataSourceTransactionManager">	
3) 声明方法需要的事务类型(配置方法的事务属性【隔离级别,传播行为,超时】)
4) 配置aop:指定哪些哪类要创建代理。
<!--声明事务管理器-->
<bean id="transcationManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<!--连接的数据库指定数据源-->
	<property name="dataSource" ref="myDataSources" />
</bean>
	<!--声明业务方法的事务属性,隔离级别、传播行为、超过时间
	id:自定义名称,表示两个标签之间配置内容的
	transaction-manager:事务管理器的id
	-->
	<tx:advice id="myAdvice" transaction-manager="transactionManager">
		<tx:attributes>
		<!--tx:method:给具体的方法配置事务属性,method可以有多个,分别给不同的方法配置事务属性
		name,方法名称,1)完整的方法,不带包名和类名
					  2)方法可以使用通配符,*表示任意字符
		propagation:传播行为,枚举值
		isolation:隔离级别
		rollback-for:指定的异常回滚的类名(全限定名称)
		-->
			<tx:method name="buy" propagation="REQUIRED" 
			isolation="DEFAULT" read-only="false"
			rollback-for="java.lang.NullPointerException,com.qzj.excep.NoEnouchException" />
		</tx:attributes>
</tx:advice>
<!--使用通配符, 指定很多的方法-->
<tx:method name="add*" propagation="REQUIRES NEW" /> 
<!--指定修改方法-->
<tx:method name="modify*" />
<!--删除方法--> 
<tx:method name="remove*" />
<!--查询方法, query , search,find-->
<tx:method name="*" propagation="SUPPORTS" read-only="true" />
<!--配置aop-->
<aop:config>
	<!--切入点表达式,指定哪些包中的类,要使用事务
	id:切入点表达式的名称,唯一值
	expression:切入点表达式,指定所有service包及其子包中的方法-->
	<aop:pointcut id="servicePt" expression="execution(* *..service..*.*(..))" />
	<!--配置增强器,关联advice和pointcut
	advice-ref:通知,tx:advice的id
	pointcut-ref:切入点表达式的id-->
	<aop:advisor advice-ref="myAdvice" pointcut-ref="servicePt" />
</aop:config>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值