Spring
1、简介
目的:简化企业级应用开发的复杂性。
maven依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13
| <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.18</version> </dependency>
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.18</version> </dependency>
|
1.1、特点:
- Spring是一个开源的免费容器;
- 是一个非轻量级、非入侵式(不影响原本内容)的框架;
- **==控制反转(IOC),面向切面编程(AOP)==**;
- 支持事务处理,整合框架。
1.2、组成
2、IOC控制反转
将service层的实现接口加上setDao方法,由用户自定义传入参数确定应该使用Dao接口的具体实现类:
==使用set注入:==
1 2 3 4
| private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; }
|
此时,程序猿不再需要管理对象的创建,而交给用户自定义!并且使系统的耦合性大大降低
控制反转IoC(Inversion of Conotrol)是一种设计思想,DI(依赖注入)是实现IoC的一种方法。
IoC是Spring框架的核心内容(通过xml配置管理对象)。
2.1 HelloSpring
pojo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.pans.pojo;
public class Hello { private String str;
public String getStr() { return str; }
public void setStr(String str) { this.str = str; }
@Override public String toString() { return "Hello{" + "str='" + str + '\'' + '}'; } }
|
beans.xml
1 2 3 4 5 6 7 8 9
| <?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 class="com.pans.pojo.Hello" id="hello"> <property name="str" value="Hello Spring!"/> </bean> </beans>
|
test
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) { ApplicationContext applicationContext= new ClassPathXmlApplicationContext("beans.xml"); Object hello = applicationContext.getBean("hello"); System.out.println(hello);
} }
|
3、IoC创建对象的方式
有参构造方式:
- 下标构造
1 2 3
| public Hello(String str) { this.str = str; }
|
1 2 3
| <bean class="com.pans.pojo.Hello" id="hello"> <constructor-arg index="0" value="Hello Spring"/> </bean>
|
- type类型构造(不建议使用,相同时按顺序构造)
- ref引用类型
- 参数名(最常用)
在配置文件被加载时,配置文件里面的所有类都会被初始化,并且同一个类只拥有一个对象!
1 2 3
| Object hello = applicationContext.getBean("hello"); Object hello2 = applicationContext.getBean("hello"); System.out.println(hello.equals(hello2));
|
4、Spring配置
5、DI(依赖注入)
Dependency Injection
5.1 构造器注入
5.2 set注入(重点)
- bean对象的创建依赖容器
- bean对象中的所有属性,由容器注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| <?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 class="com.pans.pojo.Address" id="address"> <property name="address" value="重庆"/> </bean> <bean class="com.pans.pojo.Student" id="student">
<property name="name" value="Peter~"/>
<property name="address" ref="address"/>
<property name="books"> <array> <value>红楼梦</value> <value>西游记</value> <value>三国演绎</value> </array> </property>
<property name="hobbies"> <list> <value>听歌</value> <value>敲代码</value> <value>打游戏</value> </list> </property>
<property name="card"> <map> <entry key="身份证" value="12412412"/> <entry key="学生证" value="432432423"/>
</map> </property>
<property name="games"> <set> <value>LOL</value> <value>LPL</value> <value>DOTA</value> </set>
</property> <property name="wife"> <null/> </property>
<property name="info"> <props> <prop key="学号">2021123123</prop> <prop key="姓名">张三</prop> <prop key="性别">男</prop>
</props> </property>
</bean> </beans>
|
5.3 其他方式
c命名空间注入和p命名空间注入(必须在命名约束里面引入约束代码)
1 2
| xmlns:c="http://www.springframework.org/schema/c" xmlns:p="http://www.springframework.org/schema/p"
|
1
| <bean class="com.pans.pojo.Address" p:address="重庆"/>
|
5.3 bean作用域
- 单例模式(默认)
1 2
| <bean class="com.pans.pojo.Student" id="student" scope="singleton">
|
- 原型模式
每次从容器中get的时候,都会产生一个新的对象。
1 2
| <bean class="com.pans.pojo.Student" id="student" scope="prototype">
|
- 其余的request,session,application只能在web开发中使用。
6、Bean的自动装配
- 自动装配式Spring满足bean依赖的一种方式!
- Spring会在上下文中自动寻找并自动给bean装配属性!
6.1 Spring中的三种装配方式:
- 在xml中显式配置
- 在java中显式配置
- ==隐式自动装配bean!!==
byName:(id必须全局唯一)
会在容器上下文中自动寻找和自己对象set方法后面的值对应的id
1 2 3 4 5 6 7 8
| <bean class="com.pans.pojo.Dog" id="dog"/> <bean class="com.pans.pojo.Cat" id="cat"/>
<bean class="com.pans.pojo.People" id="people" autowire="byName"> <property name="name" value="peters!!!"/>
</bean>
|
byType:(可省略id,对象属性必须唯一)
会在容器上下文中自动寻找和自己对象属性相同的bean
1 2 3 4 5 6 7 8
| <bean class="com.pans.pojo.Dog"/> <bean class="com.pans.pojo.Cat"/>
<bean class="com.pans.pojo.People" id="people" autowire="byType"> <property name="name" value="peters!!!"/>
</bean>
|
6.2 使用注解实现自动装配
- 导入约束和配置注解的支持
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?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" 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/>
<bean id="dog" class="com.pans.pojo.Dog"/> <bean id="cat" class="com.pans.pojo.Cat"/>
<bean class="com.pans.pojo.People" id="people"/> </beans>
|
- 在实体类里面添加注解(属性或者se方法上都可以)
1 2 3 4 5
| public class People { @Autowired private Cat cat; @Autowired private Dog dog;
|
@Autowired
可以不使用set方法了,前提是自动装配的属性在IOC容器中存在,且符合名字byName
可以添加(required=false)表示此字段可以为空
默认byType,当Type不止一个时,可以通过注解Qualifier指定byName
1 2 3
| @Autowired @Qualifier(value = "cat2") private Cat cat;
|
- Resource也可以用于自动装配
区别:Autowired默认通过byType实现,Resource默认byName实现,当byName找不到则通过byType实现
7、使用纯Java注解配置Spring
实体类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package com.pans.dao;
import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;
@Component public class UserDao { @Value("peters~") private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@Override public String toString() { return "UserDao{" + "name='" + name + '\'' + '}'; } }
|
配置bean类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.pans.Config;
import com.pans.dao.UserDao; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
@Configuration public class UserConfig {
@Bean public UserDao userDao(){ return new UserDao(); } }
|
测试类:
1 2 3 4 5 6 7 8 9 10 11 12 13
| import com.pans.Config.UserConfig; import com.pans.dao.UserDao; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Mytest { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(UserConfig.class); UserDao getName = context.getBean("userDao", UserDao.class); System.out.println(getName); } }
|
8、代理模式
代理模式是SpringAOP的底层!
分类:
8.1 静态代理
角色分析:
- 抽象角色:一般使用接口或者抽象类解决(租房)
- 真实角色:被代理的角色(房东 )
- 代理角色:代理真实角色,代理真实角色后会有更多附属操作!(中介)
- 客户:访问代理对象的人
代码示例:
1 2 3
| interface Rent { public void rent(); }
|
1 2 3 4 5 6
| public class Host implements Rent { public void rent(){ System.out.println("签合同,出租房屋!"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class Middle { private Host host;
public Middle(Host host) { this.host = host; }
public Middle() { }
public void rent(){ host.rent(); } public void lookOther(){ System.out.println("带客户看房!"); } }
|
1 2 3 4 5 6 7 8 9 10
| public class Renter { public static void main(String[] args) { Host host = new Host(); Middle middle = new Middle(host); middle.rent(); middle.lookOther();
} }
|
好处:
- 是真实角色(房东)更加简洁,不需要关注一些复杂的业务,交给代理角色实现
- 公共业务方便扩展和集中管理
缺陷:
- 一个真实角色需要一个代理角色,代码量大,开发效率变低!
8.2 浅聊AOP
开闭原则:对修改关闭,对扩展开放!(尽量不去改动原有业务代码,而是通过加入新的业务添加新的功能并且代理原有业务实现业务扩展)
8.3 动态代理
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是我们直接写好的!
- 动态代理分为两大类︰基于接口的动态代理,基于类的动态代理
- 基于接口—- JDK动态代理【我们在这里使用】
- 基于类: cglib
- java字节码实现 : javassist
jdk动态代理由反射实现,主要关注类Proxy
和接口
9、AOP
AOP在程序员不必改变原有代码的情况下,去横向增加新的功能!
9.1 AOP的Spring实现方式一
使用Spring自带API
- 先导入aop依赖
1 2 3 4 5 6 7
| <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.7</version> <scope>runtime</scope> </dependency>
|
- 代理服务接口
1 2 3 4 5 6 7 8
| package com.pans.service;
public interface UserService{ public void add(); public void delete(); public void update(); public void query(); }
|
- 代理服务接口实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.pans.service;
public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("调用了add方法"); }
@Override public void delete() { System.out.println("调用了delete方法");
}
@Override public void update() { System.out.println("调用了update方法"); }
@Override public void query() { System.out.println("调用了query方法"); } }
|
- aop增加服务1(前服务)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.pans.Log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class BeforeLog implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getName()+"的"+method.getName()+"方法被执行了"); } }
|
- aop增加服务2(后服务)
1 2 3 4 5 6 7 8 9 10 11 12
| package com.pans.Log;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterLog implements AfterReturningAdvice { @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getName()+"的"+method.getName()+"方法被执行了"+",返回值为"+returnValue); } }
|
- beans.xml注册服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean class="com.pans.service.UserServiceImpl" id="service"/> <bean class="com.pans.Log.AfterLog" id="afterLog"/> <bean class="com.pans.Log.BeforeLog" id="beforeLog"/>
<aop:config> <aop:pointcut id="pointcut" expression="execution(* com.pans.service.UserServiceImpl.*(..))"/>
<aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config> </beans>
|
- 测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import com.pans.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("beans.xml"); UserService userService = context.getBean("service", UserService.class); userService.add(); userService.delete(); userService.update(); userService.query(); } }
|
9.2 AOP的Spring实现方式二
使用自定义类
1 2 3 4 5 6 7 8
| public class Log { public void before(){ System.out.println("方法执行前!"); } public void after(){ System.out.println("方法执行后!"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| <bean class="com.pans.Log.Log" id="log"/> <aop:config> <aop:aspect ref="log"> <aop:pointcut id="point" expression="execution(* com.pans.service.UserServiceImpl.*(..))"/> <aop:before method="before" pointcut-ref="point"/> <aop:after method="after" pointcut-ref="point"/> </aop:aspect> </aop:config>
|
9.3 AOP的Spring实现方式三
使用注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before;
@Aspect public class Log { @Before("execution(* com.pans.service.UserServiceImpl.*(..))") public void before(){ System.out.println("方法执行前!"); } @After("execution(* com.pans.service.UserServiceImpl.*(..))") public void after(){ System.out.println("方法执行后!"); } }
|
xml中配置开启注解支持
1 2 3 4
| <bean class="com.pans.Log.Log"/>
<aop:aspectj-autoproxy/>
|
10、整合Mybatis
10.1 回顾Mybatis用法
- 编写实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| package com.pans.pojo;
public class User {
private long id; private String name; private String pwd; private String teacherId;
public long getId() { return id; }
public void setId(long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPwd() { return pwd; }
public void setPwd(String pwd) { this.pwd = pwd; }
public String getTeacherId() { return teacherId; }
public void setTeacherId(String teacherId) { this.teacherId = teacherId; }
public User(long id, String name, String pwd, String teacherId) { this.id = id; this.name = name; this.pwd = pwd; this.teacherId = teacherId; }
@Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", pwd='" + pwd + '\'' + ", teacherId='" + teacherId + '\'' + '}'; } }
|
- 编写mapper接口
1 2 3 4 5 6 7 8 9
| package com.pans.Mapper;
import com.pans.pojo.User;
import java.util.List;
public interface UserMapper { public List<User> query(); }
|
- 编写接口实现
1 2 3 4 5 6 7 8 9
| <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.pans.Mapper.UserMapper"> <select id="query" resultType="user"> select * from user; </select> </mapper>
|
- 配置mybatis-config.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <?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> <typeAliases> <package name="com.pans.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&serverTimezone=Asia/Shanghai"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/pans/Mapper/UserMapper.xml"/> </mappers> </configuration>
|
- 测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class MybatisTest { @Test public void test() throws IOException { String resource = "Mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> query = mapper.query(); for (User user : query) { System.out.println(user); } } }
|
10.2 Mybatis-Spring
- 编写数据源配置
- sqlSessionFactory
- sqlSessionTemplate
- 需要给接口增加实现类
- 将实现类注入到Spring中测试
- 直接在配置文件中配置sqlSession,简化测试类为:
1 2 3 4 5 6 7
| ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");
UserMapper userMapper = context.getBean("userMapper", UserMapper.class); List<User> query = userMapper.query(); for (User user : query) { System.out.println(user); }
|
1 2 3 4 5 6 7 8 9
| <?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> <typeAliases> <package name="com.pans.pojo"/> </typeAliases> </configuration>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.pans.Mapper;
import com.pans.pojo.User; import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;
public class UserMapperImpl implements UserMapper { private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; }
@Override public List<User> query() { UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.query(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <?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 class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean>
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:Mybatis-config.xml"/> <property name="mapperLocations" value="classpath:com/pans/Mapper/UserMapper.xml"/> </bean>
<bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSession"> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean>
</beans>
|
1 2 3 4 5 6 7 8 9 10 11 12
| <?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">
<import resource="appkicationContext.xml"/>
<bean class="com.pans.Mapper.UserMapperImpl" id="userMapper"> <property name="sqlSession" ref="sqlSession"/> </bean>
</beans>
|
11、Spring中的事务管理
- 声明式事务:AOP
- 编程式事务:需要在代码中进行事务管理(需修改原有代码,不推荐)
- mapper接口中添加方法
1 2 3 4 5 6 7 8 9 10 11
| import com.pans.pojo.User;
import java.util.List;
public interface UserMapper { public List<User> query();
public int add(User user);
public int delete(int id); }
|
- mapper实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| package com.pans.Mapper;
import com.pans.pojo.User; import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;
public class UserMapperImpl implements UserMapper { private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; }
@Override public List<User> query() { UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User(7, "潘帅", "sad", "sad"); mapper.add(user); mapper.delete(7); return mapper.query(); }
@Override public int add(User user) { UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.add(user); }
@Override public int delete(int id) { UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.delete(id); } }
|
- mapper配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.pans.Mapper.UserMapper"> <select id="query" resultType="user"> select * from user; </select>
<insert id="add" parameterType="user"> insert into user (id,name,pwd) values(#{id},#{name},#{pwd}) </insert>
<delete id="delete" parameterType="int"> deletes from user where id=#{id}; </delete>
</mapper>
|
- spring的xml配置中增加事务支持
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"> <constructor-arg ref="dataSource"/> </bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="query"/> </tx:attributes> </tx:advice>
<aop:config> <aop:pointcut id="txPoint" expression="execution(* com.pans.Mapper.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/> </aop:config>
|