Spring

1、Spring认识

1.1简介

  • Rod Johnson,Spring Framework创始人

  • 是现有的技术更加容易结合使用,整合技术框架

  • SSM:Spring + SpringMVC + Mybatis

  • SSH: Struct2 + Spring +Hibernate

    官网:https://spring.io/projects/spring.framework#overview

1.2优点

  • 开源免费的框架
  • 轻量级的、非入侵式的框架
  • 控制反转(IOC),面向切面编程(AOP)
  • 支持事务的处理,对框架整合的支持

2、IOC(控制反转)

​ 在我们之前的业务中,用户的需求变更可能会影响我们原来的代码,我们需要根据变更来修改原来的代码,这样操作会使改的代码量十分大

所以 我们要使用一个Set接口实现值的注入

public class UserServiceImpl implements  UserService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void getUser() {
        this.userDao.getUser();
    }
}
  • 之前,程序是主动创建对象!控制权在程序猿手上
  • 使用set注入后,程序不在具有主动性,而是变成了被动接受的对象

这种思想,从本质上解决了问题,我们程序员不用再去管理对象的创建。系统耦合性大大降低

3、Bean的装配

3.1 基于XML

1.属性set注入
 <bean id="student" class="com.kk.pojo.Student">
<!--        1.普通注入-->
        <property name="name" value="wkx"/>
<!--        2.bean注入-->
        <property name="address" ref="address"/>
<!--        3.数组注入-->
        <property name="book">
            <array>
                <value>红楼梦</value>
                <value>西游记</value>
                <value>水浒传</value>
                <value>三国演义</value>
            </array>
        </property>
    </bean>
2.属性构造注入
<bean id="address" class="com.kk.pojo.Address">
    <property name="address" value="CS"/>
</bean>
<bean id="student1" class="com.kk.pojo.Student1">
    <constructor-arg index="0" value="wkx"/>
    <constructor-arg index="1" ref="address"/>
</bean>
3.自动装配(autowire=“byType/byName”)

EXAMPLE 一个人有两只宠物

pojo类

public class People 
{
    private String name;
    private Cat cat;
    private Dog dog;
}
public class Cat {
    public void shout()
    {
        System.out.println("miao~");
    }
}
public class Dog {
    public void shout()
    {
        System.out.println("wang~");
    }
}

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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="cat" class="com.kk.po.Cat"/>
    <bean id="dog" class="com.kk.po.Dog"/>
    <!--  1 byName 自动装配-->
    <bean id="people" class="com.kk.po.People" autowire="byName">
        <property name="name" value="wkx"/>
    </bean>
    <!--  2 byType 自动装配-->
     <bean id="people" class="com.kk.po.People" autowire="byType">
        <property name="name" value="wkx"/>
    </bean>
</beans>

注意:

  • 如果是byName自动装配,默认匹配set后的小写名字,如setCat()方法,就自动匹配id等于cat的bean

  • 如果是byType自动装配,根据类型来匹配,如以下的cat,它是Cat类型的Bean,所以在自动装配时,会去Bean的容器里寻找这一类型的Bean

测试

public class MyTest {
    @Test
    public void test1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        People people = applicationContext.getBean("people",People.class);
        people.getCat().shout();
        people.getDog().shout();
    }
}

结果

miao~
wang~

3.2 基于Annotation(Spring4后,要依赖aop包)

注解说明
-@Component:可以放在所有类上,说明这个类被Spring容器管理了
    衍生注解
    -@Repository:Dao层
    -@Service:Service层
    -@Controller:Servlet层


自动装配 
-@Autowired:自动装配 默认byType 
    如果Autowired不能唯一自动装配属性,则需要@Qualifier(value=""")
-@Resource:自动装配 默认先byName后byType
1.属性注入 @Value
// 等价<bean id="user" class="com.kk.po.User"/>
@Component("user")
public class User {
//    相当于<property name="name" value="wkx"/>

    public String name;
    @Value("wkx")
    public void setName(String name) {
        this.name = name;
    }
}
2.自动装配
  • @Autowired 先byType
@Data
public class People {
    private String name;
    @Autowired
    private Cat cat;
    @Autowired
    private Dog dog;
}

<?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 https://www.springframework.org/schema/context/spring-context.xsd">
<!--    1.指定要扫描的包,这个包下的注解即生效-->
    <context:component-scan base-package="com.kk"/>
<!--    2.开启属性注解支持-->
    <context:annotation-config/>
 <!--   3.配置Bean-->
    <bean class="com.kk.po.People" id="people"/>
    <bean id="cat" class="com.kk.po.Cat"/>
    <bean id="dog" class="com.kk.po.Dog"/>
</beans>
  • @Qualifier配合@Autowired
    @Data
    public class People {
        private String name;
        //@Autowired直接在属性或者set方法上
        @Autowired
        @Qualifier(value="cat222")
        private Cat cat;
        @Autowired
        @Qualifier(value="dog222")
        private Dog dog;
    }
    
    <?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 https://www.springframework.org/schema/context/spring-context.xsd">
    <!--    1.指定要扫描的包,这个包下的注解即生效-->
        <context:component-scan base-package="com.kk"/>
    <!--    2.开启属性注解支持-->
        <context:annotation-config/>
     <!--   3.配置Bean-->
        <bean class="com.kk.po.People" id="people"/>
        <bean id="cat222" class="com.kk.po.Cat"/>
        <bean id="dog222" class="com.kk.po.Dog"/>
    </beans>
    
  • @Resource 先byName后byType
    public class People {
        private String name;
        //@Autowired直接在属性或者set方法上
        @Resource
        //name值等于bean上装配的id值
        private Cat cat;
        @Resource(name="dog222")
        private Dog dog;
    }
    
    <?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 https://www.springframework.org/schema/context/spring-context.xsd">
    <!--    1.指定要扫描的包,这个包下的注解即生效-->
        <context:component-scan base-package="com.kk"/>
    <!--    2.开启属性注解支持-->
        <context:annotation-config/>
     <!--   3.配置Bean-->
        <bean class="com.kk.po.People" id="people"/>
        <bean id="cat222" class="com.kk.po.Cat"/>
        <bean id="dog222" class="com.kk.po.Dog"/>
    </beans>
    
  • 测试

    public class MyTest {
        @Test
        public void test1(){
            ApplicationContext applicationContext = new 	ClassPathXmlApplicationContext("applicationContext.xml");
            People people = applicationContext.getBean("people",People.class);
            people.getCat().shout();
            people.getDog().shout();
        }
    }
    

    @Autowired 和 @Resource 的区别

    • 都是用来自动装配的,可以放在属性字段上或set方法上

    • @Autowired先通过byType,后byName

    • @Resource反之

3、作用域 @Scope
@Component("user")
@Scope("prototype")
public class User {
//    相当于<property name="name" value="wkx"/>
    public String name;
    @Value("wkx")
    public void setName(String name) {
        this.name = name;
    }
}
xml与Annotation
  • xml更加万能,适用任何场景,维护简单方便
  • 维护相对复杂
最佳实践
  • xml用来管理bean
  • 注解只负责完成属性的注入
  • 注解生效

4、AOP

4.1代理模式(SpringAOP底层)

好处:

  • 可以使真实角色的操作更加纯粹

  • 公共业务交给代理角色 实现业务分工

  • 公共业务发生拓展时,方便集中管理

缺点:

  • 一个真实的代理角色会产生一个代理角色;代码量翻倍,开发效率降低

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bsuKhumq-1625567032574)(D:\桌面文件夹\1.png)]

分类

4.2 静态代理

角色分析:

​ 抽象角色:租房

public interface Rent {
    public void rent();
}

​ 真实角色:房东

public class Host implements Rent {
    public void rent() {
        System.out.println("房东要出租房子");
    }
}

​ 代理角色:中介

public class Proxy implements Rent{
    private Host host;

    public Proxy() {
    }

    public Proxy(Host host) {
        this.host = host;
    }

    public void rent() {
        host.rent();
    }
    //看房
    public void seeHouse(){
        System.out.println("看房");
    }
    //签租赁合同
    public void contact(){
        System.out.println("签合同");
    }
}

​ 被代理角色:租客

public class Client {
    public static void main(String[] args) {
        Host host = new Host();
        //host.rent();
//        代理模式
        Proxy proxy = new Proxy(host);
        //租客直接找中介租房即可,无需通过房东
        proxy.rent();
    }
}
public class MyTest {
    //@Test
    public void t1(){
        Proxy proxy = new Proxy(new Host());
        proxy.rent();
    }
}

4.3 动态代理

  • 动态代理和静态代理角色一样

  • 动态代理的代理类时动态生成的,不是直接写好的

  • 实现方式:基于接口的JDK动态代理,基于CGLIB类的动态代理

    • 基于接口—JDK代理 InvocationHandler&&Proxy

    • 基于类—CGLIB

    • java字节码 javassist

//用这个类,自动生成代理类
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);
    }
    //处理代理实例,并返回结果
    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+"方法");
    }
}
public class Client {
    public static void main(String[] args) {
       //真实角色
        UserService userService = new UserServiceImpl();
        //代理角色,不存在
        ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler();
        //设置要代理的对象
        proxyInvocationHandler.setTarget(userService);
        //动态生成代理类
        UserService proxy = (UserService) proxyInvocationHandler.getProxy();
        proxy.add();
    }
}

动态代理的好处:

  • 一个动态代理可以代理多个类,代理的是接口

4.4 AOP的实现

4.4.1使用SPring实现

【重点】使用AOP织入,需要导入一个依赖包

<dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
</dependency>

自定义类来实现AOP

声明一个UserService接口、一个实现类、一个自定义切面类

public interface UserService {
    void add();
    void delete();
    void update();
    void select();
}
public class UserServiceImpl implements UserService{
    public void add() {
        System.out.println("增加了一个用户");
    }

    public void delete() {
        System.out.println("删除了一个用户");
    }

    public void update() {
        System.out.println("更新了一个用户");
    }

    public void select() {
        System.out.println("查询了一个用户");
    }
}
//自定义切面
public class Log  {
    //通知
    public void log(){
        System.out.println("输出日志");
    }
    public void after(){
        System.out.println("方法执行后");
    }
}

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
       https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--   1 注册Bean-->
    <bean id="userService" class="com.kk.service.UserServiceImpl"/>
    <bean id="log" class="com.kk.log.Log"/>
<!--   2 配置AOP-->
    <aop:config>
<!--       2.1 自定义切面类-->
        <aop:aspect  ref="log">
<!--       2.2 切入点 -->
            <aop:pointcut id="pointcut" expression="execution(* com.kk.service.UserServiceImpl.*(..))"/>
<!--       2.3通知-->
            <aop:before method="log" pointcut-ref="pointcut"/>
            <aop:after-returning method="after" pointcut-ref="pointcut"/>
        </aop:aspect>
    </aop:config>
</beans>

使用注解实现

@Aspect
public class AnnotationAspect {
   @Before("execution(* com.kk.service.UserServiceImpl.*(..))")
    public void before(){
        System.out.println("方法执行前");
    }
    @After("execution(* com.kk.service.UserServiceImpl.*(..))")
    public void After(){
        System.out.println("方法执行后");
    }
    @Around("execution(* com.kk.service.UserServiceImpl.*(..))")
    //在环绕增强中,我们可以给定一个参数,代表我们要获取处理切入的点
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕前");
        joinPoint.proceed();//执行方法
        System.out.println("环绕后");
    }
}
@Service("userService")

public class UserServiceImpl implements UserService{
    public void add() {
        System.out.println("增加了一个用户");
    }

    public void delete() {
        System.out.println("删除了一个用户");
    }

    public void update() {
        System.out.println("更新了一个用户");
    }

    public void select() {
        System.out.println("查询了一个用户");
    }
}
@Service
public interface UserService {
    void add();
    void delete();
    void update();
    void select();
}
public class MyTest {
    @Test
    public void test2(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext1.xml");
        UserService userService = applicationContext.getBean("userService",UserService.class);
        userService.delete();
    }
}

5、Spring整合MyBatis

5.1 MyBatis步骤

  • 整合包(Maven Repository)
    • junit
    • mysql-connector
    • mybatis
    • spring-webmvc
    • spring-jdbc
    • 【aop织入】aspectjweaver
    • mybatis-spring
  • 编写配置文件
  • 测试

5.2 MyBatis-Spring

MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapper 和 SqlSession 并注入到 bean 中,以及将 Mybatis 的异常转换为 Spring 的 DataAccessException。 最终,可以做到应用代码不依赖于 MyBatis,Spring 或 MyBatis-Spring。

要和 Spring 一起使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:一个 SqlSessionFactory 和至少一个数据映射器类。

5.3 整合实现

5.3.1基于MapperFactoryBean(sqlSessionTemplate)
  • 编写数据源配置

    <!-- DataSource:使用Spring的数据源替换MyBatis的配置,c3p0,Druid,dbcp-->
        <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"/>
            <property name="username" value="root"/>
            <property name="password" value="123456"/>
        </bean>
    
  • sqlSessionFactory

    <!--    sqlSessionFactory-->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
    <!--        指定mybatis配置文件-->
            <property name="configLocation" value="classpath:mybatis-config.xml"/>
    <!--        指定mapper文件-->
            <property name="mapperLocations" value="classpath:com/kk/dao/*.xml"/>
        </bean>
    
  • sqlSessionTemplate

       <bean id="Template" class="org.mybatis.spring.SqlSessionTemplate">
    <!--        只能用构造器注入,无set方法-->
            <constructor-arg index="0" ref="sqlSessionFactory"/>
       </bean>
    
  • 添加事务管理器

     <!--配置mybatis工厂  sqlSessionFactory-->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
    <!--        指定mybatis配置文件-->
            <property name="configLocation" value="classpath:mybatis-config.xml"/>
    <!--        指定mapper文件-->
            <property name="mapperLocations" value="classpath:com/kk/dao/*.xml"/>
        </bean>
    
  • 给接口添加实现类

    public class UserMapperImpl implements  UserMapper {
        //mybatis时,我们使用sqlSession来执行增删改查等方法,整合以后,使用SqlSessionTemplate
        private SqlSessionTemplate sqlSession;
    
        public void setSqlSession(SqlSessionTemplate sqlSession) {
            this.sqlSession = sqlSession;
        }
    
        public User getUserById(int id) {
              UserMapper mapper = sqlSession.getMapper(UserMapper.class);
              return mapper.getUserById(id);
        }
    }
    
  • 将自己写的实现类注入Spring容器中()

    <bean id="userMapper" class="com.kk.dao.UserMapperImpl">
            <property name="sqlSession" ref="Template"/>
    </bean>
    
  • 测试

    public class MyTest {
        @Test
        public void test1(){
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserMapper userMapper = applicationContext.getBean("userMapper",UserMapper.class);
            System.out.println( userMapper.getUserById(2));
            }
        }
    
5.3.2基于MapperScannerConfigurer

基于以上,删除配置UserMapperImpl.java文件,且删除userMapper Bean的配置,替换成以下这个

 <!-- 6 使用mapper代理开发(基于MapperScannerConfigurer) 无需自己手动配置mapper,自动通过包中的接口扫描,找到映射器Mapper.xml -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.kk.dao"/>
    </bean>

条件:

  • Mapper接口名称和对应Mapper.xml映射文件名称一致
  • Mapper.xml中namespace与Mapper接口类路径一致,即接口文件和映射文件在同一包下
  • Mapper接口中的方法输入、输出参数类型与Mapper.xml中一致
5.3.3 基于SqlSessionDaoSupport(由其自带的getSession获取SqlSession对象)
  • UserServiceImpl.java
public class UserServiceImpl extends SqlSessionDaoSupport implements UserService {

    public List<User> getUserList() {
        return getSqlSession().getMapper(UserMapper.class).getUserList();
    }
}
  • 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: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 https://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 1 读取db.properties文件 -->
    <context:property-placeholder location="classpath:db.properties"/>
    <!-- 2 配置数据源DataSource:使用Spring的数据源替换MyBatis的配置,c3p0,Druid,dbcp-->
    <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>
    <!--3 装配SqlSessionFactory-->
    <bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--读取mybatis配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>
    <!-- 4 装配SqlSession-->
    <bean id="SqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="SqlSessionFactory"/>
    </bean>
    <!--5 自动装配Mapper-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.kk.dao"/>
    </bean>
    <!--6 装配Bean-->
    <bean class="com.kk.service.UserServiceImpl" id="userService">
        <property name="sqlSessionFactory" ref="SqlSessionFactory"/>
    </bean>
</beans>

6、Spring中的事务管理

一组事务中,如果在没配置事务管理时,有一个方法可以正确执行时,则会更新数据库;如果加入了事务管理,必须满足ACID原则,要么全做,要么全不做。

一个使用 MyBatis-Spring 的其中一个主要原因是它允许 MyBatis 参与到 Spring 的事务管理中。

6.1编程式事务(略)

6.2声明式事务(AOP)

开启 Spring 的事务处理功能,在 Spring 的配置文件中创建一个 DataSourceTransactionManager 对象:

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <constructor-arg ref="dataSource" />
</bean>

**注意:**为事务管理器指定的 DataSource 必须和用来创建 SqlSessionFactoryBean 的是同一个数据源,否则事务管理器就无法工作了。

交由容器管理事务 结合使用AOP(在不改变源代码,横向织入)

<?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:tx="http://www.springframework.org/schema/tx" 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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--开启注解-->
    <context:annotation-config/>
    <context:component-scan base-package="com.kk"/>
    <!-- 1 读取db.properties文件 -->
    <context:property-placeholder location="classpath:db.properties"/>
    <!-- 2 配置数据源DataSource:使用Spring的数据源替换MyBatis的配置,c3p0,Druid,dbcp-->
    <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>
    <!--3 装配SqlSessionFactory-->
    <bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--读取mybatis配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>
    <!-- 4 装配SqlSession-->
    <bean id="SqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="SqlSessionFactory"/>
    </bean>
    <!--5 自动装配Mapper-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.kk.dao"/>
    </bean>
    <bean class="com.kk.service.UserServiceImpl" id="userService">
        <property name="sqlSessionFactory" ref="SqlSessionFactory"/>
    </bean>
    
    <!--6 配置声明式事务-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <constructor-arg ref="dataSource" />
    </bean>
        <!--6.1结合AOP实现事务织入-->
        <!--6.2配置事务通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <!--6.3给哪些方法配置事务-->
        <!--6.4 配置事务传播特性 propagation默认REQUIRED,可以不写-->
        <tx:attributes>
            <tx:method name="add" propagation="REQUIRED"/>
            <tx:method name="delete" propagation="REQUIRED"/>
            <tx:method name="update" propagation="REQUIRED"/>
            <tx:method name="query" read-only="true"/>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
     <!--7 配置事务切入-->
    <aop:config>
        <!--7.1切入点-->
        <aop:pointcut id="pointCut" expression="execution(* com.kk.service.*.*(..))"/>
        <!--7.2切面:将切入点和通知整合-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
    </aop:config>
</beans>

7、未完待续(思路不太清晰)、、、主要用于复习

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值