Spring (IOC, hellosppring, dependency injection, automatic assembly of bean s, annotation, spring integration, Mybatis, declarative transaction...)

Posted by benny_g on Fri, 28 Jan 2022 11:21:23 +0100

1 Spring

1.1 INTRODUCTION

  • Spring
  • SSH: Strust2 + Spring + Hibernate
  • SSM: SpringMvc + Spring + Mybatis

Official website: https://docs.spring.io/spring-framework/docs/current/reference/html/overview.html#overview

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

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

1.2 advantages

  • Spring is an open source free framework (container)
  • Spring is a lightweight, non intrusive framework!
  • Inversion of control (IOC), aspect oriented programming (AOP)
  • Support transaction processing and framework integration!

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

1.3 composition

1.4 expansion

  • Spring Boot builds everything

    A rapid development scaffold, based on SpringBoot, can quickly develop a single micro service. The contract is greater than the configuration.

  • Spring Cloud coordinates everything

    Based on SpringBoot.

  • Spring Cloud Data Flow connects everything

Now most companies are using SpringBoot for rapid development. To learn the premise of SpringBoot, you need to fully master Spring and Spring MVC! The role of connecting the preceding and the following.

Disadvantages: after development for too long, it violates the original concept, and the configuration is very cumbersome.

2 IOC theoretical derivation

Project structure diagram:

  1. UserDao interface

  2. UserDaoImpl implementation class

  3. UserService business interface

  4. UserServiceImpl business implementation class

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

We use a set interface implementation, which has undergone revolutionary changes!

private UserDao userDao;

//Dynamic value injection using set
public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
}
  • 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 receiving object. No matter how the program is created, it is only responsible for providing an interface.

This idea essentially solves the problem, and programmers no longer manage the creation of objects. The coupling of the system is greatly reduced, so we can focus more on the implementation of business. This is the prototype of IOC!

IOC essence

Control inversion IOC is a design idea. DI (dependency injection) is a method to realize IOC. Some people think that IDI is just another way of saying IOC. In programs without IOC, we use object-oriented programming. The creation of objects and the dependencies between objects are completely hard coded. In programs, 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.

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 provide a third party. In Spring, the Ioc container implements control inversion, and its implementation method is dependency injection.

3 HelloSpring

Entity class: user java

The set method is the core of spring.

package com.zsf.pojo;

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 + '\'' +
                '}';
    }
}

Configuration 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 objects, in Spring These are called Bean
 Type variable name = new type();
Hello hello = new Hello();
bean = object  new Hello()

id = Variable name
class = new Object of
property This is equivalent to setting a value for an attribute in an object
-->
    <bean id="hello" class="com.zsf.pojo.Hello">
        <property name="str" value="Spring"/>
    </bean>
</beans>

Test:

public class Mytest {
    public static void main(String[] args) {

        //Get the context object of Spring
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //Our objects are now managed in Spring. If we want to use them, we can take them out directly
        Hello hello = (Hello) context.getBean("hello");
        System.out.println(hello.toString());
    }
}

For the IOC theory in 2, use spring to write

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

    <bean id="mysqlImpl" class="com.zsf.dao.UserDaoMysqlImpl"/>
    <bean id="oracleImpl" class="com.zsf.dao.UserDaoOracleImpl"/>

    <bean id="UserServiceImpl" class="com.zsf.service.UserServiceImpl">
    <!--
    ref:quote Spring Created object in container
    value:Specific value, basic data type
    -->
        <property name="UserDao" ref="mysqlImpl"/>
    </bean>

</beans>

Test:

public class Mytest {
    public static void main(String[] args) {
        //Get ApplicationContext: get the container of spring
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        //The container is in hand. If you need anything, you can get it directly
        UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean("UserServiceImpl");

        userServiceImpl.getUser();
    }
}

Now, we don't need to change it in the program. To realize different operations, we only need to modify it in the xml configuration file.

  • Who created the Hello object?
    • The Hello object is created by Spring
  • How are the properties of the Hello object set?
    • The properties of the hello object are set by the Spring container,

This process is called control reversal!

4 how IOC creates objects

  1. Use parameterless construction to create objects. Default!

    public class User {
        private String name;
    
        //As long as the user is new, this method will be called
        public User(){
            System.out.println("user Nonparametric structure of");
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        public void show(){
            System.out.println("name="+name);
        }
    }
    
    <bean id="user" class="com.zsf.pojo.User">
        <property name="name" value="beisheng"/>
    </bean>
    
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    
    User user = (User) context.getBean("user");
    
    user.show();
    
  2. Suppose you want to create an object using a parametric build.

    1. Subscript assignment

      <!--Parameter subscript assignment-->
          <bean id="user" class="com.zsf.pojo.User">
              <constructor-arg index="0" value="SpringStudy"/>
          </bean>
      
    2. Create by type

      <!--The second is to create by type. It is not recommended to use it. If both parameters are String Type, it won't work-->
      <bean id="user" class="com.zsf.pojo.User">
          <constructor-arg type="java.lang.String" value="beisheng"/>
      </bean>
      
    3. Parameter name

      <!--The third method: set directly through the parameter name-->
      <bean id="user" class="com.zsf.pojo.User">
          <constructor-arg name="name" value="beisheng"/>
      </bean>
      

Summary: the Spring container is similar to the matchmaking website. All xml bean s have been instantiated as soon as they are registered. If you want to use them, you can get them directly.

When the configuration file is loaded, the objects managed in the container have been initialized.

5 Spring configuration

1. Alias

<!--Alias. If an alias is added, we can also use the alias to get this object-->
    <alias name="user" alias="user Alias for"/>

2. Bean configuration

<!--
id:bean The unique identifier of, which is equivalent to the object name we learned
class: bean Fully qualified name corresponding to the object: package name + type
name: It's also an alias, and name Multiple aliases can be taken at the same time
-->
    <bean id="userT" class="com.zsf.pojo.UserT" name="user2,u2">
        <property name="name" value="beisheng"/>
    </bean>

3,import

It is generally used for team development. It can import and merge multiple configuration files into one

Suppose that there are multiple developers in the project, different people are responsible for different class development, and different classes need to be registered in different beans. We can use import to import everyone's beans XML is merged into a total. If there are duplicate names, the contents will be merged automatically.

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

6 dependency injection

1. Constructor injection

2. Set mode injection [ key ]

  • Dependency injection: Set injection!
    • Dependency: the creation of bean objects depends on the container
    • Injection: all properties in the bean object are injected by the container

[environment construction]

1. Complex type

Entity class Student

package com.zsf.pojo;

import java.util.*;

public class Student {
    private String name;//Assignment by value
    private Address address;//Assignment by ref
    private String[] books;
    private List<String> hobbies;
    private Map<String,String> card;
    private Set<String> games;
    private String wife;
    private Properties info;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public String[] getBooks() {
        return books;
    }

    public void setBooks(String[] books) {
        this.books = books;
    }

    public List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }

    public Map<String, String> getCard() {
        return card;
    }

    public void setCard(Map<String, String> card) {
        this.card = card;
    }

    public Set<String> getGames() {
        return games;
    }

    public void setGames(Set<String> games) {
        this.games = games;
    }

    public String getWife() {
        return wife;
    }

    public void setWife(String wife) {
        this.wife = wife;
    }

    public Properties getInfo() {
        return info;
    }

    public void setInfo(Properties info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", address=" + address.toString() +
                ", books=" + Arrays.toString(books) +
                ", hobbies=" + hobbies +
                ", card=" + card +
                ", games=" + games +
                ", wife='" + wife + '\'' +
                ", info=" + info +
                '}';
    }
}

Entity class Address

package com.zsf.pojo;

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 + '\'' +
                '}';
    }
}

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

<!--    Let it be here first xml Inside-->
    <bean id="address" class="com.zsf.pojo.Address">
        <property name="address" value="Wuhan"></property>
    </bean>

    <bean id="student" class="com.zsf.pojo.Student">
<!--        The first: normal value injection: value-->
        <property name="name" value="beisheng"/>

<!--        Second: Bean Injection: ref-->
        <property name="address" ref="address"/>

<!--        Third: array injection: ref-->
        <property name="books">
            <array>
                <value>The Dream of Red Mansion</value>
                <value>Journey to the West</value>
                <value>Water Margin</value>
            </array>
        </property>

<!--        Fourth: List-->
        <property name="hobbies">
            <list>
                <value>listen to the music</value>
                <value>watch movie</value>
            </list>
        </property>

<!--        Fifth: Map-->
        <property name="card">
            <map>
                <entry key="ID" value="123456789"></entry>
                <entry key="bank card" value="111111111"></entry>
            </map>
        </property>

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

<!--        Seventh: null Value injection-->
        <property name="wife">
            <null></null>
        </property>

<!--        Eighth: Properties-->
        <property name="info">
            <props>
                <prop key="Student number">001</prop>
                <prop key="Gender">male</prop>
                <prop key="full name">millet</prop>
            </props>
        </property>


    </bean>

</beans>

Test class

public class Mytest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans1.xml");
        Student stu = (Student) context.getBean("student");
        System.out.println(stu.toString());
    }
}

3. Expansion mode injection

We can use p namespace and c namespace for injection

Official interpretation

use

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

<!--    p Namespace injection, you can directly inject the value of the attribute: property-->
    <bean id="user" class="com.zsf.pojo.User" p:name="beisheng" p:age="18">

<!--    c Namespace injection, which can be injected through the constructor: construct-args-->
    </bean>
    <bean id="user2" class="com.zsf.pojo.User" c:age="17" c:name="bbb">

    </bean>
</beans>

test

@Test
    public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        User user1 = context.getBean("user", User.class);
        User user2 = context.getBean("user2", User.class);
        System.out.println(user1);
        System.out.println(user2);
    }

Note: p naming and c namespace cannot be used directly. You need to import xml constraints!!

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

4. Scope of bean

1. Singleton mode

Spring default mechanism

You can add the following after the bean:

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

2. Prototype mode

Every time you get from the container, a new object will be generated!

Especially a waste of resources.

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

3. Others

request, session and application can only be used in web development!

7 automatic assembly of bean

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

There are three ways to assemble in Spring

  1. Configuration displayed in xml [talked about]
  2. Display configuration in java
  3. Implicit automatic assembly bean [key]

1. Testing

Environment construction: a person has two pets.

<bean id="cat" class="com.zsf.pojo.Cat"/>
    <bean id="dog" class="com.zsf.pojo.Dog"/>
    <bean id="people" class="com.zsf.pojo.People">
        <property name="name" value="beisheng"/>
        <property name="cat" ref="cat"/>
        <property name="dog" ref="dog"/>
    </bean>

2. ByName auto assembly

It can be injected only by ensuring that the id value is the same as the set method value

    <bean id="cat" class="com.zsf.pojo.Cat"/>
    <bean id="dog" class="com.zsf.pojo.Dog"/>
    <bean id="dog2" class="com.zsf.pojo.Dog"/>
<!--   
 byName: It will automatically find its own objects in the container context set The value after the method corresponds to beanid!
 -->
    <bean id="people" class="com.zsf.pojo.People" autowire="byName">
        <property name="name" value="beisheng"/>
    </bean>

3. ByType auto assembly

The type must be globally unique, or an error will be reported.

id can also be omitted

    <bean id="cat" class="com.zsf.pojo.Cat"/>
<!--    <bean id="dog" class="com.zsf.pojo.Dog"/>-->
    <bean id="dog2" class="com.zsf.pojo.Dog"/>
<!--
 byType: It will automatically find the object with the same object type in the container context bean!
 -->
    <bean id="people" class="com.zsf.pojo.People" autowire="byType">
        <property name="name" value="beisheng"/>
    </bean>

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 of all beans is unique, and this bean needs to be consistent with the type of automatic injection!

4. Automatic assembly using annotations

jdk1.5 supported annotations. spring2.5 supports annotation!

To use notes:

  1. Import constraint: context constraint: Context: annotation config/
  2. Configuration 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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

</beans>

Autowired

You can use it directly on the attribute! It can also be used in set mode!

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!

Equivalent to byname and bytype.

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.

When multiple beans in xml point to the same entity class (and the id value is different from the entity name), it will not be recognized with only one Autowired. Now, if you want to inject multiple beans, you need to introduce @ Qualifier to specify the value as the id value of the bean in the xml.

@Autowired
@Qualifier(value = "dog222")
private Dog dog;
<bean id="dog222" class="com.zsf.pojo.Dog"/>
<bean id="dog111" class="com.zsf.pojo.Dog"/>

The @ Resource annotation: first find it by name, and then find it by type. If you can't find it, an error will be reported (this is the native of java and has nothing to do with spring)

Summary:

@Difference between Resource and @ Autowired:

  • They are used for automatic assembly and can be placed in the attribute field
  • @Autowired is implemented by bytype, and the object must have [common]
  • @Resource is implemented by byname. If the name cannot be found, it is implemented by bytype. If both cannot be found, report an error! [common]
  • Execution order is different

8 development using annotations

After spring 4, if you want to develop with annotations, you must ensure the import of aop package

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

  1. bean

  2. How to inject attributes

    //Equivalent to < bean id = "user" class = "com. ZSF. POJO. User" / >
    //If the Component component is complex, it is recommended to use the configuration file
    @Component
    public class User {
        //Equivalent to < property name = "name" value = "being" / >
        @Value("beisheng")
        public String name;
    }
    
  3. Derived annotation

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

    • dao[@Repository]

    • service[@Service]

    • controller[@Controller]

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

  4. automatic assembly

    • @Autowired: automatically assemble a type name. If Autowired cannot uniquely assemble attributes, it needs to pass @ Qualifier (value = "xxx")
    • @The Nullable field marks this annotation, indicating that this field can be null
    • @Resource: name and type of automatic assembly
  5. Scope

    @Scope: specify singleton mode or prototype mode

    @Component
    @Scope("singleton")
    public class User {
        //Equivalent to < property name = "name" value = "being" / >
        @Value("beisheng")
        public String 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

    Best practices:

    • xml is used to manage bean s;

    • Annotation is only responsible for completing attribute injection;

    • In the process of using, we only need to pay attention to one problem: if we must make the annotation effective, we need to turn on the annotation support

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

9 configure Spring in Java

Now we have to completely leave the xml configuration of Spring to Java.

JavaConfig is a subproject of Spring. After Spring 4, it has become a core function.

Entity class user java:

//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("beisheng")//Injection attribute value
    public void setName(String name) {
        this.name = name;
    }

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

Configuration file userconfig java

//This will also be hosted by the Spring container and registered in the container, because it is originally a @ Component,
// @Configuration means that this is a configuration class, just like the beans XML is the same
@Configuration
@ComponentScan("com.zsf.pojo")
@Import(UserConfig2.class)
public class UserConfig {

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

Configuration file 2userconfig2 java

@Configuration
public class UserConfig2 {
}

Test class Mytest:

public class Mytest {
    @Test
    public void test(){
        //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 context = new AnnotationConfigApplicationContext(UserConfig.class);
        User getUser = context.getBean("user", User.class);
        System.out.println(getUser.getName());
    }
}

This pure java configuration method can be seen everywhere in SpringBoot.

10 agent mode

Why learn agent mode? Because this is the bottom layer of spring AOP! [spring AOP and spring MVC]

Classification of agent mode:

  • Static proxy
  • Dynamic agent

1. Static proxy

Role analysis:

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

Code steps:

  1. Interface

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

    //landlord or landlady
    public class Host implements Rent{
        public void rent() {
            System.out.println("The landlord wants to rent the house");
        }
    }
    
  3. delegable role

    public class Proxy implements Rent{
        private Host host;
    
        public Proxy(Host host) {
            this.host = host;
        }
    
        public Proxy() {
        }
    
        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 hetong(){
            System.out.println("Sign a lease contract");
        }
        //Intermediary fee
        public void fare(){
            System.out.println("Intermediary fee");
        }
    }
    
  4. Client access agent role

    public class Client {
        public static void main(String[] args) {
            //The landlord wants to rent a house
            Host host = new Host();
            //Agent, an intermediary helps the landlord rent a house, but the agent role usually has some ancillary operations!
            Proxy proxy = new Proxy(host);
            //Don't face the landlord, just find an intermediary to rent a house
            proxy.rent();
        }
    }
    

Benefits of agent mode:

  • It can make the operation of real roles more pure, without paying attention to some public businesses.
  • The public is also handed over to the agent role, which realizes 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.

acquire a better understanding

Write an addition, deletion, modification and query, and add the log function.

Interface:

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

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("Modified a user");
    }

    public void query() {
        System.out.println("Queried a user");
    }
}

Agent:

public class UserServiceProxy implements UserService{
    private UserServiceImpl userService;

    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }

    public void add() {
        log("add");
        userService.add();
    }

    public void delete() {
        log("delete");
        userService.delete();
    }

    public void update() {
        log("update");
        userService.update();
    }

    public void query() {
        log("query");
        userService.query();
    }

    //Log method
    public void log(String msg){
        System.out.println("Used"+msg+"method");
    }
}

visit:

public class Client {
    public static void main(String[] args) {
        UserServiceImpl userService = new UserServiceImpl();
//        userService.add();
        UserServiceProxy proxy = new UserServiceProxy();
        proxy.setUserService(userService);
        proxy.add();
    }
}

2. Dynamic agent

  • Dynamic agents have the same role as static agents
  • Dynamic proxy classes are dynamically generated, not written directly
  • Dynamic agents are divided into two categories: interface based dynamic agents and class based dynamic agents
    • Interface based - JDK dynamic agent [we use it here]
    • Class based: cglib
    • java bytecode implementation: javasist

Two classes need to be understood: Proxy: Proxy, InvocationHandler: calling handler

11 using Spring to implement AOP

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

Method 1: use Spring API interface [mainly Spring API interface implementation]

public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void query();
}
public class Log implements MethodBeforeAdvice {
    //Method: the method of the target object to execute
    //objects: parameters
    //Target: target object
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName()+"of"+method.getName()+"It was realized");
    }
}
public class AfterLog 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 result is:"+returnValue);
    }
}
<!--    register bean-->
    <bean id="userService" class="com.zsf.service.UserServiceImpl"/>
    <bean id="log" class="com.zsf.log.Log"/>
    <bean id="afterLog" class="com.zsf.log.AfterLog"/>

<!--    Method 1: use native Spring API Interface-->
<!--    to configure aop:Import required aop Constraints of-->
    <aop:config>
<!--        Entry point: expression:expression, execution(Location to execute!***)-->
        <aop:pointcut id="pointcut" expression="execution(* com.zsf.service.UserServiceImpl.*(..))"></aop:pointcut>

<!--        Execute surround increase-->
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>

    </aop:config>
public class Mytest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //The interface of dynamic proxy: Note
        UserService userService = (UserService) context.getBean("userService");
        userService.add();
    }
}

Method 2: Customize to implement AOP [mainly section definition]

public class DiyPointCut {
    public void before(){
        System.out.println("======Before method execution======");
    }
    public void after(){
        System.out.println("======After method execution======");
    }
}
<!--    Method 2: user defined class-->
    <bean id="diy" class="com.zsf.diy.DiyPointCut"/>
    <aop:config>
<!--        Custom section, ref:Class to reference-->
        <aop:aspect ref="diy">
<!--            breakthrough point-->
            <aop:pointcut id="point" expression="execution(* com.zsf.service.UserServiceImpl.*(..))"/>
<!--            notice-->
            <aop:before method="before" pointcut-ref="point"/>
            <aop:after method="after" pointcut-ref="point"/>
        </aop:aspect>
    </aop:config>

Method 3: implement with annotation

//Method 3: implement AOP by annotation
@Aspect//Mark that this class is a facet
public class AnnotationPointCut {

    @Before("execution(* com.zsf.service.UserServiceImpl.*(..))")
    public void before(){
        System.out.println("======Before method execution======");
    }

    @After("execution(* com.zsf.service.UserServiceImpl.*(..))")
    public void after(){
        System.out.println("======After method execution======");
    }

    //In surround programming, we can give a parameter to represent the point where we want to get the processing entry point
    @Around("execution(* com.zsf.service.UserServiceImpl.*(..))")
    public void around(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("Surround front");

        Signature signature = jp.getSignature();//Get signature
        System.out.println("signature:"+signature);

        //Execution method
        Object proceed = jp.proceed();

        System.out.println("After surround");

        System.out.println(proceed);
    }

}
<!--    Mode 3-->
    <bean id="annotationPointCut" class="com.zsf.diy.AnnotationPointCut"/>
<!--    Enable annotation support-->
    <aop:aspectj-autoproxy/>

12 integrate Mybatis

Steps:

  1. Import related jar packages

    • junit
    • mybatis
    • mysql database
    • spring related
    • aop weaving
    • mybatis-spring[new]
    <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</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.3.13</version>
            </dependency>
    <!--        Spring You also need one to operate the database 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.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>2.0.2</version>
            </dependency>
        <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.16.18</version>
            </dependency>
        </dependencies>
    

    Resource filtering problem:

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>
    
  2. Write configuration file

  3. test

1. Recall mybatis

  1. Writing entity classes

    @Data
    public class User {
        private int id;
        private String name;
        private String pwd;
    }
    
  2. Write core configuration file

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

    public interface UserMapper {
        public List<User> selectUser();
    }
    
  4. Write mapper xml

    <?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.zsf.mapper.UserMapper">
    
        <select id="selectUser" resultType="User">
            select * from mybatis.user;
        </select>
    </mapper>
    

5. Test

public class Mytest {
    @Test
    public void test() throws IOException {
        String resources = "mybatis-config.xml";
        InputStream in = Resources.getResourceAsStream(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);
        }


    }
}

2,Mybatis-spring

It was originally done in the business layer of service. Now it can be directly used in the implementation class after spring integration.

Method 1:

  1. Write data source configuration

    <?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 data source:use spring Data source replacement for mybatis Configuration of c3p0 dbcp druid
            We use it here spring Provided jdbc
    -->
    
        <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=true&amp;characterEncoding=UTF-8"/>
            <property name="username" value="root"/>
            <property name="password" value="root"/>
        </bean>
    </beans>
    
  2. Sqlsessionfactory (core)

    Inject the data source (configured above) and bind the configuration file of Mybatis

    <!--    sqlSessionFactory-->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
    <!--        binding mybatis configuration file-->
            <property name="configLocation" value="classpath:Mybatis-config.xml"/>
            <property name="mapperLocations" value="classpath:com/zsf/mapper/*.xml"/>
        </bean>
    
  3. Sqlsessiontemplate (core)

    Because the sqlSessionTemplate will be used for addition, deletion, modification and query to replace the original sqlSession.

    Here, sqlSession is generated through sqlSessionTemplate; Bring in sqlSessionFactory through the only construction method.

    <!--    SqlSessionTemplate That's what we use sqlSession-->
        <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>
    
        <bean id="userMapper" class="com.zsf.mapper.UserMapperImpl">
            <property name="sqlSession" ref="sqlSession"/>
        </bean>
    
  4. You need to add an implementation class to the interface []

    Write an implementation class, make SqlSession private, and then inject it through SqlSessionTemplate.

    public class UserMapperImpl implements UserMapper{
    
        //All our operations are performed using sqlSession. In the past, SqlSessionTemplate is used now;
        private SqlSessionTemplate sqlSession;
    
        public void setSqlSession(SqlSessionTemplate sqlSession) {
            this.sqlSession = sqlSession;
        }
    
        public List<User> selectUser() {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.selectUser();
        }
    }
    
  5. Inject the implementation class written by yourself into spring for testing (users call spring for use)

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

Method 2:

Instead of injecting SqlSession, it directly inherits a class: 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 later.

In fact, it's still method 1, but the official has written it for us, and then we can use it directly.

13 declarative transactions

1. Review transaction

  • Either all succeed or all fail!
  • Transactions are in project development. It is very important to be careless when it comes to the consistency of data.
  • 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 happens to the system, the result will not be affected and will be written to the memory persistently.

2. Transaction management in spring

One of the main reasons for using MyBatis Spring is that it allows MyBatis to participate in Spring's transaction management. Instead of creating a new dedicated transaction manager for MyBatis, MyBatis Spring implements transaction management with the help of the data source transaction manager in Spring.

Once the Spring transaction manager is configured, you can configure transactions in Spring in your usual way. It also supports @ Transactional annotation and AOP style configuration. A separate SqlSession object will be created and used during the transaction. When the transaction is completed, the session will be committed or rolled back in an appropriate way.

After the transaction is configured, mybatis spring will manage the transaction transparently. In this way, no additional code is required in your DAO class.

  • Declarative transaction: AOP

To enable the transaction processing function of Spring, create a DataSourceTransactionManager object in the configuration file of Spring

<!--    Configure declarative transactions-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

<!--    combination AOP To realize the weaving of transactions, first find an entry point-->
<!--    Configure transaction Notifications:-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--        Which methods are configured with transactions-->
<!--        Configure propagation properties of transactions-->
        <tx:attributes>
            <tx:method name="add" propagation="REQUIRED"/>
            <tx:method name="delete" propagation="REQUIRED"/>
            <tx:method name="update" propagation="REQUIRED"/>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

<!--    Configure transaction entry-->
    <aop:config>
        <aop:pointcut id="txPointCut" expression="execution(* com.zsf.mapper.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>
  • Programming transaction

Thinking: why do you need business?

  • If transactions are not configured, there may be inconsistent data submission;
  • If we don't configure declarative transactions in spring anymore, we need to manually configure transactions in our code
  • Transaction is very important in project development, which involves the consistency and integrity of data.

Topics: Java Spring Back-end