Spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架
2002年,首次推出Spring框架的雏形,interface21框架
2004年3月24日,Spring框架以interface21为基础,经过重新设计发布了1.0正式版
开源的免费框架
轻量级非入侵式框架
支持对事务的处理,对框架整合的支持
官方网站:https://spring.io/
5.2.23官方文档:https://docs.spring.io/spring-framework/docs/current/reference/html/
api文档:https://docs.spring.io/spring-framework/docs/current/javadoc-api/
老版本文档:https://docs.spring.io/spring-framework/docs/5.0.10.RELEASE/spring-framework-reference/(更改地址中间的版本号访问响应版本)
老版本jar包下载地址:https://repo.spring.io/ui/native/release/org/springframework/spring
github下载地址:https://github.com/spring-projects/spring-framework
maven仓库
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.3.23version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.3.23version>
dependency>
IOC全称是Inversion of Control,控制反转
它是一种设计思想,由容器将设计好的对象交给容器控制,而非对象内部直接new
传统的Java设计中,直接会在对象的内部通过new进行对象的创建,是程序主动创建以来对象;
对Ioc来说,有一个专门的容器专门管理这些对象的生命周期,控制对象的创建;所以在Ioc中,是通过Ioc容器控制对象,由Ioc容器控制外部资源的获取
bean.xml
测试类
import com.daban.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Mytest {
public static void main(String[] args) {
// 获取spring的上下文对象
// 参数可以有多个xml文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
// 由上下文对象得到bean对象
// 第一个参数为对象的名字(对应xml的bean标签中的id值)
// 第二个参数为该bean对象的类型,避免了强制类型转换
Hello hello = applicationContext.getBean("hello1", Hello.class);
System.out.println(hello.toString());
}
}
默认使用无参构造器
三种方式,只能使用其中之一
变量索引+值的方式
<constructor-arg index="0" value="野山鸡">
类型+值的方式,如果两个String就不太好分辨,不推荐
<constructor-arg type="java.lang.String" value="野山鸡"/>
变量名+值的方式
<constructor-arg name="name" value="野山鸡"/>
总结:在配置文件被加载的时候,容器中管理的对象就已经被初始化了
给bean的id取一个别名。设置别名后,使用别名和原先的名字都可以
<alias name="user" alias="user2"/>
| 属性 | 作用 | 备注 |
|---|---|---|
| id | bean的唯一标识,类似与对象名 | |
| class | bean所对应的类全限名 | |
| name | 取别名,可以取多个,和alisa标签类似 |
一般用于团队开发使用,把其他多个配置文件合并到一个配置文件中,加载配置文件时,只加载一个就行
<import resource="bean2.xml"/>
详看《IOC创建对象的方式》
<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 id="student" class="com.daban.pojo.Student">
<property name="name" value="青山"/>
<property name="address" ref="address"/>
<property name="book">
<array>
<value>西游记value>
<value>三国演义value>
<value>红楼梦value>
<value>水浒传value>
array>
property>
<property name="hobbys">
<list>
<value>唱歌value>
<value>弹吉他value>
<value>骑行value>
list>
property>
<property name="card">
<map>
<entry key="身份证" value="12345512351512553"/>
<entry key="银行卡" value="662522512525221"/>
map>
property>
<property name="games">
<set>
<value>吃鸡value>
<value>LOLvalue>
set>
property>
<property name="info">
<props>
<prop key="username">张三prop>
<prop key="password">112233prop>
props>
property>
<property name="wife">
<null/>
property>
bean>
<bean id="address" class="com.daban.pojo.Address">
<property name="address" value="陕西西安"/>
bean>
beans>
p命名空间注入(和set方法注入作用一样)
需要加入p的命名空间
xmlns:p=“http://www.springframework.org/schema/p”
<bean id="user" class="com.daban.pojo.User" p:age="12" p:name="雪山"/>
c命名空间注入(和构造器方法注入作用一样)
需要加入c的命名空间
xmlns:c=“http://www.springframework.org/schema/c”
<bean id="user" class="com.daban.pojo.User" c:age="12" c:name="青山"/>
<bean id="user" class="com.daban.pojo.User" c:_0="青山" c:_1="13" />
bean标签的属性中设置scope
| 作用域 | 描述 | 备注 |
|---|---|---|
| singleton | 单例模式 | 每次从容器中get,就会的到同一个对象 |
| prototype | 原型模式 | 每次从容器中get,就会的到一个新对象 |
| request | 再一次请求中 | |
| session | 再一次会话中 | |
| application | 在一个应用中 |
Spring中装配的三种方式
<bean id="person" class="com.daban.pojo.Person">
<property name="name" value="川崎"/>
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
bean>
<bean id="cat" class="com.daban.pojo.Cat"/>
<bean id="dog" class="com.daban.pojo.Dog"/>
<bean id="person" class="com.daban.pojo.Person" autowire="byName">
<property name="name" value="川崎"/>
bean>
<bean id="cat" class="com.daban.pojo.Cat"/>
<bean id="dog" class="com.daban.pojo.Dog"/>
导入需要的约束context
xm<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"
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">
配置注解支持,加入如下,开能开启注解
<context:annotation-config/>
| 注解 | 解释 | 备注 |
|---|---|---|
| @Autowired | 直接使用在需要装配的属性上 | 使用后可以省去set方法 |
| @Qualifier(value = “xxx”) | 匹配id为value值的bean | 自动装配环境复杂bean不唯一时使用 |
| @Resource | java的自动装配 | 先用名字查询,查不到使用类型 |
| @Nullable | 该字段可以为null |
使用注解必须保证aop包的导入
必须导入约束context
<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"
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">
<context:annotation-config/>
<context:component-scan base-package="com.daban.pojo"/>
| 注解 | 描述 | 备注 |
|---|---|---|
| @Component | 放在类上,说明被spring管理,将该类放在容器中 | 就是bean |
| @Value(“XXX”) | 属性注入,属性上 | 复杂的属性建议使用配置文件 |
| @Repository | 和@Component一样,只是在dao层使用这个 | |
| @Service | 和@Component一样,只是在Service层使用这个 | |
| @Controller | 和@Component一样,只是在Controller层使用这个 | |
| @Scope(“xxx”) | bean的作用域 |
实体类
package com.daban.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//@Component注册一个组件,在这里可以省略
@Component
public class User {
@Value("hhhhh")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
配置类
package com.daban.config;
import com.daban.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//@Configuration代表这是一个配置类,可省略
//@Bean相当于注册一个bean,id就是方法名,class就是方法返回值
@Configuration
public class MyConfig {
@Bean
public User getUser(){
return new User();
}
}
测试类
import com.daban.config.MyConfig;
import com.daban.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User user = context.getBean("getUser", User.class);
System.out.println(user.toString());
}
}
SpringAOP的底层就使用代理模式
角色分析:
静态代理模式的优点:
静态代理模式的缺点:
代码步骤:
1、接口
package com.daban.demo01;
public interface Rent {
public void rent();
}
2、真实角色
package com.daban.demo01;
public class Host implements Rent {
private int NO;
public Host() {
}
public Host(int NO) {
this.NO = NO;
}
@Override
public void rent() {
System.out.println(NO+"号房东要出租房子");
}
}
3、代理角色
package com.daban.demo01;
public class Proxy implements Rent{
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
@Override
public void rent() {
seeHouse();
fare();
host.rent();
}
public void seeHouse(){
System.out.println("中介带你看房");
}
public void fare(){
System.out.println("收取中介费");
}
}
4、客户端访问代理角色
package com.daban.demo01;
public class Client {
public static void main(String[] args) {
Proxy proxy = new Proxy(new Host(2));
proxy.rent();
}
}
基本示例:
接口:
package com.daban.demo02;
public interface Rent {
public void rent();
}
实现类:
package com.daban.demo02;
public class Host implements Rent {
private int NO;
public Host() {
}
public Host(int NO) {
this.NO = NO;
}
@Override
public void rent() {
System.out.println(NO+"号房东要出租房子");
}
}
动态生成类:
package com.daban.demo02;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//使用这个类自动生成代理类
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);
}
//处理代理实例,并返回结果
@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("收取中介费");
}
}
测试类:
package com.daban.demo02;
public class Client {
public static void main(String[] args) {
//真实角色
Host host = new Host(3);
//用这个来生成代理类
ProxyInvocationHandler handler = new ProxyInvocationHandler();
handler.setRent(host);
//生成代理类
Rent proxy =(Rent)handler.getProxy();
proxy.rent();
}
}
通用示例:
接口:
package com.daban.demo03;
public interface UserService {
void add();
void delete();
void update();
void select();
}
实现类
package com.daban.demo03;
public class UserServiceImp implements UserService{
@Override
public void add() {
System.out.println("增加用户");
}
@Override
public void delete() {
System.out.println("删除用户");
}
@Override
public void update() {
System.out.println("修改用户");
}
@Override
public void select() {
System.out.println("查询用户");
}
}
动态生成类(通用了):
package com.daban.demo03;
import com.daban.demo02.Rent;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//使用这个类自动生成代理类
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);
}
//处理代理实例,并返回结果
@Override
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 msg){
System.out.println("执行了"+msg+"方法");
}
}
测试类:
package com.daban.demo03;
public class Client {
public static void main(String[] args) {
UserServiceImp userServiceImp = new UserServiceImp();
ProxyInvocationHandler handler = new ProxyInvocationHandler();
handler.setTarget(userServiceImp);
UserService proxy = (UserService) handler.getProxy();
proxy.add();
}
}
什么是AOP:面向切面编程
名词:
SpringAOP中,通过Advice定义横切逻辑,支持五种类型的Advice
| 通知类型 | 连接点 | 实现接口 |
|---|---|---|
| 前置通知 | 方法方法前 | org.springframework.aop.MethodBeforeAdvice |
| 后置通知 | 方法后 | org.springframework.aop.AfterReturningAdvice |
| 环绕通知 | 方法前后 | org.aopalliance.intercept.MethodInterceptor |
| 异常抛出通知 | 方法抛出异常 | org.springframework.aop.ThrowsAdvice |
| 引介通知 | 类中增加新的方法属性 | org.springframework.aop.IntroductionInterceptor |
即,AOP在不改变源代码的情况下,增加新功能
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.9.9.1version>
<scope>runtimescope>
dependency>
package com.daban.service;
public interface UserService {
void add();
void delete();
void update();
void select();
}
package com.daban.service;
public class UserServiceImp implements UserService{
@Override
public void add() {
System.out.println("增加了一个用户");
}
@Override
public void delete() {
System.out.println("删除了一个用户");
}
@Override
public void update() {
System.out.println("改变了一个用户");
}
@Override
public void select() {
System.out.println("查询了一个用户");
}
}
package com.daban.log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
//需要切入的类需要实现相应的接口,11.2中五种接口都可以,扮演不同的方式
public class Log implements MethodBeforeAdvice {
/**
* method:要执行的目标对象的方法
* args:参数
* target:目标对象
*/
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName()+"的"+method.getName()+"方法被执行");
}
}
<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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.daban.service.UserServiceImp"/>
<bean id="log" class="com.daban.log.Log"/>
<bean id="afterLog" class="com.daban.log.AfterLog"/>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.daban.service.UserServiceImp.*(..))"/>
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
aop:config>
import com.daban.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//动态代理类代理的是接口,所以这里使用UserService接口,而不使用实现类
UserService userService = context.getBean("userService", UserService.class);
userService.add();
}
}
package com.daban.diy;
public class DiyPointcut {
public void before(){
System.out.println("********方法执行前********");
}
public void after(){
System.out.println("========方法执行后========");
}
}
<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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="com.daban.service.UserServiceImp"/>
<bean id="log" class="com.daban.log.Log"/>
<bean id="afterLog" class="com.daban.log.AfterLog"/>
<bean id="diy" class="com.daban.diy.DiyPointcut"/>
<aop:config>
<aop:aspect ref="diy">
<aop:pointcut id="pointcut" expression="execution(* com.daban.service.UserServiceImp.*(..)))"/>
<aop:after method="after" pointcut-ref="pointcut"/>
<aop:before method="before" pointcut-ref="pointcut"/>
aop:aspect>
aop:config>
beans>
package com.daban.diy;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect//标注这个类是一个切面
public class AnnotationPointCut {
//设置切入点在要切入的方法上
@Before("execution(* com.daban.service.UserServiceImp.*(..)))")
public void before(){
System.out.println("********注解方式方法执行前********");
}
@After("execution(* com.daban.service.UserServiceImp.*(..)))")
public void after(){
System.out.println("========注解方式方法执行后========");
}
}
<bean id="anntation" class="com.daban.diy.AnnotationPointCut"/>
<aop:aspectj-autoproxy/>
步骤:
junit,mybatis,mysql数据库,spring相关,aop植入,mybatis-spring
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.47version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.11version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.3.23version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.1.9.RELEASEversion>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.9.9.1version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>2.0.2version>
dependency>
dependencies>
package com.daban.pojo;
import lombok.Data;
@Data
public class User {
private int id;
private String name;
private String pwd;
}
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.daban.pojo"/>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="UserMapper.xml"/>
mappers>
configuration>
package com.daban.mapper;
import com.daban.pojo.User;
import java.util.List;
public interface UserMapper {
public List<User> getUser();
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.daban.mapper.UserMapper">
<select id="getUser" resultType="user">
select * from mybatis.user
select>
mapper>
import com.daban.mapper.UserMapper;
import com.daban.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class MyTest {
@Test
public void test() throws IOException {
String resources = "mybatis-config.xml";
InputStream resource = Resources.getResourceAsStream(resources);
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resource);
SqlSession sqlSession = build.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> user = mapper.getUser();
for (User user1 : user) {
System.out.println(user1);
}
}
}
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.daban.pojo"/>
typeAliases>
configuration>
package com.daban.mapper;
import com.daban.pojo.User;
import java.util.List;
public interface UserMapper {
public List<User> getUser();
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.daban.mapper.UserMapper">
<select id="getUser" resultType="user">
select * from mybatis.user
select>
package com.daban.mapper;
import com.daban.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;
public class UserMapperImp implements UserMapper{
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> getUser() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.getUser();
}
}
<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 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=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:UserMapper.xml"/>
bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
bean>
<bean id="userMapper" class="com.daban.mapper.UserMapperImp">
<property name="sqlSession" ref="sqlSession"/>
bean>
beans>
import com.daban.mapper.UserMapper;
import com.daban.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
import java.util.List;
public class MyTest {
@Test
public void test() throws IOException {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");
UserMapper bean = context.getBean("userMapper",UserMapper.class);
List<User> user = bean.getUser();
for (User user1 : user) {
System.out.println(user1);
}
}
}
参见官网http://mybatis.org/spring/zh/sqlsession.html#SqlSessionDaoSupport
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource"/>
bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add" propagation="REQUIRED"/>
<tx:method name="*" propagation="REQUIRED"/>
tx:attributes>
tx:advice>
<aop:config>
<aop:pointcut id="txPointCut" expression="execution(* com.daban.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
aop:config>