[我的工作台 - Gitee.com]:
<dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.3</version> </dependency> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.1</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency> </dependencies>
<?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" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd "> <!--开启注解的支持--> <context:annotation-config/> </beans>
dataSource和sqlSession的Spring方式注入 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true& characterEncoding=UTF- 8&allowPublicKeyRetrieval=true"/> <property name="username" value="root"/> <property name="password" value="8613919"/> </bean> <!-- sqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 绑定mybatis配置文件--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath*:com/mf/dao/**/*.xml"/> </bean> <!-- SqlSessionTemplate就是我们使用的sqlSession--> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <!-- 只能使用构造器注入sqlSessionFactory,因为他没有set方法--> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean>
spring理念:使现有技术更加实用,本身就是一个大杂烩,整合现有的框架技术。
一句话概括:spring是一个轻量级的控制反转Ioc和面向切面AOP的容器(框架)。
spring7层分层架构:
**核心容器:**通过beanfactory使用控制反转定义创建、配置、管理bean的方式。
spring上下文:配置文件,提供一些企业服务。
**springAOP:**将声明性事务切入应用程序。
**springDAO:**面向 JDBC 的异常,降低了需要编写的异常代码数量(例如打开和关闭连接)。
Spring ORM:若干个 ORM 框架。
Spring Web 模块:为基于 Web 的应用程序提供了上下文
Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。
1.ApplicationContext.xml读取配置文件
2.POJO根据元数据创建和组装Bean
3.程序使用时再从Ioc容器中取出需要的对象
Ioc实现方式有两种:xml配置和注解
采用xml配置,bean的定义信息和实现分离;
注解把二者合二为一,定义信息直接以注解形式在实现类中,从而达到零配置。
控制反转的本质是一种设计思想,DI(依赖注入)是实现IOC的一种方式。
1.创建实体,创建接口和实现类
2.注册beans.xml,交由spring创建和管理
<?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就是java对象 , 由Spring创建和管理--> <bean id="hello" class="com.kuang.pojo.Hello"> <property name="name" value="Spring"/> </bean> <bean id="MysqlImpl" class="com.kuang.dao.impl.UserDaoMySqlImpl"/> <bean id="OracleImpl" class="com.kuang.dao.impl.UserDaoOracleImpl"/> <bean id="ServiceImpl" class="com.kuang.service.impl.UserServiceImpl"> <!--注意: 这里的name并不是属性 , 而是set方法后面的那部分 , 首字母小写--> <!--引用另外一个bean , 不是用value 而是用 ref--> <property name="userDao" ref="OracleImpl"/> </bean> </beans>
3.要用直接ApplicationContext 从beans.xml拿到(再也不用new 对象了)
1.通过无参构造方法来创建。
2.通过有参构造方法(还是用Set方法)来创建。
beans.xml参数设置3种方式:
1.根据index参数下标。
2.根据参数名字。推荐使用
3.根据参数类型。不建议使用
<constructor-arg index="0" value="kuangshen2"/> <property name="name" value="马富说"/> <constructor-arg type="java.lang.String" value="kuangshen2"/>
配置文件加载的时候,其中管理的对象已经创建和初始化了。
传统对象由程序本身控制创建。
spring由IOC容器创建对象并设置属性,程序本身不创建对象而是被动接受对象,利用set方法进行注入,这个过程就叫做控制反转。
id是bean的标识符,要唯一;
没有配置id,name就是默认标识符;
有id又有name,name就是别名;
两个都没有,applicationContext.getBean(.class)获取对象。
<bean id="hello" name="hello2 h2,h3;h4" class="com.kuang.pojo.Hello"> <property name="name" value="Spring"/> </bean>
依赖IOC容器创建对象,注入对象属性值。
1.常量注入
2.bean注入 ref
3.数组注入 array
4.list注入 list
5.Map注入 map entry
6.set注入 set
7.null注入
8.properties注入 props prop
p标签注入(set方式注入)
c标签注入(有参构造方式注入)
单例 singleton
原生型 score=prototype
request创建自己的bean
session共享bean
spring装配bean方式有三种:
1.java中显示配置
2.xml中显示配置
3.隐式bean发现机制和自动装配(组件扫描component scanning,自动装配autowiring)
什么叫自动装配:spring自动发现应用上下文所创建的bean,spring自动满足bean之间的依赖。
自动装配有3种方式:
byname
bytype
注解(推荐使用)
<!--原来的方式--> <bean id="dog" class="com.kuang.pojo.Dog"/> <bean id="cat" class="com.kuang.pojo.Cat"/> <bean id="user" class="com.kuang.pojo.User"> <property name="cat" ref="cat"/> <property name="dog" ref="dog"/> <property name="str" value="qinjiang"/> </bean> <!--byname自动装配--> <bean id="user" class="com.kuang.pojo.User" autowire="byName"> <property name="str" value="qinjiang"/> </bean> <!--bytype自动装配,类型要唯一--> <bean id="dog" class="com.kuang.pojo.Dog"/> <bean id="cat" class="com.kuang.pojo.Cat"/> <!--类型不唯一报错--> <bean id="cat2" class="com.kuang.pojo.Cat"/> <bean id="user" class="com.kuang.pojo.User" autowire="byType"> <property name="str" value="qinjiang"/> </bean>
导使用注解就需要导入spring-aop的包
开启注解支持
<context:annotation-config/>
@Autowired是按类型自动装配的,不支持id匹配
//如果允许对象为null,设置required = false,默认为true @Autowired(required = false) private Cat cat; @Autowired private Dog dog; private String str;
<context:annotation-config/> <bean id="dog" class="com.kuang.pojo.Dog"/> <bean id="cat" class="com.kuang.pojo.Cat"/> <bean id="user" class="com.kuang.pojo.User"/>
@Autowired加上 @Qualifier可以根据byname自动装配,就可以支持id匹配了
@Autowired @Qualifier(value = "cat2") private Cat cat; @Autowired @Qualifier(value = "dog2") private Dog dog;
@Resource
如有指定的name属性,先按该属性进行byName方式查找装配;
其次再进行默认的byName方式进行装配;
其次再按byType的方式自动装配。
@Resource private Cat cat; @Resource private Dog og;
导入注解支持包aop 和 context约束
扫描包 和 添加注解驱动
<context:component-scan base-package="com.kuang.pojo"/> <context:annotation-config/>
包下的类增加注解@Component,属性注入 @Value(如果提供了set方法,在set方法上添加@value(“值”)
@Component("user") // 相当于配置文件中 <bean id="user" class="当前注解的类"/> public class User { @Value("秦疆") // 相当于配置文件中 <property name="name" value="秦疆"/> public String name; }
不同层的衍生注解:本质都是@component
bean的自动装配上节已讲。
小结:
xml与注解比较:
xml适用任何场景,结构清晰,维护方便
注解不是自己提供的类适用不了,开发方便
**推荐使用xml和注解整合开发:**xml管理bean,注解完成属性注入
编写实体类
创建config配置包,编写配置类
@Configuration //代表这是一个配置类 public class MyConfig { @Bean //通过方法注册一个bean,这里的返回值就Bean的类型,方法名就是bean的id! public Dog dog(){ return new Dog(); } }
@Test public void test2(){ ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class); Dog dog = (Dog) applicationContext.getBean("dog"); System.out.println(dog.name); }
@Import(MyConfig2.class) //导入合并其他配置类,类似于配置文件中的 inculde 标签
静态代理
1.抽象角色
2.具体角色
3.代理角色
4客户
缺点:增加具体角色要增加代理类,工作量变大,改动功能需要改动代码量大,违反开闭原则。
动态代理
动态代理分两类:基于接口(JDK动态代理)和基于类(cglib) 。
现在比较多使用javasist生成动态代理。
InvocationHandler:调用处理程序
Proxy :实现了接口InvocationHandler
Proxy
提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。
两个重要方法:
getProxy() : newProxyInstance(loader,interfaces,h);
loader-类加载器来定义代理类
interfaces-代理类实现接口列表
h-调度方法调用的调用处理函数
invoke() : 处理代理实例上的方法调用并返回结果
//生成代理类 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this); }
public class ProxyInvocationHandler implements InvocationHandler { private Rent rent; public void setRent(Rent rent) { this.rent = rent; } //生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this); } // proxy : 代理类 //method : 代理类的调用处理程序的方法对象. // 处理代理实例上的方法调用并返回结果 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { seeHouse(); //核心:本质利用反射实现! Object result = method.invoke(rent, args); fare(); return result; } //看房 public void seeHouse(){ System.out.println("带房客看房"); } //收中介费 public void fare(){ System.out.println("收中介费"); } }
//代理实例的调用处理程序 ProxyInvocationHandler pih = new ProxyInvocationHandler(); pih.setRent(host); //将真实角色放置进去! Rent proxy = (Rent)pih.getProxy(); //动态生成对应的代理类!
动态代理代理某一类业务
一个动态代理可以代理多个类,代理的是接口!
public class ProxyInvocationHandler implements InvocationHandler { private Object target; public void setTarget(Object target) { this.target = target; } //生成代理类 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this); } // proxy : 代理类 // method : 代理类的调用处理程序的方法对象. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { log(method.getName()); Object result = method.invoke(target, args); return result; } public void log(String methodName){ System.out.println("执行了"+methodName+"方法"); } }
//真实角色 UserServiceImpl userService = new UserServiceImpl(); //代理角色,不存在 ProxyInvocationHandler pih = new ProxyInvocationHandler(); //设置要代理的对象 pih.setTarget(userService); UserService proxy =(UserService) pih.getProxy(); proxy.add(); proxy.delete();
纵向开发:
dao
|
service
|
servlet
|
前端
横向开发:
log->userservice
面向切面编程: 不改变原来的代码的情况下,实现了对原有功能的增强。
springaop:提供声明式事务,允许用户自定义切面。
通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
切入点(PointCut):切面通知 执行的 “地点”的定义。
1.前置通知
2.后置通知
3.环绕通知
4.异常抛出通知
5.引介通知
导入aop织入包
编写业务接口
编写业务实现类
编写增强类(5种通知类型) implements MethodBeforeAdvice implements AfterReturningAdvice
public class Log implements MethodBeforeAdvice { //method : 要执行的目标对象的方法 //objects : 被调用的方法的参数 //Object : 目标对象 @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println( o.getClass().getName() + "的" + method.getName() + "方法被执行了"); } }
public class AfterLog implements AfterReturningAdvice { //returnValue 返回值 //method被调用的方法 //args 被调用的方法的对象的参数 //target 被调用的目标对象 @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("执行了" + target.getClass().getName() +"的"+method.getName()+"方法," +"返回值:"+returnValue); } }
注册到spring中
<!--注册bean--> <bean id="userService" class="com.kuang.service.UserServiceImpl"/> <bean id="log" class="com.kuang.log.Log"/> <bean id="afterLog" class="com.kuang.log.AfterLog"/> <!--aop的配置--> <aop:config> <!--切入点 expression:表达式匹配要执行的方法--> <aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/> <!--执行环绕; advice-ref执行方法 . pointcut-ref切入点--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config>
公共业务(实现了复用)和领域业务结合;
领域业务更纯粹 , 程序猿专注领域业务 , 其本质还是动态代理。
自定义切入类
public class DiyPointcut { public void before(){ System.out.println("---------方法执行前---------"); } public void after(){ System.out.println("---------方法执行后---------"); } }
注册到spring中
<bean id="diy" class="com.kuang.config.DiyPointcut"/> <!--aop的配置--> <aop:config> <!--第二种方式:使用AOP的标签实现--> <aop:aspect ref="diy"> <aop:pointcut id="diyPonitcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/> <aop:before pointcut-ref="diyPonitcut" method="before"/> <aop:after pointcut-ref="diyPonitcut" method="after"/> </aop:aspect> </aop:config>
编写注解实现的增强类
@Aspect public class AnnotationPointcut { @Before("execution(* com.kuang.service.UserServiceImpl.*(..))") public void before(){ System.out.println("---------方法执行前---------"); } @After("execution(* com.kuang.service.UserServiceImpl.*(..))") public void after(){ System.out.println("---------方法执行后---------"); } @Around("execution(* com.kuang.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint jp) throws Throwable { System.out.println("环绕前"); System.out.println("签名:"+jp.getSignature()); //执行目标方法proceed Object proceed = jp.proceed(); System.out.println("环绕后"); System.out.println(proceed); } }
注册到spring中
<!--第三种方式:注解实现--> <bean id="annotationPointcut" class="com.kuang.config.AnnotationPointcut"/> <aop:aspectj-autoproxy/>
<aop:aspectj-autoproxy />
声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。
当然,spring 在内部依旧采用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作,但具体实现的细节已经被<aop:aspectj-autoproxy />隐藏起来了
<aop:aspectj-autoproxy />有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为<aop:aspectj-autoproxy poxy-target-class=“true”/>时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理。
1.导入相关依赖:
<dependencies> <!--mybatis相关--> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency> <!--spring相关--> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.3</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.0.RELEASE</version> </dependency> <!-- aspectJaop织入器--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.6</version> </dependency> <!-- mybatis-spring整合包【重点】--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.6</version> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.1</version> <scope>test</scope> </dependency> <!-- 配置maven静态资源过滤问题--> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build> </dependencies>
2.编写配置文件
编写pojo实体类
applicationContext.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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <import resource="spring-dao.xml"/> <bean id="userMapper" class="com.mf.dao.UserMapperImpl"> <property name="sqlSessionTemplate" ref="sqlSession"/> </bean> <bean id="userMapper2" class="com.mf.dao.UserMapperImpl2"> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean> </beans>
mybatis.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 给mybatis留点面子,设置和别名留给它来做--> <typeAliases> <package name="com.mf.pojo"/> </typeAliases> </configuration>
spring-dao.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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- DataSource:使用Spring的数据源替换mybatis的配置 c3p0 dbcp druid 我们这里使用Spring提供的JDBC --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true& characterEncoding=UTF-8&allowPublicKeyRetrieval=true"/> <property name="username" value="root"/> <property name="password" value="8613919"/> </bean> <!-- sqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 绑定mybatis配置文件--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath*:com/mf/dao/**/*.xml"/> </bean> <!-- SqlSessionTemplate就是我们使用的sqlSession--> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <!-- 只能使用构造器注入sqlSessionFactory,因为他没有set方法--> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean> </beans>
编写dao接口类
编写mapper映射文件
编写service
public class UserDaoImpl implements UserDao { private SqlSession sqlSession; public void setSqlSession(SqlSession sqlSession) { this.sqlSession = sqlSession; } public User getUser(String userId) { return sqlSession.getMapper...; } }
注入sqlsessiontemplate
<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl"> <property name="sqlSession" ref="sqlSession" /> </bean>
3.代码实现
整合方式一:
1.引入spring配置文件beans.xml
2.配置数据源替换mybytatis数据源
<!--配置数据源:数据源有非常多,可以使用第三方的,也可使使用Spring的--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean>
3.配置SqlSessionFactory关联MyBatis
<!--配置SqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!--关联Mybatis--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath:com/kuang/dao/*.xml"/> </bean>
4.注册sqlsessionTemplate,关联sqlsessionFactory
<!--注册sqlSessionTemplate , 关联sqlSessionFactory--> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <!--利用构造器注入--> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean>
5.增加dao接口的实现类,私有化sqlsessionTemplate
public class UserDaoImpl implements UserMapper { //sqlSession不用我们自己创建了,Spring来管理 private SqlSessionTemplate sqlSession; public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; } public List<User> selectUser() { UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.selectUser(); } }
6.注册bean的实现。
<bean id="userDao" class="com.kuang.dao.UserDaoImpl"> <property name="sqlSession" ref="sqlSession"/> </bean>
整合方式二:
dao继承Support类 , 直接利用 getSqlSession() 获得 , 然后直接注入SqlSessionFactory 。
比起方式1 , 不需要管理SqlSessionTemplate , 而且对事务的支持更加友好 。
public class UserDaoImpl extends SqlSessionDaoSupport implements UserMapper { public List<User> selectUser() { UserMapper mapper = getSqlSession().getMapper(UserMapper.class); return mapper.selectUser(); } }
<bean id="userDao" class="com.kuang.dao.UserDaoImpl"> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean>
整合到spring以后可以完全不要mybatis的配置文件
1.原子性
2.一致性
3.隔离性
4.持久性
编程式事务管理:直接嵌套业务方法
声明式事务管理:aop前面编程,比前者要好。
spring事务管理
导入约束:tx
配置声明性事务
配置事务通知
配置AOP
<!-- 配置声明式事务--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 结合AOP实现事务的织入--> <!-- 配置事务通知:--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 给那些方法配置事务--> <!-- 配置事务传播的特性 propagation传播--> <tx:attributes> <tx:method name="add" propagation="REQUIRED"/> <tx:method name="delete" propagation="REQUIRED"/> <tx:method name="update" propagation="REQUIRED"/> <tx:method name="select" read-only="true"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!-- 配置事务的切入--> <aop:config> <aop:pointcut id="txPointCut" expression="execution(* com.mf.dao.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config>