Spring [Spring integrates MyBatis, SpringAOP (AOP introduction, AOP related terms, AOP introduction)] (5) - comprehensive detailed explanation (learning summary --- from entry to deepening)

Table of contents

 Spring integrates MyBatis_ to prepare database and entity classes

Spring integrates MyBatis_ write persistence layer interface and service class

Spring integrates MyBatis_Spring integrates Junit for unit testing

Spring integrates MyBatis_ to automatically create proxy objects 

Introduction to Spring AOP_AOP 

 SpringAOP_AOP related terms

 Getting Started with Spring AOP_AOP


 Spring integrates MyBatis_ to prepare database and entity classes

prepare database

CREATE DATABASE `student`;
USE `student`;
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `sex` varchar(10) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT
CHARSET=utf8;
insert  into
`student`(`id`,`name`,`sex`,`address`)
values (1,'程序员','男','北京'),(2,'程序媛','女','北京');

Prepare Entity Class

public class Student {
    private int id;
    private String name;
    private String sex;
    private String address;
    
    // 省略构造方法/getter/setter/tostring
}

Spring integrates MyBatis_ write persistence layer interface and service class

Write the persistence layer interface

@Repository
public interface StudentDao {
    // 查询所有学生
    @Select("select * from student")
    List<Student> findAll();
    // 添加学生
    @Insert("insert into student values(null,#{name},#{sex},#{address})")
    void add(Student student);
}

Write service class

@Service
public class StudentService {
    // SqlSession对象
    @Autowired
    private SqlSessionTemplate sqlSession;
    // 使用SqlSession获取代理对象
    public List<Student> findAllStudent(){
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        return studentDao.findAll();
   }
}

Spring integrates MyBatis_Spring integrates Junit for unit testing

Before unit testing, it was necessary to manually create the Spring container. Can Spring automatically create the container during the test?

1. Introduce Junit and Spring to integrate Junit dependencies

<!-- junit,如果Spring5整合junit,则junit版本
至少在4.12以上 -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<!-- spring整合测试模块 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.3.13</version>
</dependency>

2. Write test class

// JUnit使用Spring方式运行代码,即自动创建spring容器。
@RunWith(SpringJUnit4ClassRunner.class)
// 告知创建spring容器时读取哪个配置类或配置文件
// 配置类写法:
@ContextConfiguration(classes=配置类.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class StudentServiceTest {
    @Autowired
    private StudentService studentService;
    
    @Test
    public void testFindAll(){
        List<Student> allStudent = studentService.findAllStudent();
        allStudent.forEach(System.out::println);
   }
}

Note: Using SqlSessionTemplate to create a proxy object still needs to register an interface or a mapping file.

1. Register the interface in the MyBatis configuration file

<configuration>
    <mappers>
        <mapper class="com.tong.dao.StudentDao"></mapper>
    </mappers>
</configuration>

2. Specify the MyBatis configuration file when creating sqlSessionFactory

<!-- 创建Spring封装过的SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"></property>
    <property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
</bean>

Spring integrates MyBatis_ to automatically create proxy objects 

Spring provides the MapperScannerConfigurer object, which can automatically scan the package to create a proxy object and put the proxy object into the container. At this time, there is no need to use SqlSession to manually create the proxy object.

1. Create a MapperScannerConfigurer object

<!-- 该对象可以自动扫描持久层接口,并为接口创建代理对象 -->
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!-- 配置扫描的接口包 -->
    <property name="basePackage" value="com.tong.dao"></property>
</bean>

2. The Service class can directly use the proxy object

@Service
public class StudentService {
    // 直接注入代理对象
    @Autowired
    private StudentDao studentDao;
  
    // 直接使用代理对象
    public void addStudent(Student student){
        studentDao.add(student);
   }
}

3. Test

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath :applicationContext.xml")
public class StudentServiceTest {
    @Autowired
    private StudentService studentService;
    
    @Test
    public void testAdd(){
        Student student = new Student(0, "童小纯", "男", "上海");
        studentService.addStudent(student);
   }
}

Introduction to Spring AOP_AOP 

 The full name of AOP is Aspect Oriented Programming, that is, aspect-oriented programming. It is a technology to achieve unified maintenance of functions. It isolates various parts of business logic, so that developers can concentrate on core business when writing business logic, thereby improving development efficiency.

Function : On the basis of not modifying the source code, the existing methods are enhanced.

Implementation principle : dynamic proxy technology.

Advantages : reduce duplication of code, improve development efficiency, and facilitate maintenance

Application scenarios : transaction processing, log management, authority control, exception handling, etc.

 SpringAOP_AOP related terms

 In order to better understand AOP, you need to have some understanding of AOP-related terms

 Getting Started with Spring AOP_AOP

AspectJ is an AOP framework based on the Java language. It is recommended to use AspectJ to implement AOP in the Spring framework.

Next, let's write an AOP entry case: each method of the dao layer can print a log after the end:

1. Introduce dependencies

<!-- spring -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.13</version>
</dependency>

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

<!-- junit -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

2. Write the connection point

@Repository
public class UserDao {
    public void add(){
        System.out.println("用户新增");
   }
    public void delete(){
        System.out.println("用户删除");
   }
    public void update(){
        System.out.println("用户修改");
   }
}

3. Write notification class

public class MyAspectJAdvice {
    // 后置通知
    public void myAfterReturning() {
        System.out.println("打印日志...");
   }
}

4. Configuration section

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:aop="http://www.springframework.org/schema/aop"
      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
        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:component-scan base-package="com.tong"></context:component-scan>
    <!-- 通知对象 -->
    <bean id="myAspectJAdvice" class="com.tong.advice.MyAspectAdvice"></bean>
    <!-- 配置AOP -->
    <aop:config>
    <!-- 配置切面 -->
        <aop:aspect ref="myAspectJAdvice">
            <!-- 配置切点 -->
            <aop:pointcut id="myPointcut" expression="execution(* com.tong.dao.UserDao.*(..))"/>
            <!-- 配置通知 -->
            <aop:after-returning method="myAfterReturning" pointcutref="myPointcut"/>
        </aop:aspect>
    </aop:config>
</beans>

5. Test

public class UserDaoTest {
    @Test
    public void testAdd(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        UserDao userDao = (UserDao) ac.getBean("userDao");
        userDao.add();
   }
    @Test
    public void testDelete(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        UserDao userDao = (UserDao)ac.getBean("userDao");
        userDao.delete();
   }
    @Test
    public void testUpdate(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        UserDao userDao = (UserDao) ac.getBean("userDao");
        userDao.update();
   }
}

review:

Introduction to Spring

 Spring is an open source framework born to simplify enterprise-level development. It takes IOC (Inversion of Control) and AOP (Aspect-Oriented) as its ideological core, provides many technologies such as SpringMVC for the control layer, SpringData for the data layer, transaction management for the service layer, and can integrate many third-party frameworks. Spring makes many complicated codes elegant and concise, effectively reduces the coupling degree of codes, and greatly facilitates the later maintenance, upgrade and expansion of projects.

Spring official website address: https://spring.io/

 Spring Architecture

 The Spring framework is divided into multiple modules according to different functions. These modules can meet the needs of all enterprise-level application development. During the development process, the required modules can be selectively used according to the requirements.

1. Core Container: The core module of Spring. The use of any function is inseparable from this module, which is the basis for the establishment of other modules.

2. Data Access/Integration: This module provides the corresponding functions of data persistence.

3. Web: This module provides corresponding functions for web development.

4. AOP: Provides aspect-oriented programming implementation

5. Aspects: Provides integration with the AspectJ framework, which is an aspect-oriented programming framework.

6. Instrumentation: Provides the support of class tools and the implementation of class loaders, which can be used in specific application servers.

7. Messaging: Integrate some basic messaging applications for the Spring framework

8. Test: Provides integration with the testing framework

IOC_Inversion of Control Thought 

 IOC (Inversion of Control): The program hands over the right to create objects to the framework. In the previous development process, the creation of object instances was managed by the caller, the code is as follows:

public interface StudentDao {
    // 根据id查询学生
    Student findById(int id);
}
public class StudentDaoImpl implements StudentDao{
    @Override
    public Student findById(int id) {
        // 模拟从数据库查找出学生
        return new Student(1,"程序员","北京");
   }
}
public class StudentService {
    public Student findStudentById(int id){
        // 此处就是调用者在创建对象
        StudentDao studentDao = new StudentDaoImpl();
        return studentDao.findById(1);
   }
}

This way of writing has two disadvantages:

1 Waste of resources: When the StudentService calls a method, an object will be created, and if the method is called continuously, a large number of StudentDao objects will be created.

2 High degree of code coupling: Assume that with the development, we have created another more complete implementation class StudentDaoImpl2 of StudentDao. If you want to use StudentDaoImpl2 in StudentService, you must modify the source code.

The IOC idea is to hand over the right to create objects to the framework. The framework will help us create objects and allocate the use of objects. The control right is transferred from the program code to the framework, and the control right is reversed. This is Spring's IOC idea. The IOC idea can perfectly solve the above two problems. 

IOC_Custom Object Container

 Next, we simulate the IOC idea through a piece of code. To create a collection container, first create the object and put it in the container. When you need to use the object, you only need to get the object from the container without recreating it. At this time, the container is the manager of the object.

Create entity classes

public class Student {
    private int id;
    private String name;
    private String address;
 // 省略getter/setter/构造方法/tostring
}

Create Dao interface and implementation class

public interface StudentDao {
    // 根据id查询学生
    Student findById(int id);
}
public class StudentDaoImpl implements StudentDao{
    @Override
    public Student findById(int id) {
        // 模拟从数据库查找出学生
        return new Student(1,"程序员","北京");
   }
}
public class StudentDaoImpl2 implements StudentDao{
    @Override
    public Student findById(int id) {
        // 模拟根据id查询学生
        System.out.println("新方法!!!");
        return new Student(1,"程序员","北京");
   }
}

Create a configuration file bean.properties that defines managed objects

studentDao=com.tong.dao.StudentDaoImpl

Create a container management class, which reads the configuration file when the class is loaded, and creates and puts all the objects configured in the configuration file into the container.

public class Container {
    static Map<String,Object> map = new HashMap();
    static {
        // 读取配置文件
        InputStream is = Container.class.getClassLoader().getResourceAsStream("bean.properties");
        Properties properties = new Properties();
        try {
            properties.load(is);
       } catch (IOException e) {
            e.printStackTrace();
       }
        // 遍历配置文件的所有配置
        Enumeration<Object> keys = properties.keys();
        while (keys.hasMoreElements()){
            String key = keys.nextElement().toString();
            String value = properties.getProperty(key);
            try {
                // 创建对象
                Object o = Class.forName(value).newInstance();
                // 将对象放入集合中
                map.put(key,o);
           } catch (Exception e) {
                e.printStackTrace();
           }
       }
   }
    // 从容器中获取对象
 public static Object getBean(String key){
        return map.get(key);
   }
}

The caller StudentService that creates the Dao object

public class StudentService {
    public Student findStudentById(int id)
     {
        // 从容器中获取对象
        StudentDao studentDao = (StudentDao) Container.getBean("studentDao");
        System.out.println(studentDao.hashCode());
        return studentDao.findById(id);
   }
}

testStudentService

public class Test {
    public static void main(String[] args)
    {
      StudentService studentService = new StudentService();
      System.out.println(studentService.findStudentById(1));
      System.out.println(studentService.findStudentById(1));
   }
}

 IOC_Spring implements IOC

 Next, we use Spring to implement IOC, and there is also a container inside Spring to manage objects.

Create a Maven project and introduce dependencies

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.13</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Create POJO classes, Dao classes and interfaces

public class Student {
    private int id;
    private String name;
    private String address;
  // 省略getter/setter/构造方法/tostring
}
public interface StudentDao {
    // 根据id查询学生
    Student findById(int id);
}
public class StudentDaoImpl implements StudentDao{
    @Override
    public Student findById(int id) {
        // 模拟从数据库查找出学生
        return new Student(1,"程序员","北京");
   }
}

Write an xml configuration file, and configure the objects that Spring needs to create for us in the configuration file.

<?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="studentDao" class="com.tong.dao.StudentDaoImpl"></bean>     
</beans>

 The test fetches objects from the Spring container.            

public class TestContainer {
    @Test
    public void t1(){
        // 创建Spring容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        // 从容器获取对象
        StudentDao studentDao1 = (StudentDao) ac.getBean("studentDao");
        StudentDao studentDao2 = (StudentDao) ac.getBean("studentDao");
        System.out.println(studentDao1.hashCode());
        System.out.println(studentDao2.hashCode());
        System.out.println(studentDao1.findById(1));
   }
}

 IOC_Spring container type                                                                     container interface                            

 1. BeanFactory: BeanFactory is the top-level interface in the Spring container, which can manage Bean objects.

2. ApplicationContext: ApplicationContext is a subinterface of BeanFactory. In addition to inheriting all the functions of BeanFactory, it also adds good support for internationalization, resource access, and event propagation.

 ApplicationContext has the following three commonly used implementation classes:,

container implementation class

1. ClassPathXmlApplicationContext: This class can read configuration files from the project

2. FileSystemXmlApplicationContext: This class reads configuration files from disk

3. AnnotationConfigApplicationContext: Using this class does not read configuration files, but reads annotations

@Test
public void t2(){
    // 创建spring容器
    //       ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
    ApplicationContext ac = new FileSystemXmlApplicationContext("C:\\Users\\a\\IdeaProjects\\spring_demo\\src\\main\\resources\\bean.xml");
    
    // 从容器中获取对象
    StudentDao userDao = (StudentDao)ac.getBean("studentDao");
    System.out.println(userDao);
    System.out.println(userDao.findById(1));
}

Guess you like

Origin blog.csdn.net/m0_58719994/article/details/131744311