Spring

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 id = "book" class = "com.qfedu.ioc.bean.Book" scope = "singleton" lazy-init = "true" ></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 — 基于注解

1 创建 Maven 项⽬
2 添加 SpringIoC 依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.13.RELEASE</version>
</dependency>
3 创建 Spring 配置⽂件
因为 Spring 容器初始化时,只会加载 applicationContext.xml ⽂件,那么我们在实体类中添加的注解就不会被 Spring扫描,所以我们需要 applicationContext.xml 声明 Spring 的扫描范围 ,以达到 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"
 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 之外的类⼀律使⽤此注解声明
@Scope("prototype") 表示声明当前类为⾮单例模式(默认单例模式)
@Lazy(true) 表示声明为懒汉模式,默认为饿汉模式
@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; }

代理模式

动态代理

静态代理:代理类只能为 实现了该接口的类 生产代理对象 (特定接口比较局限)

 使用代理类的好处

  1. 被代理类中只用关注核心业务的实现,将通用的管理型逻辑(事务管理、日志管理)和业务逻辑分离
  2. 将通用的代码放在代理类中实现,提供了代码的复用性
  3. 通过在代理类添加业务逻辑,实现对原有业务逻辑的扩展(增强)

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动态代理

代理类去创建被代理类的子类 来创建代理类对象

  1. 添加CGLib依赖
  2. 创建一个类,实现MethodInt:rceptor接口,同时实现接口中的intercept方法
  3. 在类中定义一个0bject类型,并提供这个变量的有参构造器,用于传递被代理对象
  4. 定义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();
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值