Spring - Crazy God says Java learning notes

Spring

Bili Bili crazy God says Java spring learning website
The article is only for sharing learning experience and reviewing. It is more effective to check the formal video website and official documents

1. Introduction

The spring framework was created due to the complexity of software development. Spring uses basic JavaBean s to do things that previously could only be done by EJB s. However, the use of spring is not limited to server-side development. In terms of simplicity, testability and loose coupling, most Java applications can benefit from spring.

  • Spring: Spring ------ > brings spring to the software industry!
  • In 2002, the prototype of Spring framework, interface21 framework, was launched for the first time
  • On March 24, 2004, the spring framework released the official version of 1.0, which is based on the interface21 framework, redesigned and continuously enriched its connotation.
  • Rod Johnson, founder and famous author of Spring Framework. It's hard to imagine that rod Johnson's degree really surprised many people. He is a doctor at the University of Sydney. However, his major is not computer, but musicology
  • "Wheel theory" means "don't invent the wheel again"
  • Spring's concept: to make the existing technology more applicable, it is a "hodgepodge" and integrates the existing technical framework
  • SSH: Struct2 + Spring + Hibernate
  • SSM: SpringMav + Spring + Mybatis

Official website: https://spring.io/projects/spring-framework

Official download address: https://repo.spring.io/ui/native/release/org/springframework/spring

GitHub :https://github.com/spring-projects/spring-framework

Official documents: https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-basics

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.10</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.3.10</version>
</dependency>

1.1 advantages

  • Spring is an open source free framework, container
  • Spring is a lightweight, non intrusive framework
  • Two key points: control inversion (IOC) and aspect oriented (AOP)
  • Support transaction processing and framework integration

To sum up: Spring is a lightweight container (framework) for inversion of control (IOC) and aspect oriented (AOP)

1.2 composition

Spring framework is a layered architecture, which consists of seven well-defined modules. Spring modules are built on the core container, which defines the way to create, configure and manage bean s

Each module (or component) constituting the Spring framework can exist alone or be implemented jointly with one or more other modules. The functions of each module are as follows:

Core container: the core container provides the basic functions of the Spring framework. The main component of the core container is BeanFactory, which is the implementation of the factory pattern. BeanFactory uses the inversion of control (IOC) pattern to separate the configuration and dependency specifications of the application from the actual application code.

Spring context: Spring context is a configuration file that provides context information to the spring framework. Spring context includes enterprise services, such as JNDI, EJB, e-mail, internationalization, checksum and scheduling functions.

Spring AOP: through the configuration management feature, the spring AOP module directly integrates aspect oriented programming functions into the spring framework. Therefore, it is easy for the spring framework to manage any object that supports AOP. The spring AOP module provides transaction management services for objects in spring based applications. By using spring AOP, you can manage objects without relying on components Declarative transaction management can be integrated into applications.

Spring DAO: the JDBC DAO abstraction layer provides a meaningful exception hierarchy that can be used to manage exception handling and error messages thrown by different database vendors. The exception hierarchy simplifies error handling and greatly reduces the amount of exception code that needs to be written (such as opening and closing connections) Spring DAO's JDBC oriented exceptions follow a common DAO exception hierarchy.

Spring ORM: the spring framework inserts several ORM frameworks to provide ORM object relationship tools, including JDO, Hibernate and iBatis SQL Map. All of these comply with spring's common transaction and DAO exception hierarchy.

Spring Web module: the Web context module is built on the application context module and provides context for web-based applications. Therefore, the spring framework supports integration with Jakarta Struts. The web module also simplifies the work of processing multipart requests and binding request parameters to domain objects.

Spring MVC framework: the MVC framework is a full-featured MVC implementation for building Web applications. Through the policy interface, the MVC framework becomes highly configurable. MVC accommodates a large number of view technologies, including JSP, Velocity, Tiles, iText and POI.

1.3 expansion

Spring Boot and Spring Cloud

  • Spring Boot

    • Spring is a set of rapid configuration scaffolding
    • You can quickly develop a single microservice based on Spring Boot
    • Contract greater than configuration
  • Spring Cloud

    • It is implemented based on Spring Boot

Because most companies are now applying SpringBoot for rapid development. To learn the premise of SpringBoot, they need to fully control Spring and Spring MVC to connect the preceding and the following

Spring Boot focuses on a single micro service individual that is fast and easy to integrate. Spring Cloud focuses on the overall service governance framework;

Spring Boot uses the concept that constraints are better than configuration. Many integration schemes have been selected for you. You can't configure without configuration. A large part of Spring Cloud is implemented based on Spring Boot. Spring Boot can use development projects independently of Spring Cloud, but Spring Cloud is inseparable from Spring Boot and belongs to dependency.

SpringBoot plays a connecting role in SpringClound. If you want to learn spring cloud, you must learn SpringBoot.

Disadvantages: after too long development, it violates the original concept! The configuration is very cumbersome, known as "configuration hell!"

2. IOC theoretical derivation

2.1 IOC Foundation

Create a new blank maven project

Import package

Parent pom.xml

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

1. Analysis and Implementation

Let's write a piece of code in our original way

1. First write a UserDao interface

public interface UserDao {
   public void getUser();
}

2. Then write Dao's implementation class

public class UserDaoImpl implements UserDao {
   @Override
   public void getUser() {
       System.out.println("Get user data by default");
  }
}

3. Then write the UserService interface

public interface UserService {
   public void getUser();
}

4. Finally, write the implementation class of Service

public class UserServiceImpl implements UserService {
   private UserDao userDao = new UserDaoImpl();

   @Override
   public void getUser() {
       userDao.getUser();
  }
}

5. Test it

@Test
public void test(){
   UserService service = new UserServiceImpl();
   service.getUser();
}

This is our original way. At first, everyone wrote it like this, right? Let's revise it now

2. After modification

Add an implementation class of Userdao

public class UserDaoMySqlImpl implements UserDao {
   @Override
   public void getUser() {
       System.out.println("MySql Get user data");
  }
}

Next, if we want to use MySql, we need to modify the corresponding implementation in the service implementation class

public class UserServiceImpl implements UserService {
   private UserDao userDao = new UserDaoMySqlImpl();

   @Override
   public void getUser() {
       userDao.getUser();
  }
}

In the assumption, we add another Userdao implementation class

public class UserDaoOracleImpl implements UserDao {
   @Override
   public void getUser() {
       System.out.println("Oracle Get user data");
  }
}

If we want to use Oracle, we need to modify the corresponding implementation in the service implementation class.

This method is not applicable at all, even anti-human, right? Every change requires a lot of code modification. The coupling of this design is too high, which will affect the whole body.

How can we solve it?

Instead of implementing it, we can set aside an interface where we need it. Using set, we can modify the service implementation class code

public class UserServiceImpl implements UserService {
   private UserDao userDao;
// Using set implementation, dynamic value injection
   public void setUserDao(UserDao userDao) {
       this.userDao = userDao;
  }

   @Override
   public void getUser() {
       userDao.getUser();
  }
}

Now go to our test class and test;

@Test
public void test(){
   UserServiceImpl service = new UserServiceImpl();
   service.setUserDao( new UserDaoMySqlImpl() );
   service.getUser();
   //So now we want to use Oracle to implement it
   service.setUserDao( new UserDaoOracleImpl() );
   service.getUser();
}

In this way, when a new Dao implementation class appears, we do not need to modify the methods in the service implementation class, but the caller selects the implementation class methods he needs from the test class.

In our previous business, the needs of users may affect our original code. We need to modify the original code according to the needs of users! If the amount of program code is very large, the cost of modifying once is very expensive!

We use a set interface implementation and have sent revolutionary changes!

  • Previously, the program actively created objects, and the control was in the hands of the programmer
  • After using set injection, the program no longer has the initiative, but becomes a passive acceptance object!
  • You don't have to worry about how to create and implement it. You are only responsible for providing an interface

This idea essentially solves the problem. Our programmers no longer manage the creation of objects and pay more attention to the implementation of business. The coupling is greatly reduced, which is the prototype of IOC!

2.2 essence of IOC

Previous programming

set programming, the initiative becomes the user

Inversion of control (IOC) is a design idea. DI (dependency injection) is a method to realize IOC. Some people think that DI is just another term of IOC. In the program without IOC, we use object-oriented programming. The creation of objects and the dependencies between objects are completely hard coded. In the program, the creation of objects is controlled by the program itself. After the control is reversed, the creation of objects is transferred to a third party. Personally, I think the so-called control reversal is the reversal of the way to obtain dependent objects.

IOC is the core content of the Spring framework. IOC is perfectly implemented in a variety of ways. It can be configured using XML or annotations. The new version of Spring can also implement IOC with zero configuration.

During initialization, the Spring container reads the configuration file first, creates and organizes objects according to the configuration file or metadata, and stores them in the container. When the program is used, it takes out the required objects from the IOC container.

When configuring a Bean in XML, the definition information of the Bean is separated from the implementation, and the annotation method can integrate the two. The definition information of the Bean is directly defined in the implementation class in the form of annotation, so as to achieve the purpose of zero configuration.

Inversion of control is a way to produce or obtain specific objects through description (XML or annotation) and through a third party. In Spring, the IOC container implements control inversion, and its implementation method is dependency injection (DI)

2.3,HelloSpring

Entity class

public class Hello {
    private String str;
public String getStr() {
    return str;
}

public void setStr(String str) {
    this.str = str;
}

@Override
public String toString() {
    return "Hello{" +
            "str='" + str + '\'' +
            '}';
}
}

xml file

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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--use Spring To create an object, in Spring These are called Bean
-->
<bean id="hello" class="com.ssxxz.pojo.Hello">
    <property name="str" value="spring"/>
</bean>
</beans>

Normal condition: class name variable name = new type ()

​ Hello hello = new Hello()

Spring:

  • id = variable name

  • class = new object

  • Property is equivalent to setting a value for a property in an object

    • Name = attribute name to be set
    • Value = attribute value to be set

test

The ApplicationContext constructor instantiates Spring

public class MyTest {
public static void main(String[] args) {
    //Get the context object of spring, get
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    //Our objects are now managed in spring. If we want to use them, we can get them directly from the spring container
    Hello hello = (Hello) context.getBean("hello");
    System.out.println(hello.toString());
}
}

After using Spring, it is found that there is no need to manually new objects, which are configured in xml files. Or generally speaking, there is no need to change the underlying code, and xml files are not the underlying code.

This process is called control reversal

Control: who controls the creation of objects? Traditional application objects are created by the program itself. After using Spring, objects are created by Spring

Inversion: the program itself does not create an object, but becomes a passive receiving object.

Dependency injection: it uses the set method to inject

IOC is a programming idea that changes from active programming to passive reception. You can browse the underlying source code through newClassPathXmlApplicationContext

2.4. Code before modification

Write the beans.xml 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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--Import entity class-->
<bean id="mysqlImpl" class="com.ssxxz.dao.UserDaoMysqlImpl"/>
<bean id="oracleImpl" class="com.ssxxz.dao.UserDaooracleImpl"/>
    
<bean id="UserServiceImpl" class="com.ssxxz.service.UserServiceImpl">
    <property name="userDao" ref="mysqlImpl"/>
    <!-- 
 		ref:quote Spring Created object in container
		value:Specific value, basic data type!
	-->
</bean>
</beans>
  • ref: refers to the object created in the Spring container
  • Value: specific value, basic data type!

test

public class MyTest {
public static void main(String[] args) {
    //Get ApplicationContext and get the container of Spring
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    
    //The container is in hand. I have it in the world. I can directly gei whatever I need
    UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean("UserServiceImpl");
    userServiceImpl.getUser();
}
}

To get other values, you only need to modify the ref value in the beans.xml configuration file without modifying the code.

Now, we don't need to modify in the program at all. To realize different operations, we only need to modify in the xml configuration file. The so-called IOC is done in one sentence: objects are created, managed and assembled by Spring

2.5. How IOC creates objects - constructor injection

Objects are created using parameterless construction by default

There are three ways to create objects using parametric construction

Constructor Argument Resolution constructor function

public class User {
private String name;
private int age;
public User(String name, int age) {this.name = name;this.age = age;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public int getAge() {return age;}
public void setAge(int age) {this.age = age;}
}

1. Subscript assignment Constructor argument index

<bean id="user" class="com.ssxxz.entity.User">
    <constructor-arg index="0" value="Zhang San"/>
    <constructor-arg index="1" value="18"/>
</bean>
  • How many methods of index subscript

2. Variable type assignment Constructor argument type matching

<bean id="user1" class="com.ssxxz.entity.User">
    <constructor-arg type="int" value="18"/>
    <constructor-arg type="java.lang.String" value="Zhang San"/>
</bean>
  • Basic types can be used directly, and reference types need fully qualified names
  • However, it is not recommended to use the same type, such as two ints

3. Variable name assignment Constructor argument name

<bean id="user2" class="com.ssxxz.entity.User">
    <constructor-arg name="name" value="Zhang San"/>
    <constructor-arg name="age" value="18"/>
</bean>

When you get the spring context object (new ClassPathXmlApplicationContext("beans.xml");), all objects in the spring container have been created.

3. Basic configuration of Spring

3.1 alias

<bean id="user" class="com.ssxxz.entity.User">
    <constructor-arg index="0" value="Zhang San"/>
    <constructor-arg index="1" value="18"/>
</bean>

<!--If an alias is added, the object can also be obtained through the alias-->
   <alias name="user" alias="userAlias"/>
  • Both can be obtained, using the original User or userAlias

3.2 Bean configuration

	<!--
        id: bean The unique identifier of, which is equivalent to the object name we learned
        class:  bean Fully qualified name of object: package name + type
        name:  It's also an alias, and name Multiple aliases can be set at the same time, which can be separated by commas, spaces and semicolons
    -->
    <bean id="user1" class="com.ssxxz.entity.User" name="test test1, test2; test3"> 
        <constructor-arg type="int" value="18"/>
        <constructor-arg type="java.lang.String" value="Zhang San"/>
    </bean>
  • ID: the unique identifier of the bean, which is equivalent to the object name we learned
  • class: fully qualified name of bean object: package name + type
  • Name: it is also an alias, and name can set multiple aliases at the same time, which can be separated by commas, spaces and semicolons

3.3,import

Import is generally used for team development. It can import and merge multiple configuration files into one
Suppose that there are many developers in the project. These three people are responsible for the development of different classes. Different classes need to be registered in different beans. We can use import to merge everyone's beans.xml into a total!

beans.xml
beans2.xml
beans3.xml
Merge into applicationContext.xml

<import resource="beans.xml"/>
<import resource="beans2.xml"/>
<import resource="beans3.xml"/>

When using, just use the general configuration directly

4. DI dependency injection

4.1. Constructor injection

As already said

4.2 set mode injection [ key ]

Dependency injection

  • Dependency: the creation of bean objects depends on the container

  • Injection: all attributes in the bean object are injected by the container

Environment construction

1. Complex type

public class Address {
private String address;

public String getAddress() {
    return address;
}

public void setAddress(String address) {
    this.address = address;
}
@Override
public String toString() {
    return "Address{" +
            "address='" + address + '\'' +
            '}';
}
}

2. Real test object

import java.util.*;

public class Student {
private String name;
private Address address;
private String [] books;
private List<String> hobbies;
private Map<String, String> card;
//set is out of order and cannot be repeated
private Set<String> games;
//Null pointer
private String wife;
//Configuration class
private Properties info;

//Getter, Setter and toString
}

Note: private address; It is a copy method class, so you need toString its method toString, Address.toString(address)

3,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">
<!-- Because it is a complex type called separately, it needs to be imported first and then injected -->
<bean id="address" class="com.ssxxz.entity.Address">
    <property name="address" value="Left left right right"/>
</bean>

<!--Ordinary injection value-->
<bean id="student" class="com.ssxxz.entity.Student">
    <property name="name" value="ups and downs"/>
    
    <!--Bean Injection, ref-->
    <property name="address" ref="address"/>
    
    <!--array array -->
    <property name="books">
        <array>
            <value>The Dream of Red Mansion</value>
            <value>Romance of the Three Kingdoms</value>
            <value>Water Margin</value>
            <value>Journey to the West</value>
        </array>
    </property>

    <!--List-->
    <property name="hobbies">
        <list>
            <value>smoking</value>
            <value>drink</value>
            <value>Hot head</value>
        </list>
    </property>

    <!--Map (entry)-->
    <property name="card">
        <map>
            <entry key="ID" value="1234567891234"/>
            <entry key="bank card" value="98765432112"/>
        </map>
    </property>

    <!--Set-->
    <property name="games">
        <set>
            <value>LOL</value>
            <value>COC</value>
            <value>BOB</value>
        </set>
    </property>

    <!--null value-->
    <!-- Empty string<property name="wife" value=""/> -->
    <property name="wife">
        <null/>
    </property>

    <!--Properties Special type -->
    <property name="info">
        <props>
            <prop key="url">drive</prop>
            <prop key="username">root</prop>
            <prop key="password">123456</prop>
        </props>
    </property>
</bean>
</beans>

4. Test class

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    Student student = (Student) context.getBean("student");
    System.out.println(student);
    /*
    * Student{
    * name='ssxxz',
    * address=Address{address='Dalian'},
    * books=[Dream of Red Mansions, romance of the Three Kingdoms, outlaws of the marsh, journey to the West],
    * hobbies=[Smoking, drinking, scalding],
    * card={ID card = 220........, bank card = 626........},
    * games=[LOL, COC, BOB],
    * wife='null',
    * info={password=123456, name=root, driver=Drive}}
    * */
}
}

View the official website document to learn

https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-basics

4.3 p, c label injection

We can use p and c tag injection, but we need to import third-party xml constraints

P tag injection, xmlns: P must be introduced into beans=“ http://www.springframework.org/schema/p "

<?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 Namespace injection, you can directly inject the value of the attribute: property-->
    <bean id="p_test" class="com.ssxxz.entity.Student" p:name="ssxxz"/>

C tag injection requires adding a parameter construction method in the entity and introducing xmlns: C=“ http://www.springframework.org/schema/c "

<?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"
       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">
    
<!--c Namespace injection through constructor: construct-args-->
<bean id="c_test" class="com.ssxxz.entity.Address" c:address="DL"/>

4.4 scope of Bean

Bean Scopes

1. singleton (Spring default mechanism, globally unique)

<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>

2. prototype pattern: each object has its own, which is recreated every time it get s an object from the container

<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>

3. The rest of the request, session, application and websocket can only be used in web development

5. Automatic assembly of Bean

  • Automatic assembly is a way for spring to meet bean dependencies
  • Spring will automatically find it in the context and automatically assemble properties for the bean

There are three assembly methods in Spring

  • Explicit configuration in xml
  • Explicit configuration in java
  • Implicit auto assembly bean

5.1. autowire - ByName and ByType automatic assembly

<?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="cat" class="com.ssxxz.entity.Cat"/>
    <bean id="dog" class="com.ssxxz.entity.Dog"/>
    <!--
        byName:It will find its own objects in the container context set Corresponding to the value after the method beanid
        byType: It will automatically find the object with the same property type as its own object in the container context bean
    -->
    <bean id="people" class="com.ssxxz.entity.People" autowire="byName">
        <property name="name" value="ups and downs"/>
    </bean>
    <!-- Injection was required in the past dog Information, but automatic assembly does not need to be written -->
    <!-- <property name="dog" ref="dog"/> -->
    <bean id="people1" class="com.ssxxz.entity.People" autowire="byType">
        <property name="name" value="ups and downs"/>
    </bean>
</beans>

Summary:
When byName, it is necessary to ensure that the IDs of all beans are unique, and the bean needs to be consistent with the value of the set method of the automatically injected attribute
When byType, you need to ensure that the class es of all beans are unique, and the bean needs to be consistent with the type of automatically injected properties

5.2. Use notes to realize automatic assembly

Annotations supported by jdk1.5 annotations supported by spring 2.5

The introduction of annotation-based configuration raised the question of whether this approach is "better" than XML

Notes for use:

1. Import constraints: context constraints

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

2. Configuration annotation support

<context:annotation-config/>

<?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
       https://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/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">

   <!--Enable annotation support-->
   <context:annotation-config/>
</beans>

Add @ Autowired to the entity class to automatically assemble and import

5.3 @ Autowired and @ Resource

1,@Autowired

  • You can use it directly on the attribute! It can also be used in the set mode, so there is no need to write the setDog method
  • Using Autowired, we don't need to write the set method. The premise is that your auto assembled attribute exists in the IOC (Spring) container and conforms to the name byName

@Nullable

@The Nullable field is marked with this annotation, indicating that this field can be null;

//If it is marked, no error will be reported even if the name is empty
public People(@Nullable String name){
    this.name = name;
}

@Autowired can also be null, which is good

@The Autowired unique property defaults to true

public @interface Autowired{
    boolean required() default true;
}

If required = false, it can be null

public class People {
    //If the required property of Autowired is defined as false, it means that the object can be null, otherwise it is not allowed to be empty
    @Autowired(required = false)
    private Cat cat;
    @Autowired
    private Dog dog;
    private String name;
}

@Qualifier

If the environment of @ Autowired automatic assembly is complex and the automatic assembly cannot be completed through an annotation [@ Autowired], we can use @ Qualifier (value = "xxx") to configure the use of @ Autowired and specify a unique bean object injection!

public class People {
    @Autowired()
    private Cat cat;
    @Autowired
    @Qualifier(value = "xxx")
    private Dog dog;
    private String name;
}

2,@Resource

@The Resource annotation is similar to the byName and byType collection. First judge the id and then the class. If one can be injected, it will be successful. You can also specify the name value to use

public class People {
    @Resource(name = "xxxx")
    private Cat cat;

Summary: @ Resource and @ Autowired are different

  • They are used for automatic assembly and can be placed in the attribute field
  • @Autowired is implemented by byType, and this object must exist! If it is not unique, it needs to be implemented through @ Qualifier (value = "xxx")
  • @Resource is implemented by byName by default. If the name cannot be found, it is implemented by byType! If both cannot be found, an error will be reported!
  • Different execution order: @ Autowired is implemented by byType@ Resource is implemented by byName by default.

6. Using annotation development

After spring 4, to develop with annotations, you must ensure that the aop package is imported

To use annotations, you need to import context constraints and add annotation support!

<?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
        https://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/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

<!--Specify the package to be scanned, and the annotations under the package will take effect-->
<context:component-scan base-package="com.ssxxz.pojo"/>
<!--Enable annotation support-->
<context:annotation-config/>
</beans>

1. bean injection uses @ Componet annotation

Put it on the class, indicating that the class is managed by Spring, that is, bean

//@Component is equivalent to < bean id = "user" class = "com. Ssxxz. Entity. User" / >
//@Component component
@Component
public class User {
    String name;
}

test class

public static void main(String[] args){
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    //The bean id is the lowercase of the method name
    User user = (User) context.getBean("user");
    System.out.println(user.name());
    
}

The bean id is the lowercase of the method name

2. Attribute injection uses @ Value annotation

//@Component is equivalent to < bean id = "user" class = "com. Ssxxz. Entity. User" / >
@Component
public class User {
String name;
//@Value("ssxxz") is equivalent to < property name = "name" value = "ssxxz" / >
@Value("ssxxz")
public void setName(String name) {
    this.name = name;
}
}

3. Derived annotation

@Componet has several derived annotations. In web development, we will layer according to the mvc three-tier architecture!

  • dao layer [@ Repository]
  • Service layer [@ service]
  • Controller layer [@ controller]

The four annotation functions are the same. They all represent registering a class in Spring and assembling beans

4. Automatic assembly

  • @Autowired auto assembly type and name
    • If Autowired cannot uniquely auto assemble attributes, you need to pass @ Qualifier(value = "xxx")
  • @The Nullable field marks this annotation, indicating that this field can be null
  • @Resource is automatically assembled by name and type

5. Scope

@Scope("Singleton") singleton

@Scope("prototype")

@Component			@Component  assembly bean

@Scope("prototype")	//Scope
public class User {
String name;

@Value("ssxxz")		//Attribute injection
public void setName(String name) {
    this.name = name;
}
}

6. Summary
XML and annotations

  • xml is more versatile and suitable for any occasion! Simple and convenient maintenance

  • Annotations are not their own classes and cannot be used. Maintenance is relatively complex

XML and annotation best practices

  • xml is used to manage bean s
  • Annotations are only responsible for completing attribute injection
  • In the process of using, we only need to pay attention to one problem: to make the annotation effective, we need to turn on the annotation support
<!--Enable annotation support-->
<context:annotation-config/>
<!--Specify the package to be scanned, and the annotations under the package will take effect-->
<context:component-scan base-package="com.ssxxz"/>

7. Configure Spring in Java

Now we'll leave it entirely to Java without using Spring's xml configuration

JavaConfig used to be a subproject of Spring. After Spring 4, it became a core function

@Component is similar to beans

Entity class

@The annotation of Component here means that this class is taken over by Spring and registered in the container

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//The annotation here means that this class is taken over by Spring and registered in the container
@Component
public class User {
private String name;

public String getName() {
    return name;
}
@Value("ssxxz")//Attribute injection value
public void setName(String name) {
    this.name = name;
}
}

Configuration class

@Configuration represents this configuration class, which is the same as applicationContext.xml

@ComponentScan("com.ssxxz.pojo") scans packages

@Bean registering a bean is equivalent to a bean tag we wrote earlier

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

//@Configuration, which will also be managed by the Spring container and registered in the container. Because the annotation is opened, it itself is defined as a Component @ Component
//@Configuration represents that this is a configuration class, which is the same as applicationContext.xml
@Configuration
@ComponentScan("com.ssxxz.pojo")
//Introduce other classes
@Import(ssConfig2.class)

public class YangConfig {
//Registering a bean is equivalent to a bean tag we wrote earlier
//Method name = = id of bean tag
//Return value of method = = class attribute in bean tag
@Bean
public User getUser () {
    return new User();//Is to return the object to be injected into the bean
}
}

Test class

public class MyTest {
public static void main(String[] args) {
//If the configuration class method is completely used, we can only obtain the container through the ApplicationContext context and load it through the class object of the configuration class
ApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(YangConfig.class);
    //"getUser" is a lowercase configuration method name
    User getUser = (User)annotationConfigApplicationContext.getBean("getUser");
    System.out.println(getUser.getName());
}
}

Configuration class of ApplicationContext annotation

This pure Java configuration method can be seen everywhere in SpringBoot

8. Agent mode

The bottom layer of spring AOP is the proxy pattern [spring AOP and spring MVC]

Classification of agent mode:

  • Static proxy
  • Dynamic agent

Agent model of rental

8.1 static agent

Role analysis:

  • Abstract role: it is usually solved by using interfaces or abstract classes
  • Real role: the role represented
  • Agent role: represent the real role. After representing the real role, we usually do some ancillary operations
  • Client: the person who accesses the proxy object

Code steps:

  1. Interface - rental

    //Rent a house
    public interface Rent{
        public void rent();
    }
    
  2. Real role - landlord

    public calss Host interface Rent{
        public void rent(){
            System.out.println("The landlord wants to rent the house!");
        }
    }
    
  3. Agent role - Mediation

    public calss Proxy interface Rent{
    	private Host host;
        public Proxy(){
        }
        public Proxy(Host host){
        	this.host = host;
        }
        //The landlord only needs to rent the house
        //But the intermediary agent rents other affairs
        public void rent(){
            seeHouse();
            host.rent();
            hetong();
            fare();
        }
        //House viewing
        public void seeHouse(){
           System.out.println("The agent will show you the house!"); 
        }
        //sign a contract
        public void seeHouse(){
           System.out.println("Sign the lease contract!"); 
        }
        //Intermediary fee
        public void seeHouse(){
           System.out.println("Charge intermediary fee!"); 
        }
        
    }
    
  4. Client access agent role

    public calss Client{
    	//The landlord wants to rent a house
        Host host = new Host();
        //Agents, intermediaries help landlords rent houses, or are there other ancillary operations
        Proxy proxy = new Proxy(host);
        //You don't have to face the landlord, just find an intermediary to rent a house
        proxy.rent();
    }
    

Benefits of agent mode:

  • It can make the operation of real characters more concise! Don't pay attention to some public business
  • The public is handed over to the agent role to realize the division of business
  • When the public business is expanded, it is convenient for centralized management

Disadvantages:

  • A real role will produce a proxy role, the amount of code will double, and the development efficiency will be low

Re understanding

Horizontal development of agent model

Add a log function to the original code

In order to ensure the security of the original code, you can't change it directly. You need to add a proxy class and add the log function

Interface class

public interface UserService{
    public void add();
    public void delete();
    public void upadte();
    public void query();
}

Implementation class

public class UserServiceImpl interface UserService{
    public void add(){
        System.out.println("Added a user!"); 
    };
    public void delete(){
        System.out.println("Deleted a user!");
    };
    public void upadte(){
        System.out.println("Modified a user!");
    };
    public void query(){
        System.out.println("Queried a user!");
    };
}

proxy class

Create agent class and add log function

public class UserServiceProxy interface UserService{
    //Create a set method to get the entity class
    private UserServiceImpl userService;
    public void setUserService(UserService userService){
        this.userService = userService;
    }
    
    public void add(){
        log("add");
        userService.add();
    };
    public void delete(){
        log("delete");
        userService.delete();
    };
    public void upadte(){
        log("upadte");
        userService.upadte();
    };
    public void query(){
        log("query");
        userService.query();
    };
    
    //Log method
    public void log(String msg){
        System.out.println("[Debug] Used"+msg+"method");
    }
}

Test class

public class Client(){
    public static void main(String[] args) {
        //Create entity class
        UserServiceImpl userService = new UserServiceImpl();
        //Create proxy class
        UserServiceProxy proxy = new UserServiceProxy();
        //Passing an entity class into a proxy to associate
        proxy.setUserService(userService);
        
        proxy.query();
    }
}

Changing the original business code is a big taboo in the company!

8.2 dynamic agent

  • Dynamic agents have the same role as static agents
  • The proxy class of dynamic proxy is generated dynamically, which is not written directly
  • Dynamic agents are divided into two categories: interface based dynamic agents and class based dynamic agents
    • Interface based: JDK dynamic agent
    • Class based: cglib
    • java bytecode implementation: javasist

You need to know two classes:

  • Proxy: proxy, which provides static methods for dynamic proxy classes and instances
  • InvocationHandler: the implementation class interface of the calling handler

1. Common method test

Call processing tool class

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//We will use this class to automatically generate the class of the proxy class
public class ProxyInvocationHandler implements InvocationHandler {
//Proxy interface
private Rent rent;

public void setRent (Rent rent) {
    this.rent = rent;
}

//Generated proxy class
public Object getProxy () {
    return Proxy.newProxyInstance(this.getClass().getClassLoader(),
            rent.getClass().getInterfaces(), this);
}

//Process the proxy instance and return the result
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //The essence of dynamic agent is to use reflection mechanism!
    seeHouse();
    Object result = method.invoke(rent, args);
    fare();
    return result;
}
//Add your own proxy method
public void seeHouse(){
    System.out.println("Show me the house");
}
public void fare(){
    System.out.println("Intermediary fee");
}
}

Test, create proxy class and test together

public class Client {
    public static void main(String[] args) {
        //Real role
        Host host = new Host();
        
        //Agent role, does not exist, create agent tool
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        //Handle the interface object (real role) we want to call by calling the program processing role (proxy tool)
        pih.setRent(host);
        
        //Proxy is a dynamically generated proxy class. We didn't write it
        Rent proxy = (Rent)pih.getProxy();
        proxy.rent();
    }
}

2. Abstract method testing

The interface type of the proxy is not written dead and becomes an abstract Object class

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//Automatically generate classes for proxy classes
public class ProxyInvocationHandler implements InvocationHandler {
//Proxy interface
private Object target;

public void setTarget (Object target) {
    this.target = target;
}

//Generated proxy class
public Object getProxy () {
    return Proxy.newProxyInstance(this.getClass().getClassLoader(),
            target.getClass().getInterfaces(), this);
}

//Process the proxy instance and return the result
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //Get the name of the method being executed through reflection
    log(method.getName());
    Object result = method.invoke(target, args);
    return result;
}
//Add a dynamic logging method
public void log (String msg) {
    System.out.println("Yes" + msg + "method");
}
}

Entity class

public class UserServiceImpl implements UserServiceInterface{
    public void add() {
        System.out.println("Add a user");
    }
    public void delete() {
        System.out.println("Delete a user");
    }
    public void update() {
        System.out.println("Update a user");
    }
    public void select() {
        System.out.println("Retrieve a user");
    }
}

Test class

public class Client {
    public static void main(String[] args) {
        //Real role
        UserServiceImpl userService = new UserServiceImpl();
        //Proxy role, does not exist
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        //Sets the object to proxy
        pih.setTarget(userService);
        //Dynamically generate proxy classes
        UserService proxy = (UserService)pih.getProxy();
        proxy.add();
    }
}

3. Benefits of dynamic agents

  • It can make the operation of real characters more pure! Don't pay attention to some public business
  • The public will be handed over to the agent role! The division of business is realized
  • When sending and expanding public services, it is convenient for centralized management!
  • A dynamic agent class represents an interface, which is generally a corresponding type of business
  • A dynamic proxy class can proxy multiple classes as long as it implements the same interface

9,AOP

9.1. What is AOP

AOP (Aspect Oriented Programming) means: Aspect Oriented Programming, which realizes the unified maintenance of program functions through precompiled mode and runtime dynamic agent. AOP is the continuation of OOP, a hot spot in software development, an important content in Spring framework and a derived generic of functional programming. AOP can isolate each part of business logic, reduce the coupling between each part of business logic, improve the reusability of program, and improve the efficiency of development.

9.2. The role of Aop in Spring

Provide life transaction: allows users to customize aspects

  • Crosscutting concerns: methods or functions that span multiple modules of an application. That is, the part that has nothing to do with our business logic, but we need to focus on is crosscutting concerns. Such as log, security, cache, transaction and so on
  • ASPECT: a special object whose crosscutting concerns are modularized. That is, it is a class
  • Advice: the work that must be done in the aspect, that is, it is a method in the class
  • target: the notified object
  • Proxy: an object created after notification is applied to the target object
  • PointCut: the definition of the "place" where the aspect notification is executed
  • Join point: the execution point that matches the pointcut

In Spring AOP, crosscutting logic is defined through Advice. There are five types of Advice supported in Spring

That is, Aop adds new functions without changing the original code

9.3. Using Spring to implement Aop

[key] AOP weaving requires dependent packages

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

Method 1: use the Spring API interface

[mainly spring API interface implementation]

com.ssxxz.service

UserServer interface

public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void select();
}

com.ssxxz.service

UserServer implementation class

public class UserServiceImpl implements UserService{
    public void add() {
        System.out.println("Added a user");
    }
    public void delete() {
        System.out.println("A user was deleted");
    }
    public void update() {
        System.out.println("A user has been updated");
    }
    public void select() {
        System.out.println("A user was retrieved");
    }
}

com.ssxxz.log

Before Log class execution

import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
	//MethodBeforeAdvice 	 Before execution

public class Log implements MethodBeforeAdvice {
    //Method: the method of the target object to be executed (method being invoked)
    //object: arguments to the method
    //o: Target: target of the method invocation
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName() + "of" + method.getName() + "Executed");
    }
}

After the AfterLog class is executed

import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
	//After returning advice is executed
public class Log implements  AfterReturningAdvice {

    //returnValue: return value
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("Yes" + method.getName() + "Method, the return value is" + returnValue);
    }
}

configuration file

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"
       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">
    
    <!--register bean-->
    <bean id="userService" class="com.ssxxz.service.UserServiceImpl"/>
    <bean id="log" class="com.ssxxz.log.Log"/>
    <bean id="afterLog" class="com.ssxxz.log.AfterLog"/>
    
    <!--Method: use native Spring Api Interface-->
    <!--to configure aop;Import required aop Constraints of-->
    <aop:config>
    <!--Entry point: execution:expression, execution(*(Modifier) *(Return value) *(Class name) *(Method name) *(parameter))  ..Arbitrary parameter-->
     <!--Methods protect you from executing at this entry point-->
    <aop:pointcut id="pointcut" expression="execution(* com.ssxxz.service.UserServiceImpl.*(..))"/>

    <!--Execute surround increase-->
    <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
    <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>   
</aop:config>
    <!--hold log This class, cut into pointcut Method-->
</beans>

Test class

import com.ssxxz.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //The dynamic proxy is the interface, and the entity class will report an error
        UserService userService = context.getBean("userService", UserService.class);
        userService.add();
    }
} 

Method 2: Customize to implement AOP

[mainly section definition]

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"
       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">
    <!--register bean-->
    <bean id="userService" class="com.ssxxz.service.UserServiceImpl"/>
    <bean id="log" class="com.ssxxz.log.Log"/>
    <bean id="afterLog" class="com.ssxxz.log.AfterLog"/>
    
    <!--Method 2: custom class-->    
    <bean id="diy" class="com.ssxxz.diy.DiyPointCut"/>
    <aop:config> 
        <!-- Custom cut, ref Class to import-->
        <aop:aspect ref="diy">
            
            <!--breakthrough point AspectJ Pointcut expression for-->
            <aop:pointcut id="point" expression="execution(* com.ssxxz.service.UserServiceImpl.*(..))"/>
            
            <!--Notice,"before"Find it by yourself-->
            <aop:before method="before" pointcut-ref="point"/>
            <aop:after method="after" pointcut-ref="point"/>
        </aop:aspect>
    </aop:config>
</beans>

Custom class

com.ssxxz.diy

DiyPointCut

public class DiyPointCut {
    public void before(){
        System.out.println("===Before method execution===");
    }
    public void after(){
        System.out.println("===After method execution===");
    }
}

Method 3: implement AOP with annotations

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
//Be careful not to reverse the package. The package that needs annotation
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect	//Label this class as a facet 
public class AnnotationPointcut {
    //breakthrough point
    @Before("execution(* com.ssxxz.service.UserServiceImpl.*(..))")
    public void before () {
        System.out.println("====Before method execution====");
    }
    @After("execution(* com.ssxxz.service.UserServiceImpl.*(..))")
    public void after () {
        System.out.println("====After method execution====");
    }
    //In surround enhancement, we can give a parameter representing the point where we want to get the processing pointcut
    @Around("execution(* com.ssxxz.service.UserServiceImpl.*(..))")
    public void around (ProceedingJoinPoint jp) throws Throwable {
        System.out.println("Surround front");
        
        Signature signature = jp.getSignature();//Get the signature and execute that method
        System.out.println("signature" + signature);
        
        //Execution method
        Object proceed = jp.proceed();//Execution method
    	System.out.println("After surround");
	}
}

Execution sequence: "before wrapping" → "before method execution" → (execution method) → "after wrapping" → "after mode execution"

XML 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"
       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">
    
    <!--register bean-->
    <bean id="userService" class="com.ssxxz.service.UserServiceImpl"/>
    <!--Method 3: use annotation-->
    <!--Enable annotation support  JDK(default proxy-target-class="false")cglib default proxy-target-class="true")-->
    <aop:aspectj-autoproxy proxy-target-class="false"/>
    <bean id="annotationPointCut" class="com.ssxxz.diy.AnnotationPointcut"/>
<beans/>

10. Integrate Mybatis

Steps:

  1. Import related jar packages
  2. Write configuration file
  3. test

1. Import related jar packages

  • junit
  • mybatis
  • mysql database
  • spring related
  • aop weaving
  • mybatis-spring
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>spring-study</artifactId>
        <groupId>com.ssxxz</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
<artifactId>spring-10-mybatis</artifactId>

<dependencies>
    
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>
    <!--Spring If you operate the database, you also need one spring-jdbc-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.4</version>
    </dependency>
    
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.13</version>
    </dependency>
    
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.2</version>
    </dependency>
 
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.10</version>
    </dependency>
</dependencies>

<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>
</project>

10.1. Recall mybatis

1. Writing entity classes

User

com.ssxxz.pojo

@Data
public class User{
    private int id;
    private String name;
    private String pwd;
}

2. Write core configuration file

mybatis-config.xml

resources

<?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>
    
  <typeAliases>
  	<package name="com.ssxxz.pojo"/>  
  </typeAliases>
    
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/><!-- transaction management -->
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode&amp;characterEncoding=UTF-8"/>
        <!-- Account password -->
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
      <mapper class="com.ssxxz.mapper.UserMapper"/>
  </mappers>
</configuration>

3. Write interface

UserMapper.java

com.ssxxz.mapper

public interface UserMapper {
    public List<User> selectUser();
}

4. Write Mapper.xml

UserMapper.xml

com.ssxxz.mapper

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssxxz.mapper.UserMapper">
    
    <select id="selectUser" resultType="user">
        select * from mybatis.user;
    </select>
</mapper>

5. Testing

public class MyTest {
    @Test
    public void test () throws IOException {
        String resources ="mybatis-config.xml";
        InputStream in = Resources.getResourcesAsStream(resources);
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
        SqlSession sqlSession = sessionFactory.openSession(true);
        
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = mapper.selectUser();
        
  		for (User user : userList) {
       		System.out.println(user);
   		}
	}
}

10.2,MyBatis-Spring

Official document address: https://mybatis.org/spring/zh/index.html

MyBatis Spring will help you seamlessly integrate MyBatis code into Spring. It will allow MyBatis to participate in Spring's transaction management, create mapper s and sqlsessions and inject them into bean s, and convert MyBatis exceptions into Spring's DataAccessException. Finally, you can make the application code independent of MyBatis, Spring or MyBatis Spring.

< bean id = "datasource" class = "org. Springframework. JDBC. Datasource. Drivermanagerdatasource" > this package is required

    <!--Spring If you operate the database, you also need one spring-jdbc-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.1.9.RELEASE</version>
    </dependency>

Steps:

  1. Write data source configuration
  2. SqlSessionFactory
  3. SqlSessionTemplate
  4. You need to add an implementation class to the interface
  5. Write your own implementation class and inject it into Spring
  6. Test and use

Write a configuration file instead of mybatis

spring-dao.xml

resources

<?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">
    <!-- DataSource: use Spring Data source replacement for Mybatis Configuration of c3p0 dbcp druid
	We use it here Spring Provided JDBC:  org.springframework.jdbc.datasource
-->
    <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?useSSL=true&amp;useUnicode&amp;characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>
    
    <!-- sqlSessionFactory Injection data source -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  		<property name="dataSource" ref="dataSource" />
        <!--binding Mabatis configuration file-->
        <property name="configLocation" value="classpath:mybatis-config.xml" />
        <property name="mapperLocations" value="classpath:com/ssxxz/mapper/*.xml" />
	</bean>
    
    <!-- sqlSessionTemplate:That's what we use salSession -->
    <bean id="sqlSession" class="org.mybatis.spring.sqlSessionTemplate">
    	<!--Only constructor injection can be used sqlSessionFactory,Because it doesn't set method-->
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>
    
    <!--to configure SqlSessionTemplate object-->
    <bean id="userMapper" class="com.ssxxz.mapper.UserMapperImpl">
    	<property name="sqlSession" ref="sqlSession"/>
    </bean>
</beans>

In this way, most of them can be set here. Mabatis only leaves some settings

Xxtemplate will often be used in the future: templates, such as redisTemplate and thymeTemplate

You can also export the configuration object so that the database content does not need to be modified

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">

    <inport resource="spring-dao.xml"/>
    
    <!--to configure SqlSessionTemplate object-->
    <bean id="userMapper" class="com.ssxxz.mapper.UserMapperImpl">
    	<property name="sqlSession" ref="sqlSession"/>
    </bean>
</beans>

You need to add another object implementation class

SqlSessionTeamplate

public class UserMapperImpl implements UserMapper{
    //It turns out that all our operations are performed using sqlSession
    //Now use SqlSessionTemplate
    private SqlSessionTeamplate sqlSession;
    public void setSqlSession(SqlSessionTeamplate sqlSession){
        this.sqlSession = sqlSession;
    }
    
    public List<User> selectUser(){
        UserMapper mapper = sqlSession.getMapper(UserMapper,class);
        return mapper.selectUser();
    }
}

Before writing the method to the test class, the method is written to the object, and only needs to be invoked in the test class.

Test class

public class MyTest {
    @Test
    public void test () throws IOException {
        ApplicationContext context = new ClassPathXmlApplicationContext("sqring-dao.xml");
        UserMapper userMapper = context.getMapper("userMapper",UserMapper.class);
      	for (User user : userMapper.selectUser) {
       		System.out.println(user);
   		}
	}
}

10.3. Simplify SqlSessionDaoSupport

SqlSessionDaoSupport is an abstract support class used to provide you with SqlSession. Call getSqlSession() method and you will get a SqlSessionTemplate, which can be used to execute SQL methods, as follows:

import com.ssxxz.entity.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import java.util.List;
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper {
    public List<User> selectUser() {
        SqlSession sqlSession = getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = mapper.selectUser();
        //return getSqlSession().getMapper(UserMapper.class).selectUser();
        return users;
    }
}

In addition, there is no need to inject attributes. You can directly inject the parent class sqlSessionFactory

<bean id="userMapper" class="com.ssxxz.mapper.UserMapperImpl">
    	<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>

Mybatis plug-in: mybatis plus, general mybatis

11. Declarative transaction

1. Review transactions

  • Treat a group of businesses as a business, either all succeed or all fail!
  • Transaction is very important in project development. It involves data consistency and cannot be careless
  • Ensure integrity and consistency

Transaction ACID principle:

  • Atomicity
  • uniformity
  • Isolation
    • Multiple businesses may operate the same resource to prevent data corruption
  • persistence
    • Once the transaction is committed, no matter what problem the system sends, the result will not be affected and will be written to the memory persistently

2. Transaction process review

  1. pom dependency
  2. pojo entity class
  3. UserMapper interface
  4. mybatis
    • Configuration file mybatis-config.xml
  5. Integrate mybatis - spring-dao.xml
    • Configure data sources
    • SqlSessionFactory
    • SqlSession
  6. UserMapper.xml input sql statement
  7. UserMapper implementation class - inherits SqlSessionDaoSupport
  8. Configure Srping - applicationContext.xml
  9. test

Finally, the test shows that even if there are sql statement errors and program execution fails, other correct sql statements will be executed successfully, which does not comply with the transaction ACID consistency principle

3. Transaction management in Srting

If one program fails, make sure that other programs fail at the same time

  • Declarative transaction: AOP, the code is crosscut and does not affect the original code
    • Container managed transactions
  • Programming transaction: it is necessary to manage the transaction in the code
    • Use try catch

Declarative transaction

  1. Transaction processor configuration declaration

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

  1. Then the container manages the transaction and imports the tx transaction
  2. Configure transaction entry

spring-dao.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"
       
       xmlns:tx="http://www.springframework.org/schema/tx"
       
       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
                           
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">
    
    <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?useSSL=true&amp;useUnicode&amp;characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  		<property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:mybatis-config.xml" />
        <property name="mapperLocations" value="classpath:com/ssxxz/mapper/*.xml" />
	</bean>
    <bean id="sqlSession" class="org.mybatis.spring.sqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>
    <!-- Configure declarative transactions -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
	</bean>
    
    <!-- combination AOP Implement transaction weaving -->
    <!-- Configuring transaction notifications, importing tx affair-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
    <!--For which methods are transactions configured-->
    <!--Configure propagation properties of transactions propagation-->
    <tx:attributes>
        <tx:method name="add" propagation="REQUIRED"/>
        <tx:method name="delete" propagation="REQUIRED"/>
        <tx:method name="update" propagation="REQUIRED"/>
        <!--read-only="true read-only-->
        <tx:method name="select" read-only="true"/>
        <!--All methods-->
        <tx:method name="*" propagation="REQUIRED"/>
    </tx:attributes>
	</tx:advice>
    
    <!--Configure transaction entry-->
    <aop:config>
        <!--mapper All classes, all methods and parameters under-->
        <aop:pointcut id="txPointCut" expression="execution(* com.ssxxz.mapper.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>
    
</beans>

Configure propagation properties of transactions

  • PROPAGATION_REQUIRED: if there is no transaction currently, create a new transaction. If there is already a transaction, join it. This is the most common choice and the default choice.
  • PROPAGATION_SUPPORTS: supports the current transaction. If there is no current transaction, it will be executed in a non transaction method.
  • PROPAGATION_MANDATORY: use the current transaction. If there is no current transaction, an exception will be thrown.
  • PROPAGATION_REQUIRES_NEW: create a new transaction. If there is a current transaction, suspend the current transaction.
  • PROPAGATION_NOT_SUPPORTED: perform the operation in a non transactional manner. If there is a current transaction, suspend the current transaction.
  • PROPAGATION_NEVER: execute the operation in a non transactional manner. If the current transaction exists, an exception will be thrown.
  • PROPAGATION_NESTED: if a transaction currently exists, it is executed within a nested transaction. If there is no current transaction, execute the same as the deployment_ Required similar operations

Think, why do you need business?

  • If the transaction is not configured, there may be inconsistent data submission
  • If we do not configure declarative transactions in SPRING, we need to manually configure transactions in the code
  • Transaction is very important in the development of the project. The consistency and integrity of data should not be sloppy

Tags: Java Spring

Posted on Sat, 02 Oct 2021 19:25:47 -0400 by djBuilder