Spring两大核心思想:loC和AOP
IOC:控制反转,Spring容器可以完成对象的创建、属性注入、对象管理等工作
AOP:面向切面,在不修改原有业务逻辑的情况下,实现原有业务的增强
Spring IOC--基于xml
ICO和DI
- IoC (Inverse of Control) 控制反转,通过Spring对象⼯⼚完成对象的创建 使用Bean创建对象
- DI (Dependency Injection)依赖注⼊,在Spring完成对象创建的同时依赖Spring容器完成对象属性的赋值
bean.xml
<!--通过bean将实体类配置给Spring进⾏管理,id表示实体类的唯⼀表示-->
<bean id="stu" class="com.qfedu.ioc.bean.Student"></bean>
test类
//1.初始化Spring容器,加载Spring配置⽂件
ClassPathXmlApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
//2.通过Spring容器获取Student对象
Student student2 = (Student) context.getBean("stu");
底层原理 :getBean通过id拿到类的全路径名,可以通过反射机制(class.forNam)得到class对象再通过 newInstance() 得到对象。 getDeclaredFields() 通过反射获取类中的属性
map( id, class): bean中的 id 和 class 存放在map中 通过key可以拿到value。
DI依赖注⼊
依赖注⼊三种⽅式
Spring 容器加载配置⽂件之后,通过 反射 创建类的对象,并给属性赋值;Spring 容器通过反射实现属性注⼊有三种⽅式:
- set⽅法注⼊
- 构造器注⼊
- 接⼝注⼊(不常⽤)
1、常量注入
<bean id="student" class="com.kuang.pojo.Student">
<property name="name" value="小明"/>
</bean>
2、Bean注入
注意点:这里的值是一个引用,ref
<bean id="addr" class="com.kuang.pojo.Address">
<property name="address" value="重庆"/>
</bean>
<bean id="student" class="com.kuang.pojo.Student">
<property name="name" value="小明"/>
<property name="address" ref="addr"/>
</bean>
3、数组注入
<bean id="student" class="com.kuang.pojo.Student">
<property name="name" value="小明"/>
<property name="address" ref="addr"/>
<property name="books">
<array>
<value>西游记</value>
<value>红楼梦</value>
<value>水浒传</value>
</array>
</property>
</bean>
4、List注入
<property name="hobbys">
<list>
<value>听歌</value>
<value>看电影</value>
<value>爬山</value>
</list>
</property>
5、Map注入
<property name="card">
<map>
<entry key="中国邮政" value="456456456465456"/>
<entry key="建设" value="1456682255511"/>
</map>
</property>
6、set注入
<property name="games">
<set>
<value>LOL</value>
<value>BOB</value>
<value>COC</value>
</set>
</property>
7、Null注入
<property name="wife"><null/></property>
8、Properties注入
<property name="info">
<props>
<prop key="学号">20190604</prop>
<prop key="性别">男</prop>
<prop key="姓名">小明</prop>
</props>
</property>
构造器注⼊
有参构造器注入
1、User.java
public class User {
private String name;
public User() {
System.out.println("user无参构造方法");
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("name="+ name );
}
}
2、beans.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.kuang.pojo.User">
<property name="name" value="kuangshen"/>
</bean>
</beans>
3、测试类
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//在执行getBean的时候, user已经创建好了 , 通过无参构造
User user = (User) context.getBean("user");
//调用对象的方法 .
user.show();
}
结果可以发现,在调用show方法之前,User对象已经通过无参构造初始化了!
有参构造方法注入
1、UserT . java
public class UserT {
private String name;
public UserT(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("name="+ name );
}
}
2、beans.xml 有三种方式编写 掌握第三种
<!-- 第一种根据index参数下标设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
<!-- index指构造方法 , 下标从0开始 -->
<constructor-arg index="0" value="kuangshen2"/>
</bean>
<!-- 第二种根据参数名字设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
<!-- name指参数名 -->
<constructor-arg name="name" value="kuangshen2"/>
</bean>
<!-- 第三种根据参数类型设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
<constructor-arg type="java.lang.String" value="kuangshen2"/>
</bean>
3、测试
@Test
public void testT(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserT user = (UserT) context.getBean("userT");
user.show();
}
结论:在配置文件加载的时候。其中管理的对象都已经初始化了!
Bean的作⽤域
在 bean 标签可以通过 scope 属性指定对象的的作⽤域
- scope="singleton" 表示当前bean是单例模式(默认饿汉模式,Spring容器初始化阶段就会完成此对象的 创建;当在bean标签中设置 lazy-init="true"变为懒汉模式)
- scope="prototype" 表示当前bean为原型模式,每次通过Spring容器获取此bean的对象时都会创建⼀个 新的对象。没有懒饿汉之分
Bean的自动装配
⾃动装配: Spring 在实例化当前 bean 的时候从 Spring 容器中找到匹配的实例赋值给当前 bean 的属性
- byName 根据当前Bean的属性名在Spring容器中寻找匹配的对象 ,如果根据name找打了bean但是类型不匹配则抛出异常
- byType 根据当前Bean的属性类型在Spring容器中寻找匹配的对象,如果根据类型找到了多个bean也会抛出异常
byName
通过实体类中的Set方法后面的名字和bean上下文中的id进行对比(id名要唯一)
<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="user" class="com.kuang.pojo.User" autowire="byName">
<property name="str" value="刘"/>
</bean>
byType
在beans.xml上下文中,查找和People属性类型相对应的bean (class类型要唯一)
<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="刘"/>
</bean>
IOC工作原理
Spring IoC — 基于注解
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.13.RELEASE</version>
</dependency>
<?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/>
<!-- 声明Spring⼯⼚注解的扫描范围 -->
<context:component-scan base-package="com.qfedu.beans"/>
</beans>
IoC常⽤注解
@Component 类注解,声明此类被Spring 容器进⾏管理,相当于 bean 标签的作⽤@Component(value="stu") value 属性⽤于指定当前 bean 的 id ,相当于 bean 标签的 id 属性; value 属性也可 以省略,如果省略当前类的id 默认为类名⾸字⺟改⼩写除了 @Component 之外 @Service 、 @Controller 、 @Repository 这三个注解也可以将类声明给 Spring 管理,他们主要是语义上的区别@Controller 注解主要声明将控制器类配置给 Spring 管理,例如 Servlet@Service 注解主要声明业务处理类配置 Spring 管理, Service 接⼝的实现类@Repository 直接主要声明持久化类配置给 Spring 管理, DAO 接⼝@Component 除了控制器、 servcie 和 DAO 之外的类⼀律使⽤此注解声明
@Controller
@Component(value="stu")
@Scope("prototype")
@Lazy(true)
public class User {
@Value("小明")
public String name;
}
放在要声明为初始和销毁的方法上面
@PostConstruct ⽅法注解,声明⼀个⽅法为当前类的初始化⽅法(在构造器之后执⾏),相当于bean标签的init-method属性
@PreDestroy ⽅法注解,声明⼀个⽅法为当前类的销毁⽅法(在对象从容器中释放之前执⾏),相当于bean标签的destory-method属性
添加注解在属性上面(或者set方法上面),表示使用注解进行属性值的自动装配
@Autowired 是byType自动装配的,加上@Qualifier则可以根据byName的方式自动装配
@Resource 先按该属性进行byName方式查找装配,再通过byType。可指定name属性 @Resource(name = "cat2")
public class User {
@Autowired
private Cat cat;
@Autowired
private Dog dog;
private String str;
}
@Autowired
public void setClazz(@Qualifier("c2") Clazz clazz) {
this.clazz = clazz; }
代理模式
动态代理
静态代理:代理类只能为 实现了该接口的类 生产代理对象 (特定接口比较局限)
使用代理类的好处
- 被代理类中只用关注核心业务的实现,将通用的管理型逻辑(事务管理、日志管理)和业务逻辑分离
- 将通用的代码放在代理类中实现,提供了代码的复用性
- 通过在代理类添加业务逻辑,实现对原有业务逻辑的扩展(增强)
JDK动态代理
动态代理:几乎可以为所有的类生产代理对象
动态代理有两种实现方式
JDK动态代理
CGLib动态代理
动态代理:代理类通过被代理对象实现的接口 产生代理对象。
1.创建一个被代理的对象,任意的都可以
package com.lj.demo02;
//房东实现接口
public class UserServiceImpl 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("查询了一个方法");
}
}
2.创建动态代理类
package com.lj.demo02;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//JDK动态代理底层原理
//JDK动态代理:通过被代理对象实现的接口 生产其代理类
//1 .创建一个类,实现InvocationHandler接口,重写invoke方法
//2.在类种定义一个0bject类型的变量,并提供这个变量的有参构造器,用于将被代理对象传递进来
//3.定义getProxy方法,用于创建并返回代理对象
//4.重写invoke方法,增加业务
public class JDKDynamicProxy implements InvocationHandler {
//被代理对象
private Object obj;
public JDKDynamicProxy(Object obj){
this.obj=obj;
}
//产生代理对象,返回代理对象
public Object getProxy(){
//1.获取被代理对象的类加载器
ClassLoader classLoader = obj.getClass().getClassLoader();
//2.获取被代理对象实现的接口
Class<?>[] interfaces = obj.getClass().getInterfaces();
//3.产生代理对象(通过被代理对象的类加载器和实现的接口)
//第三个参数:使用产生代理对象时,用于拦截方法的执行器
Object proxy = Proxy.newProxyInstance(classLoader, interfaces,this);
return proxy;
}
//method:被调用的方法,作为参数传递到invoke方法中
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
begin();
Object result = method.invoke(obj,args); //被代理对象的方法 add()
after();
return result;
}
public void begin(){
System.out.println("方法执行前----");
}
public void after(){
System.out.println("方法执行后----");
}
}
3.测试类
import com.lj.demo02.JDKDynamicProxy;
import com.lj.demo02.UserService;
import com.lj.demo02.UserServiceImpl;
import org.junit.Test;
public class MyTest {
@Test
public void test(){
//被代理对象
UserServiceImpl userService = new UserServiceImpl();
//将被代理对象传入JDK动态代理类
JDKDynamicProxy proxyclass = new JDKDynamicProxy(userService);
//创建代理对象
UserService proxy = (UserService) proxyclass.getProxy();
//使用代理对象调用方法,并不会执行调用的方法,而是进入到创建代理对象时指定的InvocationHandler类中的invoke方法
proxy.add();
}
}
CGLib动态代理
代理类去创建被代理类的子类 来创建代理类对象
- 添加CGLib依赖
- 创建一个类,实现MethodInt:rceptor接口,同时实现接口中的intercept方法
- 在类中定义一个0bject类型,并提供这个变量的有参构造器,用于传递被代理对象
- 定义getProxy方法创建并返回代理对象(代理对象是通过创建被代理类的子类来创建的)
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
代码实现
package com.lj.demo02;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CGLibDynamicProxy implements MethodInterceptor {
private Object obj;
public CGLibDynamicProxy(Object obj){
this.obj= obj;
}
public Object getProxy(){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(obj.getClass());
enhancer.setCallback(this);
Object proxy = enhancer.create();
return proxy;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
begin();
Object result = method.invoke(obj, objects);
after();
return result;
}
public void begin(){
System.out.println("方法执行前----");
}
public void after(){
System.out.println("方法执行后----");
}
}
测试
@Test
public void test2(){
//被代理对象
UserServiceImpl userService = new UserServiceImpl();
CGLibDynamicProxy proxyclass = new CGLibDynamicProxy(userService);
UserService proxy = (UserService) proxyclass.getProxy();
proxy.add();
}
Spring Aop
AOP概念
Aspect Oriented Programming面向切面编程,是一种利用“横切"的技术(底层实现就是动态代理),对原有的业务逻辑进行拦截,并且可以在这个拦截的横切面上添加特定的业务逻辑,对原有的业务进行增强。
基于动态代理实现在不改变原有业务的情况下对业务逻辑进行增强
SpringAop框架部署
- 在pom.xml中导入一个Aop织入依赖包 在Applicationcontext.xml导入aop的约束
- 自定义一个切入类
- 在Applicationcontext.xml中使用切入面进行配置
具体步骤如下:
1. 创建maven项目
2. 添加依赖
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
3.编写一个UserServiceImpl类实现UserService接口
//UserService接口
public interface UserService {
public void add();
public void delete();
public void update();
public void select();
}
//UserServiceImpl
public class UserServiceImpl implements UserService {
@Override
public void add() {
System.out.println("执行了add方法");
}
@Override
public void delete() {
}
@Override
public void update() {
}
@Override
public void select() {
}
}
4.自定义一个切面类
public class DiyPointcut {
public void before(){
System.out.println("---------方法执行前---------");
}
public void after(){
System.out.println("---------方法执行后---------");
}
}
5.配置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
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.lj.service.UserServiceImpl"/>
<bean id="diy" class="com.lj.log.DiyPointcut"/>
<aop:config>
<!--切入点-->
<aop:pointcut id="cut" expression="execution(* com.lj.service.UserServiceImpl.*(..))" />
<!--切面类-->
<aop:aspect ref="diy">
<!--通知-->
<aop:before method="before" pointcut-ref="cut"/>
<aop:after method="after" pointcut-ref="cut"/>
</aop:aspect>
</aop:config>
</beans>
6. 测试:
public class MyTest {
@Test
public void test(){
ApplicationContext context = newClassPathXmlApplicationContext("beans.xml");
UserService userService = (UserService) context.getBean("userService");
userService.add();
}
}
AOP使用注意事项
1.如果要使用Spring aop 面向切面编程.调用切入点方法的对象必须通过Spring容器获取
解释:如果一个类中的方法被声明为切入点并且织入了切点之后,通过Spring容器(getBean() )获取该类对象,实则获取到的是一个代理对象
AOP通知策略
before
after
after-throwing
after-returnning
around
//环绕通知的切点方法,必须准守如下的定义规则:
//1 .必须带有一个ProceedingJoinPoint类型的参数
//2.必须有0bject类型的返回值
//3.在前后增强的业务逻辑之间执行0bject v = point. proceed();
//4 .方法最后返回v
public Object method5( ProceedingJoinPoint point) throws Throwable {
system . out.println( "~~~~~~method5---before" );
//此代码的执行,就表示切入点方法的执行
Object v = point.proceed();
System. out.println( " ~~~~~~~method5---after " );
return v;
}
Aop注解配置
导入AOP织入依赖包,在applicationContext.xml中配置context和aop约束
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--配置注解支持-->
<context:annotation-config/>
<!--指定注解扫描包-->
<context:component-scan base-package="com.lj"/>
<!--基于注解配置的AOP-->
<aop:aspectj-autoproxy/>
</beans>
dao包下编写一个类
@Component
public class UserDaoImpl {
public void add(){
System.out.println("增加了一本书");
}
}
util下自定义一个事务管理类
@Component
@Aspect
public class LogManager {
@Pointcut("execution(* com.lj.dao.*.*(..)) ")
public void cut(){}
@Before("cut()")
public void begin(){
System.out.println("开始事务------");
}
@After("cut()")
public void commit(){
System.out.println("提交事务-------");
}
@Around("cut()")
public Object printExecuteTime(ProceedingJoinPoint point) throws Throwable {
long time1 = System.currentTimeMillis();
Object proceed = point.proceed();
long time2 = System.currentTimeMillis();
System.out.println("time:"+(time2-time1));
return proceed;
}
}
测试类
public class MyTest {
@Test
public void test(){
ApplicationContext userDaoImpl = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDaoImpl userDao = (UserDaoImpl) userDaoImpl.getBean("userDaoImpl");
userDao.add();
}
}
注意︰注解使用虽然方便,但是只能在源码上添加注解,因此我们的自定义类提倡使用注解配置;但如果如果使用到第三方提供的类则需要通过xml配置形式完成配置。
spring整合mybatis
Spring整合mybatis整合IOC配置
Spring可以为Mybatis提供那些帮助?
IOC支持:SpringIoc可以为Mybatis完成DataSource,SqlSessionFactory,SqlSession以及Dao对象的创建
Aop支持:使用spring提供的事务管理切面类完成对Mybatis数据库操作中的事务管理
<!--加载db.properties属性文件-->
<context:property-placeholder location="db.properties"/>
<!--依赖spring容器完成数据源DataSource的创建-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--依赖spring容器完成mybatis的SqlSessionFactory对象的创建-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mappers/*Mapper.xml"/>
<property name="typeAliasesPackage" value="com.lj.pojo"/>
<!--配置mybatis的主配置文件-->
<!--<property name="configLocation" value="classpath:mybatis-config.xml"/>-->
</bean>
<!--Dao扫描工具:加载dao包中的所有Dao接口,通过SqlSessionFactory获取SqlSession,然后创建所有的Dao接口对象,存储在Spring容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.lj.dao"/>
</bean>
</beans>
整合步骤
1.导入依赖
2.User类
package com.lj.pojo;
import lombok.Data;
@Data
public class User {
private int id;
private String name;
private String pwd;
}
3.UserMapper接口
package com.lj.dao;
import com.lj.pojo.User;
import java.util.List;
public interface UserMapper {
public List<User> getUserList();
}
4.UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lj.dao.UserMapper">
<select id="getUserList" resultType="user">
select * from mybatis.user
</select>
</mapper>
5.db.properties
使用外部配置文件连接时要注意
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&;useUnicode=true&;characterEncoding=utf8
jdbc.username=root
jdbc.password=123456
6.mybatis-config.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>
</configuration>
7.applicationContext.xml
导入context apo约束
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--加载db.properties属性文件-->
<context:property-placeholder location="db.properties"/>
<!--依赖spring容器完成数据源DataSource的创建-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--依赖spring容器完成mybatis的SqlSessionFactory对象的创建-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:mappers/*Mapper.xml"/>
<property name="typeAliasesPackage" value="com.lj.pojo"/>
<!--配置mybatis的主配置文件-->
<!--<property name="configLocation" value="classpath:mybatis-config.xml"/> -->
</bean>
<!--Dao扫描工具:加载dao包中的所有Dao接口,通过SqlSessionFactory获取SqlSession,然后创建所有的Dao接口对象,存储在Spring容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.lj.dao"/>
</bean>
</beans>
8.测试类
import com.lj.dao.UserMapper;
import com.lj.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class MyTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationConfig.xml");
//Dao的id默认首字母小写
UserMapper userMapper = (UserMapper) context.getBean("userMapper");
//System.out.println(userMapper.getUserList());
List<User> userList = userMapper.getUserList();
for (User user : userList) {
System.out.println(user);
}
}
}
Spring整合Mybatis整合AOP配置
Aop支持:使用spring提供的事务管理切面类完成对Mybatis数据库操作中的事务管理
springAop 事务管理策略-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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--配置注解支持-->
<context:annotation-config/>
<!--指定注解扫描包-->
<context:component-scan base-package="com.lj"/>
<!--1.将spring提供的事务管理,配置给Spring容器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--2.通过Spring提供的tx标签,声明事务管理策略-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" isolation="READ_COMMITTED" propagation="REQUIRED"/>
<tx:method name="insert*" isolation="READ_COMMITTED" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
<!--3.将事务管理以AOP配置,应用于DAO操作方法-->
<aop:config>
<aop:pointcut id="crud" expression="execution(* com.lj.service.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="crud"/>
</aop:config>
<bean/>
SpringAOP事务管理策略-注解
-
在applicationContext.xml中配置事务管理,声明使用注解方式进行事务配置
<!--1.将spring提供的事务管理,配置给Spring容器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--2.声明使用注解完成事务配置-->
<tx:annotation-driven transaction-manager="transactionManager"/>
-
在需要Spring进行事务管理的方法上添加@Transactional注解
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.SUPPORTS)
public List<User> listUsers() {
return userMapper.getUserList();
}