spring

Dapeng 2022-08-06 13:34:33 阅读数:504

spring

Spring 简介

Spring框架是由于软件开发的复杂性而创建的.Spring使用的是基本的JavaBean来完成以前只可能由 EJB 框架完成的事情.然而,Spring的用途不仅仅限于服务器端的开发.从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益.

历史 :

  • 2002 年首次推出了 Spring 的雏形 – interface21框架!
  • Spring 框架以 interface21 框架为基础,经过重新设计,并不断丰富其内涵,在2004年3月24日,发布了1.0正式版

Spring框架的创始人 – Rod Johnson

Rod在悉尼大学不仅获得了计算机学位,同时还获得了音乐学位.

Spring Frameworks make existing technologies easier to use,整合了现有的技术框架

优点

  • Spring是一个开源免费的框架
  • Spring 是一个轻量级的框架
  • 控制反转(IOC)和 面向切面编程(AOP)
  • 支持事务的处理,spring提供了统一的事务管理接口,无需手动编程.
  • Support for integrating other types of frameworks (如:Struts、Hibernate、MyBatis).
  • 异常处理:SpringProvides a unified mechanism for handling exceptions.

Spring 的组成

在这里插入图片描述

需要用到的maven依赖

<!-- spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.9</version>
</dependency>

IOC 的本质

之前的 实例化 dao 接口

private UserDao userDao = new UserDaoImpl();

instantiation now dao 接口

private UserDao userDao ;
//使用 set Instantiate by way of injectiondao接口
public void setUserDao(UserDao userDao) {

this.userDao = userDao;
}

Before the program actively created the object,控制权在程序员手上;现在使用了 set After injection,程序不在具有主动性,而是变成了被动的接受对象!

这种思想,从本质上解决了问题,Programmers no longer need to manage the creation of objects.The coupling of the system is greatly reduced,You can focus more on the implementation of business code!这就是 IOC 的原型.

编写第一个 Spring 程序

1、导入 maven 依赖

<!-- spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.9</version>
</dependency>

2、创建实体类

package com.hkp.entity;
public class User {

private Integer id;
private String name;
private Integer age;
//生成对应的 get、set、toString 方法
}

3、在 resources 文件夹中创建 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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 使用 Spring 来创建对象,在Spring objects are called bean. Equivalent to before new 出一个对象 User user = new User(); 该id属性是一个字符串,用于标识单个 bean 定义. 相当于 user 该class属性定义 bean 的类型并使用完全限定的类名. 相当于 User() <property name="id" value="1"/> 相当于调用 set 方法 nameProperties are property names in an object,value 是 The value given to this property,ref 引用 Spring 容器中已经创建好的对象 -->
<bean id="user" class="com.hkp.entity.User">
<property name="id" value="1"/>
<property name="name" value="admin"/>
<property name="age" value="21"/>
</bean>
</beans>

4、创建测试类

public static void main(String[] args) {

//家在配置文件,实例化一个容器,获取Spring的上下文对象,参数可以有多个(可以加载多个配置文件)
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//我们的对象现在都在 Spring 容器中管理,如果要使用,Just take it out of it
//从 Spring 容器中取对象 ,参数为 对象名 -- 就是 applicationContext.xml 文件中 bean 标签中的 name 属性
User user = (User) context.getBean("user");
System.out.println(user.toString());
//输出结果 :User{id=1, name='admin', age=21}
}

思考问题 :

1、谁创建的对象? --Spring 创建的

2、对象的属性是怎么设置的? --property is there Spring 容器设置的

这个过程就叫控制反转.

控制 :谁来控制对象的创建?传统的应用程序的对象是由程序本身控制创建的(new出一个对象),使用 Spring 后,对象是由 Spring 来创建的.

反转 :程序本身不创建对象,而是被动的接收对象.

依赖注入 :就是利用 set 方法进行注入.

IOC 是一种编程思想,由主动的编程变成被动的接收.

现在,要实现的操作,We don't have to make changes to the program at all.只需要在 xml 配置文件中进行修改.

所谓的 IOC 就是一句话 :对象由 Spring 来创建、管理、装配.

IOC 创建对象的方式

1、默认使用 无参构造器 创建对象,默认的方式

<bean id="user" class="com.hkp.entity.User">
<property name="id" value="1"/>
<property name="name" value="admin"/>
<property name="age" value="21"/>
</bean>

2、使用有参构造器创建对象,

  • 通过下标赋值,The order of the subscripts is the order of the parameters,不能颠倒顺序

  • <bean id="user" class="com.hkp.entity.User">
    <constructor-arg index="0" value="1"/>
    <constructor-arg index="1" value="admin"/>
    <constructor-arg index="2" value="21"/>
    </bean>
    
  • 通过参数名赋值(Similar to a no-argument constructor)

  • <bean id="user" class="com.hkp.entity.User">
    <constructor-arg name="id" value="1"/>
    <constructor-arg name="name" value="admin"/>
    <constructor-arg name="age" value="21"/>
    </bean>
    

总结 :在配置文件被加载的时候,容器中管理的对象(bean)就已经被初始化了.

Spring 配置

别名

方式一 :使用 alias 标签定义

<!-- nameThe value in the property is the object that has been created(已经配置好的 bean 中的 name 属性的值) alias 是别名 这样的话,在getBean 的时候,The object can be created using that name -->
<alias name="user" alias="newUser"/>
//实例化一个容器,获取Spring的上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
User user2 = (User) context.getBean("newUser");
System.out.println(user.getName().equals(user2.getName()));//true

方式二 :使用 bean 标签定义

<!-- id : bean 的唯一标识符,相当于对象名 class :类的全限定名 :包名+类名 name :The alias given to this object,多个别名可用 逗号、空格、分号 隔开 -->
<bean id="user" class="com.hkp.entity.User" name="user2,user3 user4;user5">
<property name="id" value="1"/>
<property name="name" value="admin"/>
<property name="age" value="21"/>
</bean>

import

This tag is for team development use,他可以将多个配置文件,导入合并为一个.

Configurations in multiple configuration files have the same configuration,When called, one will be randomly selected for use

案例

1、在 resources 文件夹中创建 beans.xml 、beans2.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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 使用 Spring 来创建对象,在Spring objects are called bean. Equivalent to before new 出一个对象 User user = new User(); 该id属性是一个字符串,用于标识单个 bean 定义. 相当于 user 该class属性定义 bean 的类型并使用完全限定的类名. 相当于 User() <property name="id" value="1"/> 相当于调用 set 方法 nameProperties are property names in an object,value 是 The value given to this property,ref 引用 Spring 容器中已经创建好的对象 -->
<!-- id : bean 的唯一标识符,相当于对象名 class :类的全限定名 :包名+类名 name :The alias given to this object,多个别名可用 逗号、空格、分号 隔开 -->
<bean id="user" class="com.hkp.entity.User" name="user2,user3 user4;user5">
<property name="id" value="1"/>
<property name="name" value="admin"/>
<property name="age" value="21"/>
</bean>
</beans>

2、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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 引入外部配置 -->
<import resource="beans.xml"/>
<import resource="beans2.xml"/>
</beans>

3、测试

public static void main(String[] args) {

//实例化一个容器,获取Spring的上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//我们的对象现在都在 Spring 容器中管理,如果要使用,Just take it out of it
//从 Spring 容器中取对象 ,参数为 对象名 -- 就是 applicationContext.xml 文件中 bean 标签中的 name 属性
User user = (User) context.getBean("user");
System.out.println(user.toString());
//输出结果 :User{id=1, name='admin', age=21}
}

DI 依赖注入

依赖 :bean 对象的创建依赖于容器

注入 :bean 对象中的所有属性,由容器来注入

DI There are two main variants:基于构造函数的依赖注入和基于 Setter 的依赖注入.

通过 构造函数 注入

在 IOC The way to create objects has already been discussed.

  • 通过下标赋值,The order of the subscripts is the order of the parameters,不能颠倒顺序

  • <bean id="user" class="com.hkp.entity.User">
    <constructor-arg index="0" value="1"/>
    <constructor-arg index="1" value="admin"/>
    <constructor-arg index="2" value="21"/>
    </bean>
    
  • 通过参数名赋值(Similar to a no-argument constructor)

  • <bean id="user" class="com.hkp.entity.User">
    <constructor-arg name="id" value="1"/>
    <constructor-arg name="name" value="admin"/>
    <constructor-arg name="age" value="21"/>
    </bean>
    

通过 set 方法 注入

案例 :

1、创建实体类

The real test entity class

public class User {

private String name;
private Address address;
private String[] books;
private List<String> hobbies;
private Map<String,String> score;
private Set<String> games;
private String testNull;
private String testKong;
private Properties pro;
//对应的 get、set和 toString 方法
}

Entity class of a reference type

package com.hkp.entity;
public class Address {

private String address;
//对应的 get、set和 toString 方法
}

配置 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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 创建一个 address 对象 -->
<bean id="address" class="com.hkp.entity.Address">
<property name="address" value="北京市"/>
</bean>
<!-- 创建一个 User 对象,并对其属性赋值 -->
<bean id="user" class="com.hkp.entity.User">
<!-- 普通类型注入 : value属性 -->
<property name="name" value="admin"/>
<!-- 引用类型注入 : ref属性 -->
<property name="address" ref="address"/>
<!-- 数组类型注入 : array value标签 -->
<property name="books">
<array>
<value>水浒传</value>
<value>西游记</value>
<value>红楼梦</value>
<value>三国演义</value>
</array>
</property>
<!-- list集合注入-->
<property name="hobbies">
<list>
<value>听歌</value>
<value>读书</value>
<value>敲代码</value>
</list>
</property>
<!-- map集合注入 -->
<property name="score">
<map>
<entry key="语文" value="96"/>
<entry key="数学" value="99"/>
<entry key="英语" value="90"/>
</map>
</property>
<!-- set集合注入 -->
<property name="games">
<set>
<value>LOL</value>
<value>BOB</value>
<value>吃鸡</value>
</set>
</property>
<!-- 设置值为 null -->
<property name="testNull">
<null/>
</property>
<!-- 设置值为 空字符串 -->
<property name="testKong" value=""/>
<!-- properties -->
<property name="pro">
<props>
<prop key="学号">20210210</prop>
<prop key="姓名">admin</prop>
<prop key="性别"></prop>
</props>
</property>
</bean>
</beans>

测试

public static void main(String[] args) {

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
System.out.println(user.toString());
/* * User{ * name='admin', * address=Address{address='北京市'}, * books=[水浒传, 西游记, 红楼梦, 三国演义], * hobbies=[听歌, 读书, 敲代码], * score={语文=96, 数学=99, 英语=90}, * games=[LOL, BOB, 吃鸡], * testNull='null', * testKong='', * pro={学号=20210210, 性别=男, 姓名=admin} * } * */
}

拓展注入方式

p 命名空间

在 applicationContext.xml 文件中添加

xmlns:p="http://www.springframework.org/schema/p"

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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- p 命名空间,You can inject values ​​directly into properties,属性-ref This represents all other references to this propertybean对象 -->
<bean id="user" class="com.hkp.entity.User" p:id="1" p:age="21" p:name="admin" p:address-ref="address"/>
<bean id="address" class="com.hkp.entity.Address">
<property name="address" value="北京市"/>
</bean>
</beans>

c 命名空间

在 applicationContext.xml 文件中添加

xmlns:c="http://www.springframework.org/schema/c"

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:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- p 命名空间,Inject values ​​to properties through the parameterized constructor,属性-ref This represents all other references to this propertybean对象 -->
<bean id="user2" class="com.hkp.entity.User" c:id="1" c:age="21" c:name="admin" c:address-ref="address"/>
<bean id="address" class="com.hkp.entity.Address">
<property name="address" value="北京市"/>
</bean>
</beans>

bean 的作用域

单例模式

是 Spring 的默认机制

<!-- scope="singleton" Indicates that the entity is set to generate a singleton mode -->
<bean id="user" class="com.hkp.entity.User" scope="singleton"/>

在 调用的时候,Calling it twice at the same time returns the same result,It shows that it is called twicebean 是同一个 bean

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
User user2 = (User) context.getBean("user");
System.out.println(user==user2);//true
System.out.println(user.hashCode());//827966648
System.out.println(user2.hashCode());//827966648

原型模式

每次从容器中 getBean 的时候都会产生一个新对象

<!-- scope="prototype" Indicates that the entity is set to prototype mode -->
<bean id="user" class="com.hkp.entity.User" scope="prototype"/>

在 调用的时候,The results returned by two simultaneous calls are not the same,It shows that it is called twicebean 不是同一个 bean

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
User user2 = (User) context.getBean("user");
System.out.println(user==user2);//false
System.out.println(user.hashCode());//1164371389
System.out.println(user2.hashCode());//517210187

the rest of the scope request、session、application 等都是 web 的时候才能用到

bean 的自动装配

自动装配是 Spring 满足 bean 依赖的一种方式,Spring 会在上下文中自动寻找,并自动给 bean 装配属性!

Spring 中有三种装配方式 :

  1. 在 xml 中显示装配
  2. 在 Java 中显示装配
  3. Implicit auto-assignment bean 【重点】

环境搭建

  • 实体类

    //cat
    public class Cat {
    
    public void shout(){
    
    System.out.println("miao~");
    }
    }
    //dog
    public class Dog {
    
    public void shout(){
    
    System.out.println("wang~");
    }
    }
    //People
    public class People {
    
    private Cat cat;
    private Dog dog;
    private String name;
    //对应的 get、set 方法
    }
    
  • 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 https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="dog" class="com.hkp.entity.Dog"/>
    <bean id="cat" class="com.hkp.entity.Cat"/>
    <bean id="people" class="com.hkp.entity.People">
    <property name="name" value="test"/>
    <property name="dog" ref="dog"/>
    <property name="cat" ref="cat"/>
    </bean>
    </beans>
    
  • 测试类

    public static void main(String[] args) {
    
    ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
    People people = context.getBean("people", People.class);
    people.getDog().shout();
    people.getCat().shout();
    }
    

自动装配-- byName

<?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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.hkp.entity.Dog"/>
<bean id="cat" class="com.hkp.entity.Cat"/>
<!-- byName : will be automatically looked up in context,查询 people 实体中的属性(要有对应的 set 方法)corresponding to the name bean id byType : will be automatically looked up in context,查询 people Corresponds to the attribute type in the entity bean ,此时 bean It is not necessary to write in the label id属性 -->
<bean id="people" class="com.hkp.entity.People" autowire="byName">
<property name="name" value="test"/>
</bean>
</beans>

自动装配-- byType

<?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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dog" class="com.hkp.entity.Dog"/>
<bean id="cat" class="com.hkp.entity.Cat"/>
<!-- byName : will be automatically looked up in context,查询 people 实体中的属性(要有对应的 set 方法)corresponding to the name bean id byType : will be automatically looked up in context,查询 people Corresponds to the attribute type in the entity bean ,此时 bean It is not necessary to write in the label id属性 -->
<bean id="people" class="com.hkp.entity.People" autowire="byType">
<property name="name" value="test"/>
</bean>
</beans>

小结 :

  • byName : 需要保证所有 bean 中 id 的唯一性,并且这个beanto and in the entity set 方法的值一致
  • byType : 需要保证所有 bean 中 class 的唯一性,并且这个beanto and in the entity 属性的类型一致

使用注解实现自动装配

jdk 从1.5开始支持注解,Spring 从 2.5 开始支持注解

1、导入约束

xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd"

2、在 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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解支持 -->
<context:annotation-config/>
<bean id="dog" class="com.hkp.entity.Dog"/>
<bean id="cat" class="com.hkp.entity.Cat"/>
<bean id="people" class="com.hkp.entity.People">
<property name="name" value="test"/>
</bean>
</beans>

People Changes in the entity

public class People {

@Autowired
@Qualifier(value = "cat1")
private Cat cat;
@Autowired
private Dog dog;
private String name;
//对应的 get 的方法
}

@Autowired

import org.springframework.beans.factory.annotation.Autowired;

The annotation can be added directly to the property or set 方法上;使用该注解时,Entity classes can be omitted set 方法

@Qualifier(value = “cat1”)

import org.springframework.beans.factory.annotation.Qualifier;

This annotation is used on an object applicationContext.xml There are more than one configured in the configuration filebean,At this point, the automatic injection does not know which one to choose,In this case, use this annotation to specify one bean 即可.value 的参数值为 bean 标签中的 id 值

@Resource

import javax.annotation.Resource;
public class People {

@Resource
private Cat cat;
@Resource
private Dog dog;
private String name;
//对应的 get 方法
}

The role of this annotation can be [email protected]Autowired@Qualifier(value = “cat1”) 他们两个,And if no parameters are [email protected]Autowired 类似. 如果一个对象在 application.xml There are more than one configured in the configuration filebean,此时直接使用 @Resource Automatic injection doesn't know which one to choose,In this case, add a parameter after the annotation @Resource(name = “”) 指定一个 bean 即可.name 的值为 bean 标签中的 id 值

@Autowired 和 @Resource 的区别 :

  • 都是自动装配,Can be placed on properties and methods
  • @Autowired 是通过 byType 的方式实现的,而且必须要求这个对象存在
  • @Resource 是通过 byName 的方式实现的,If the corresponding name is not found, it will pass byType 的方式实现

使用注解开发

在 Spring4 之后 要使用注解开发,需要导入 aop 包

在这里插入图片描述

在 applicationContext.xml Support for configuration annotations in configuration files

<?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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描包中的注解,这个包下的注解就会生效 -->
<context:component-scan base-package="com.hkp"/>
</beans>

@Component

import org.springframework.stereotype.Component;

组件,用在实体类上,等价于在xml文件中 ,idProperties default to all lowercase

1、创建实体类

@Component //组件,等价于在xml文件中<bean id="user" class="com.hkp.entity.User"/>,idProperties default to all lowercase
public class User {

public String name="Hello World!!!";
}

2、编写测试

public static void main(String[] args) {

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = context.getBean("user", User.class);
System.out.println(user.name);
}

@Value

import org.springframework.beans.factory.annotation.Value;

给属性设置默认值,相等于

1、编写实体类

@Component //组件,等价于在xml文件中<bean id="user" class="com.hkp.entity.User"/>
public class User {

//给属性默认值,相等于<property name="name" value="Hello World!!!"/>
@Value("Hello World!!!")
public String name;
}

2、编写测试

public static void main(String[] args) {

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = context.getBean("user", User.class);
System.out.println(user.name);
}

衍生的注解

@Component There are several derived annotations,These annotations have the same effect,are used to annotate classes into bean 的,But the level used is different

  • dao

    import org.springframework.stereotype.Repository;
    @Repository
    
  • service

    import org.springframework.stereotype.Service;
    @Service
    
  • controller

    import org.springframework.stereotype.Controller;
    @Controller
    

小结 :

@Component 实体类

@Repository 持久层

@Service 业务层

@Controller 控制层

自动装配

@Autowired

import org.springframework.beans.factory.annotation.Autowired;

The annotation can be added directly to the property or set 方法上;使用该注解时,Entity classes can be omitted set 方法

@Qualifier(value = “cat1”)

import org.springframework.beans.factory.annotation.Qualifier;

This annotation is used on an object applicationContext.xml There are more than one configured in the configuration filebean,At this point, the automatic injection does not know which one to choose,In this case, use this annotation to specify one bean 即可.value 的参数值为 bean 标签中的 id 值

@Resource

import javax.annotation.Resource;
public class People {

@Resource
private Cat cat;
@Resource
private Dog dog;
private String name;
//对应的 get 方法
}

The role of this annotation can be [email protected]Autowired@Qualifier(value = “cat1”) 他们两个,And if no parameters are [email protected]Autowired 类似. 如果一个对象在 application.xml There are more than one configured in the configuration filebean,此时直接使用 @Resource Automatic injection doesn't know which one to choose,In this case, add a parameter after the annotation @Resource(name = “”) 指定一个 bean 即可.name 的值为 bean 标签中的 id 值

@Autowired 和 @Resource 的区别 :

  • 都是自动装配,Can be placed on properties and methods
  • @Autowired 是通过 byType 的方式实现的,而且必须要求这个对象存在
  • @Resource 是通过 byName 的方式实现的,If the corresponding name is not found, it will pass byType 的方式实现

bean的作用域

import org.springframework.context.annotation.Scope;
@Component //组件,等价于在xml文件中<bean id="user" class="com.hkp.entity.User"/>
@Scope("singleton")
//@Scope("singleton") Indicates that the entity is set to generate a singleton mode,Spring的默认模式
//@Scope("prototype") Indicates that the entity is set to prototype mode,每次从容器中 getBean 的时候都会产生一个新对象
public class User {

//给属性默认值,相等于<property name="name" value="Hello World!!!"/>
@Value("Hello World!!!")
public String name;
}

使用 Java 的方式 配置 spring

可以不使用 xml 来配置 Spring 了,

1、创建实体

package com.hkp.entity;
import org.springframework.beans.factory.annotation.Value;
public class User {

@Value("hello")
private String name;
//get、set方法
}

2、创建配置文件

package com.hkp.config;
import com.hkp.entity.User;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
@Configurable //等同于 applicationContext.xml 文件中的 <beans></beans>标签
@Import(MyConfig2.class)//引入外部配置文件,等价于<import resource="beans.xml"/>
public class MyConfig {

/** * 注册一个bean,等价于在xml文件中<bean id="user" class="com.hkp.entity.User"/> * The method name in the method is equivalent to bean 标签中的id属性 * The return value in the method is equivalent to bean 标签中的 class 属性 * @return */
@Bean
public User getUser(){

return new User();
}
}

3、创建测试

import com.hkp.config.MyConfig;
import com.hkp.entity.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestDemo {

public static void main(String[] args) {

//如果使用了配置类方式去做,我们就只能通过AnnotationConfigApplicationContext 来获取容器
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User user = (User) context.getBean("getUser");
System.out.println(user.getName());
}
}

代理模式

代理模式是SpringAOP的底层

代理模式的分类 :

  • 静态代理
  • 动态代理

静态代理

代理模式的好处 :

  • But the real character operation is more pure,Don't focus on other businesses
  • 公共业务发生拓展的时候,方便集中管理

缺点 :

  • A real character has an agent – 代码臃肿

以一个 The case of renting :

1、编写接口

public interface Rent {

void rent();
}

2、真实角色(房东)

public class Host implements Rent{

public void rent(){

System.out.println("房主要出租房子");
}
}

3、代理

public class Proxy implements Rent{

//出租房间
@Override
public void rent() {

look();
System.out.println("Authorize the agency to publish room rentals");
free();
}
//收中介费
public void free(){

System.out.println("收中介费");
}
//看房子
public void look(){

System.out.println("看房子");
}
}

4、客户端访问代理角色

public class Client {

public static void main(String[] args) {

Proxy proxy = new Proxy();
proxy.rent();
}
}

动态代理

动态代理的代理类是动态生成的,不是我们直接写好的

动态代理分为两类 :

  • 基于接口的动态代理 :JDK 动态代理(常用)
  • 基于类的动态代理 :cglib
  • Java 字节码 :javasist

JDK The class that dynamic proxy needs to use :Proxy :代理、InvocationHandler :调用处理程序(里面只有一个方法 invoke )

案例

1、编写接口

public interface Rent {

void rent();
}

2、真实角色(房东)

public class Host implements Rent{

public void rent(){

System.out.println("房主要出租房子");
}
}

3、动态生成代理类

package com.hkp.demo1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//用这个类,自动生成代理类
public class ProxyIn 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);
free();
return result;
}
public void seeHouse(){

System.out.println("看房子");
}
public void free(){

System.out.println("收中介费");
}
}

4、客户端访问代理角色

public class Client {

public static void main(String[] args) {

//真实角色
Host host = new Host();
//获得代理类
ProxyIn proxyIn = new ProxyIn();
proxyIn.setRent(host);
//动态生成的代理类
Rent proxy = (Rent) proxyIn.getProxy();
proxy.rent();
}
}

aop

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率.

aop在Sprin的作用

提供声明式事务,允许用户自定义切面

横切关注点 :跨越应用程序多个模块的方法或功能.i.e. has nothing to do with our business logic,但需要我们关注的部分,就是横切关注点.如日志、事务、缓存等等.

切面(ASPECT):横切关注点被模块化的特殊对象.i.e. he is a class

通知(Advice):切面必须要完成的工作.That is, he is a method in the class

目标(Target):被通知的对象

代理(Proxy):向目标对象应用通知之后创建的对象

切入点(PointCut):切面通知执行的“地点”

连接点(JoinPoint):与切入点匹配的执行点

在这里插入图片描述

Spring AOP 中,通过Advice 定义横切逻辑,Spring 中支持类型的 Advice

在这里插入图片描述

使用 Spring 实现 AOP

需要的依赖

<!-- aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>

方式一 :使用 Spring API 接口

1、创建接口

package com.hkp.service;
public interface UserService {

void add();
void delete();
void update();
void select();
}

2、创建接口实现

package com.hkp.service;
public class UserServiceImpl implements UserService{

@Override
public void add() {

System.out.println("Enter the increase method");
}
@Override
public void delete() {

System.out.println("Enter the delete method");
}
@Override
public void update() {

System.out.println("Enter the modification method");
}
@Override
public void select() {

System.out.println("Enter the query method");
}
}

3、创建日志类

//前置通知
package com.hkp.log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class BeforeLog implements MethodBeforeAdvice {

/** * 参数详解 * @param method 执行的方法 * @param objects 参数 * @param o 目标对象 * @throws Throwable */
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {

System.out.println(o.getClass().getName()+"类中的 "+method.getName()+" method is about to be executed");
}
}
//后置通知
package com.hkp.log;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterLog implements AfterReturningAdvice {

/** * * @param o 返回值 * @param method 执行的方法 * @param objects 参数 * @param o1 目标对象 * @throws Throwable */
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {

System.out.println(o1.getClass().getName()+"类中的 "+method.getName()+" 方法已经被执行");
}
}

4、配置 applicationContext.xml 文件

导入约束

xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 注册 bean -->
<bean id="userServiceImpl" class="com.hkp.service.UserServiceImpl"/>
<bean id="afterLog" class="com.hkp.log.AfterLog"/>
<bean id="beforeLog" class="com.hkp.log.BeforeLog"/>
<!-- 配置 aop -->
<aop:config>
<!--切入点-->
<!-- expression : 表达式,execution(修饰词 类名 方法名 参数) * But it means all com.hkp.service.UserServiceImpl.*(..) 表示的是 UserServiceImpl类中的所有方法 , ..Represents an arbitrary parameter -->
<aop:pointcut id="pointcut" expression="execution(* com.hkp.service.UserServiceImpl.*(..))"/>
<!-- 执行环绕 -->
<aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
</beans>

5、测试

public static void main(String[] args) {

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//动态代理的是接口
UserService userService = (UserService) context.getBean("userServiceImpl");
userService.add();
}

方式二 :自定义类

The interface and implementation class are the same as in the first method

1、编写 自定义日志类

package com.hkp.diy;
public class DiyPointCut {

public void before(){

System.out.println("执行方法前");
}
public void after(){

System.out.println("执行方法后");
}
public void around(ProceedingJoinPoint jp) throws Throwable {

System.out.println("环绕前");
jp.proceed();//执行方法
System.out.println("环绕后");
}
}

2、配置 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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 注册 bean -->
<bean id="userServiceImpl" class="com.hkp.service.UserServiceImpl"/>
<bean id="diy" class="com.hkp.diy.DiyPointCut"/>
<aop:config>
<!-- 自定义切面,ref Points to the custom aspect class to reference -->
<aop:aspect ref="diy">
<!-- 切入点 -->
<aop:pointcut id="point" expression="execution(* com.hkp.service.UserServiceImpl.*(..))"/>
<!-- 通知 -->
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
<aop:around method="around" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
</beans>

3、测试

public static void main(String[] args) {

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//动态代理的是接口
UserService userService = (UserService) context.getBean("userServiceImpl");
userService.add();
}

在这里插入图片描述

方式三 :使用注解实现 aop

The interface and implementation class are the same as in the first method

1、编写 自定义日志类

package com.hkp.diy;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect //Annotation that this class is an aspect class
public class AnnoPointCut {

//The parameter inside is the entry point
@Before("execution(* com.hkp.service.UserServiceImpl.*(..))")
public void before(){

System.out.println("执行方法前");
}
@After("execution(* com.hkp.service.UserServiceImpl.*(..))")
public void after(){

System.out.println("执行方法后");
}
}

2、配置 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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 注册 bean -->
<bean id="userServiceImpl" class="com.hkp.service.UserServiceImpl"/>
<bean id="annoPointcut" class="com.hkp.diy.AnnoPointCut"/>
<!-- 开启注解支持-->
<aop:aspectj-autoproxy/>
</beans>

3、测试

public static void main(String[] args) {

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//动态代理的是接口
UserService userService = (UserService) context.getBean("userServiceImpl");
userService.add();
}

整合 mybatis

文档 :mybatis-spring –

在这里插入图片描述

需要的 jar 依赖

<!-- spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.9</version>
</dependency>
<!--spring 操作数据库 spring-jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.9</version>
</dependency>
<!-- aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!-- junit测试单元 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<!-- mysql-connector-java 连接数据库,版本最好和数据库的版本一致 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<!-- mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>

入门–先将mybatis跑起来

1、创建 mybatis 核心配置文件

<?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>
<!-- 引入外部的 properties 配置文件 -->
<properties resource="db.properties"></properties>
<!-- &lt;!&ndash; MyBatis 全局属性配置 &ndash;&gt;-->
<!-- <settings>-->
<!-- &lt;!&ndash; 日志设置,属性值是固定的 &ndash;&gt;-->
<!-- <setting name="logImpl" value="LOG4J" />-->
<!-- </settings>-->
<typeAliases>
<package name="com.hkp.entity"/>
</typeAliases>
<!-- 运行环境的配置 可以配置很多个 (mybatis连接数据库)environments中每个environment都是一个运行环境 default Runtime enabled by default -->
<environments default="development">
<environment id="development">
<!-- 事务管理器 -->
<transactionManager type="JDBC" />
<!-- 配置数据源 type="POOLED" Connect by connection pool -->
<dataSource type="POOLED">
<!-- 驱动 -->
<property name="driver" value="${driver}" />
<!-- 数据库的地址 -->
<property name="url" value="${url}" />
<!-- 数据库用户名 -->
<property name="username" value="${user}" />
<!-- 数据库密码 -->
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<!-- SQL 映射文件 (写SQL语句的文件) 可以配置很多个 -->
<mappers>
<mapper class="com.hkp.mapper.UserMapper"/>
</mappers>
</configuration>

2、创建实体类

package com.hkp.entity;
import java.util.Date;
public class User {

private Integer id;
private String userCode;
private String userName;
private String userPassword;
private Integer gender;
private Date birthday;
private String phone;
private String address;
private Integer userRole;
private Integer createdBy;
private Date creationDate;
private Integer modifyBy;
private Date modifyDate;
...对应的 get set 方法
}

3、创建 UserMapper 接口

public interface UserMapper {

List<User> selectUser();
}

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.hkp.mapper.UserMapper">
<select id="selectUser" resultType="user">
SELECT * FROM smbms_user
</select>
</mapper>

5、创建 测试类

@Test
public void testMybatis() throws Exception{

InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.selectUser();
sqlSession.close();
for (User user: userList) {

System.out.println(user);
}
}

spring 整合 mybatis

方式一 :Need to inject in the implementation class sqlSession

1、修改 mybatis 核心配置文件的配置

<?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>
<!-- &lt;!&ndash; MyBatis 全局属性配置 &ndash;&gt;-->
<!-- <settings>-->
<!-- &lt;!&ndash; 日志设置,属性值是固定的 &ndash;&gt;-->
<!-- <setting name="logImpl" value="LOG4J" />-->
<!-- </settings>-->
<typeAliases>
<package name="com.hkp.entity"/>
</typeAliases>
</configuration>

2、创建 UserMapper 实现

package com.hkp.mapper;
import com.hkp.entity.User;
import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;
public class UserMapperImpl implements UserMapper{

//之前都是使用 sqlSession 来操作,现在是使用 sqlSessionTemplate 
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {

this.sqlSession = sqlSession;
}
@Override
public List<User> selectUser() {

return sqlSession.getMapper(UserMapper.class).selectUser();
}
}

3、创建 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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 引用properties文件 -->
<context:property-placeholder location="classpath*:db.properties" />
<!-- DataSource : 使用 spring 的数据源替换mybatis的配置.使用的是 spring 的jdbc -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${user}"></property>
<property name="password" value="${password}"></property>
</bean>
<!-- SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--绑定mybatis 的配置 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!-- 匹配xml映射器 -->
<property name="mapperLocations" value="classpath:com/hkp/mapper/*.xml"/>
</bean>
<!-- SqlSessionTemplate : 就是我们使用的sqlSession. -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!-- Can only be injected using parameterized constructs,因为他没有set方法 -->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<bean id="userMapper" class="com.hkp.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
</beans>

4、编写测试类

@Test
public void testSpring(){

ApplicationContext context = new ClassPathXmlApplicationContext("spring-dataSource.xml");
UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
List<User> userList = userMapper.selectUser();
for (User user: userList) {

System.out.println(user);
}
}

方式二 :SqlSessionDaoSupport No manual injection is required sqlSession

SqlSessionDaoSupport 是一个抽象的支持类,用来为你提供 SqlSession.调用 getSqlSession() 方法你会得到一个 SqlSessionTemplate,之后可以用于执行 SQL 方法

1、重新创建 UserMapper 实现类

public class UserMapper2 extends SqlSessionDaoSupport implements UserMapper {

@Override
public List<User> selectUser() {

SqlSession sqlSession = getSqlSession();
return sqlSession.getMapper(UserMapper.class).selectUser();
}
}

2、修改 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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 引用properties文件 -->
<context:property-placeholder location="classpath:db.properties" />
<!-- DataSource : 使用 spring 的数据源替换mybatis的配置 .使用的是 spring 的jdbc -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${driver}"></property>
<property name="url" value="${url}"></property>
<property name="username" value="${user}"></property>
<property name="password" value="${password}"></property>
</bean>
<!-- SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--绑定mybatis 的配置 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!-- 匹配xml映射器 -->
<property name="mapperLocations" value="classpath:com/hkp/mapper/*.xml"/>
</bean>
<bean id="userMapper2" class="com.hkp.mapper.UserMapper2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>

3、编写测试

@Test
public void testSpring(){

ApplicationContext context = new ClassPathXmlApplicationContext("spring-dataSource.xml");
UserMapper userMapper = context.getBean("userMapper2", UserMapper.class);
List<User> userList = userMapper.selectUser();
for (User user: userList) {

System.out.println(user);
}
}

声明式事务

声明式事务 :The original code can be changed without changing,添加事务.

回顾事务 :

  • A code in a business,要么都成功,要么都失败!
  • 事务在项目中十分重要
  • 确保完整性和一致性

事务的 ACID 原则 :

  • 原子性
  • 一致性
  • 隔离性
  • 持久性

使用事务的步骤

1、在 applicationContext.xml Introduce transaction constraints (tx)

xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd

2、创建 bean

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

3、结合AOP 实现事务

<!-- 结合AOP 实现事务 -->
<!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 给方法配置事务 -->
<tx:attributes>
<tx:method name="add"/>
<tx:method name="delete"/>
<tx:method name="update"/>
<tx:method name="query"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="txPoint" expression="execution(* com.hkp.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
</aop:config>

4、Test insertion and deletion code

package com.hkp.mapper;
import com.hkp.entity.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {

@Override
public List<User> selectUser() {

User user = new User("admin","123",1);
int i = this.addUser(user);
int i1 = this.deleteUser(22);
SqlSession sqlSession = getSqlSession();
return sqlSession.getMapper(UserMapper.class).selectUser();
}
@Override
public int addUser(User user) {

return getSqlSession().getMapper(UserMapper.class).addUser(user);
}
@Override
public int deleteUser(int id) {

return getSqlSession().getMapper(UserMapper.class).deleteUser(id);
}
}
copyright:author[Dapeng],Please bring the original link to reprint, thank you. https://en.javamana.com/2022/218/202208061327435561.html