Summary of the Spring

The website address

Liverpoolfc.tv: spring. IO /

IO /libs-releas…

Making: github.com/spring-proj…

advantages

1. Spring is an open source, free framework and container.

Spring is a lightweight framework that is non-intrusive.

3. Inversion of control IoC, faceted Aop(core)

4. Support for things, support for frameworks

Spring is a lightweight inversion of Control (IoC) and AOP oriented container (framework).

The Spring of

The Spring framework is a layered architecture consisting of seven well-defined modules. Spring modules are built on top of the core container, which defines how beans are created, configured, and managed.

Each module (or component) that makes up the Spring framework can exist on its own or be implemented in conjunction with one or more other modules. The functions of each module are as follows:

  • Core containerThe core container provides the basic functionality of the Spring framework. The main component of the core container is the BeanFactory, which is an implementation of the factory pattern. The BeanFactory applies theInversion of controlThe (IOC) pattern separates the configuration and dependency specifications of an application from the actual application code.
  • Spring Context: The Spring context is a configuration file that provides context information to the Spring framework. The Spring context includes enterprise services, such as JNDI, EJB, E-mail, internationalization, validation, and scheduling capabilities.
  • Spring AOP: The Spring AOP module integrates section-oriented programming functionality directly into the Spring framework through the configuration management feature. So, you can easily have the Spring framework manage any OBJECT that supports AOP. The Spring AOP module provides transaction management services for objects in Spring-based applications. Using Spring AOP, you can integrate declarative transaction management into your application without relying on components.
  • 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 you need to write (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’s object-relational tools, including JDO, Hibernate, and iBatis SQL Map. All follow Spring’s common transaction and DAO exception hierarchies.
  • Spring Web Module: The Web context module builds on the application context module and provides the context for Web-based applications. So, the Spring framework supports integration with Jakarta Struts. The Web module also simplifies handling multi-part requests and binding request parameters to domain objects.
  • Spring MVC Framework: The MVC framework is a full-featured MVC implementation for building Web applications. With the policy interface, the MVC framework becomes highly configurable, and MVC accommodates a number of view technologies, including JSP, Velocity, Tiles, iText, and POI.

expand

Spring Boot and Spring Cloud

  • Spring Boot is a set of fast configuration scaffolding for Spring, which can be used to quickly develop individual microservices.
  • Spring Cloud is implemented based on Spring Boot.
  • Spring Boot focuses on fast and easy integration of a single microservice individual, while Spring Cloud focuses on the global service governance framework.
  • Spring Boot uses the concept of constraint over configuration. Many integration solutions have already been selected for you. A large part of Spring Cloud is implemented based on Spring Boot. Spring Boot can be independently used for development projects without Spring Cloud, but Spring Cloud cannot be separated from Spring Boot, which is a dependency.
  • SpringBoot plays a bridging role in SpringClound. If you want to learn SpringCloud, you must learn SpringBoot.

The IOC nature

Inversion of Control (IoC) is a design idea, DI(dependency injection) is a method to implement IoC, but some people think DI is just another word for IoC. In programs without IoC, we use object-oriented programming, in which 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, and the creation of objects is transferred to a third party after the inversion of control. In my opinion, the so-called inversion of control is: the way of obtaining dependent objects is reversed.

IoC is at the heart of the Spring framework and is implemented beautifully in a variety of ways, including XML configuration, annotations, and zero configuration in new versions of Spring.

The Spring container first reads the configuration file during initialization, and creates and organizes objects according to the configuration file or metadata into the container. When the program is used, the required objects are extracted from the Ioc container.

When configuring beans in XML mode, Bean definition information is separated from the implementation, while annotations can be used to combine the two. Bean definition information is directly defined in the form of annotations in the implementation class, thus achieving zero configuration.

Inversion of control is a way to produce or obtain a particular object through a description (XML or annotations) and through a third party. Inversion of control is implemented in Spring by the IoC container through Dependency Injection (DI).

Getting started with Spring

Introduction Case 1

Import the Jar package

Note: Spring needs to import commons-logging for logging. We use Maven, which automatically downloads the corresponding dependencies.

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>5.1.10. RELEASE</version>
</dependency>
Copy the code

Write the code

Write a Hello entity class

public class Hello {
   private String name;

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

   public void show(a){
       System.out.println("Hello,"+ name ); }}Copy the code

2. Write our Spring file, which we’ll call beans.xml


      
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

   <! Beans are Java objects created and managed by Spring.
   <bean id="hello" class="com.kuang.pojo.Hello">
       <property name="name" value="Spring"/>
   </bean>

</beans>
Copy the code

3. We’re ready to test it.

@Test
public void test(a){
   // Parse beans. XML file to generate and manage the corresponding Bean object
   ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
   //getBean: Parameter is the id of the bean in the Spring configuration file.
   Hello hello = (Hello) context.getBean("hello");
   hello.show();
}
Copy the code

thinking

  • 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 in a process called inversion of control:
  • Control: Who controls the creation of objects? In traditional applications, objects are created by the program itself. With Spring, objects are created by Spring
  • Inversion: instead of creating objects, the program passively receives them.

Dependency injection: is to use the set method for injection.

IOC is a programming philosophy that moves from active programming to passive reception

Can go to look at the underlying source through newClassPathXmlApplicationContext.

Modified Case 1

In case 1, we add a new Spring configuration file, beans.xml


      
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="MysqlImpl" class="com.kuang.dao.impl.UserDaoMySqlImpl"/>
   <bean id="OracleImpl" class="com.kuang.dao.impl.UserDaoOracleImpl"/>

   <bean id="ServiceImpl" class="com.kuang.service.impl.UserServiceImpl">
       <! The name is not an attribute, but the first letter of the set method is lowercase.
       <! -- Reference another bean, not with value but with ref-->
       <property name="userDao" ref="OracleImpl"/>
   </bean>

</beans>
Copy the code

The test!

@Test
public void test2(a){
   ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
   UserServiceImpl serviceImpl = (UserServiceImpl) context.getBean("ServiceImpl");
   serviceImpl.getUser();
}
Copy the code

OK, now we don’t need to make any changes in the program at all. To achieve different operations, we only need to make changes in the XML configuration file. The IoC is simple: Objects are created, managed and assembled by Spring!

IOC Object creation method

1. Create by using the no-argument constructor

1, the User. Java

public class User {

   private String name;

   public User(a) {
       System.out.println("User parameterless constructor");
  }

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

   public void show(a){
       System.out.println("name="+ name ); }}Copy the code

2, beans. XML


      
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="user" class="com.kuang.pojo.User">
       <property name="name" value="kuangshen"/>
   </bean>

</beans>
Copy the code

3. Test classes

@Test
public void test(a){
   ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
   // When the getBean is executed, the user is already created, constructed with no arguments
   User user = (User) context.getBean("user");
   // Call the method of the object.
   user.show();
}
Copy the code

As it turns out, the User object was already initialized with no-argument construction before the show method was called!

2. Create by using the parameter constructor

1, usert.java

public class UserT {

   private String name;

   public UserT(String name) {
       this.name = name;
  }

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

   public void show(a){
       System.out.println("name="+ name ); }}Copy the code

Beans.xml can be written in three ways

<! -- set index to index -->
<bean id="userT" class="com.kuang.pojo.UserT">
   <! -- index constructor, index starting at 0 -->
   <constructor-arg index="0" value="kuangshen2"/>
</bean>

<! -- The second type is set according to the parameter name -->
<bean id="userT" class="com.kuang.pojo.UserT">
   <! -- name specifies the parameter name -->
   <constructor-arg name="name" value="kuangshen2"/>
</bean>

<! -- The third type is set by parameter type -->
<bean id="userT" class="com.kuang.pojo.UserT">
   <constructor-arg type="java.lang.String" value="kuangshen2"/>
</bean>
Copy the code

3, test,

@Test
public void testT(a){
   ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
   UserT user = (UserT) context.getBean("userT");
   user.show();
}
Copy the code

Conclusion: When the configuration file is loaded. All managed objects are already initialized!

The Spring configuration

The alias

Alias Sets an alias for the bean. You can set multiple aliases

<! Set the alias: you can use the alias to fetch the Bean -->
<alias name="userT" alias="userNew"/>
Copy the code

Bean configuration

<! Beans are Java objects created and managed by Spring.

<! If id is not specified,name is the default identifier. If id is specified,name is an alias. Name can be set to multiple aliases separated by commas, semicolons, and Spaces If no configuration id and name, can according to applicationContext. GetBean (. Class) to obtain object; Class is the fully qualified bean name = package name + class name -->
<bean id="hello" name="hello2" class="com.haust.pojo.Hello">
   <property name="name" value="Spring"/>
</bean>
Copy the code

import

Team collaboration is achieved through imports.

<import resource="{path}/beans.xml"/>
Copy the code

Dependency Injection (DI)

concept

  • Dependency Injection (DI).
  • Dependency: The creation of a Bean object depends on the container. Bean object’s dependent resource.
  • Injection: Refers to the resource on which the Bean object depends, which is set and assembled by the container.

Constructor injection

We saw that in the previous case

Set injection (emphasis)

The set method must be capitalized with the first letter of the set + attribute. If the attribute is of Boolean type, there is no set method, is.

Test the POJO class:

Address.java

 public class Address {
 
     private String address;
 
     public String getAddress(a) {
         return address;
    }
 
     public void setAddress(String address) {
         this.address = address; }}Copy the code

Student.java

 package com.kuang.pojo;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
 
 public class Student {
 
     private String name;
     private Address address;
     private String[] books;
     private List<String> hobbys;
     private Map<String,String> card;
     private Set<String> games;
     private String wife;
     private Properties info;
 
     public void setName(String name) {
         this.name = name;
    }
 
     public void setAddress(Address address) {
         this.address = address;
    }
 
     public void setBooks(String[] books) {
         this.books = books;
    }
 
     public void setHobbys(List<String> hobbys) {
         this.hobbys = hobbys;
    }
 
     public void setCard(Map<String, String> card) {
         this.card = card;
    }
 
     public void setGames(Set<String> games) {
         this.games = games;
    }
 
     public void setWife(String wife) {
         this.wife = wife;
    }
 
     public void setInfo(Properties info) {
         this.info = info;
    }
 
     public void show(a){
         System.out.println("name="+ name
                 + ",address="+ address.getAddress()
                 + ",books="
        );
         for (String book:books){
             System.out.print("< <"+book+">>\t");
        }
         System.out.println("\ n hobby."+hobbys);
 
         System.out.println("card:"+card);
 
         System.out.println("games:"+games);
 
         System.out.println("wife:"+wife);
 
         System.out.println("info:"+info); }}Copy the code

Constant injection

 <bean id="student" class="com.kuang.pojo.Student">
     <property name="name" value="Xiao Ming"/>
 </bean>
Copy the code

Testing:

 @Test
 public void test01(a){
     ApplicationContext context = newClassPathXmlApplicationContext("applicationContext.xml");
 
     Student student = (Student) context.getBean("student");
 
     System.out.println(student.getName());
 
 }
Copy the code

2. Bean injection

Note: The value here is a reference, ref

 <bean id="addr" class="com.kuang.pojo.Address">
     <property name="address" value="Chongqing"/>
 </bean>
 
 <bean id="student" class="com.kuang.pojo.Student">
     <property name="name" value="Xiao Ming"/>
     <property name="address" ref="addr"/>
 </bean>
Copy the code

3. Array injection

 <bean id="student" class="com.kuang.pojo.Student">
     <property name="name" value="Xiao Ming"/>
     <property name="address" ref="addr"/>
     <property name="books">
         <array>
             <value>Journey to the west</value>
             <value>A dream of red mansions</value>
             <value>Water margin</value>
         </array>
     </property>
 </bean>
Copy the code

4. List injection

 <property name="hobbys">
     <list>
         <value>Listening to music</value>
         <value>See a movie</value>
         <value>Climbing the mountain</value>
     </list>
 </property>
Copy the code

5. Map injection

 <property name="card">
     <map>
         <entry key="China Post" value="456456456465456"/>
         <entry key="Construction" value="1456682255511"/>
     </map>
 </property>
Copy the code

6, set injection

 <property name="games">
     <set>
         <value>LOL</value>
         <value>BOB</value>
         <value>COC</value>
     </set>
 </property>
Copy the code

Null injection

 <property name="wife"><null/></property>
Copy the code

Properties injection

 <property name="info">
     <props>
         <prop key="Student id">20190604</prop>
         <prop key="Gender">male</prop>
         <prop key="Name">Xiao Ming</prop>
     </props>
 </property>
Copy the code

Test results:

P name and C name injection

User.java: [note: there is no parameter constructor here!]

 public class User {
     private String name;
     private int age;
 
     public void setName(String name) {
         this.name = name;
    }
 
     public void setAge(int age) {
         this.age = age;
    }
 
     @Override
     public String toString(a) {
         return "User{" +
                 "name='" + name + '\' ' +
                 ", age=" + age +
                 '} '; }}Copy the code

1. P namespace injection: constraint files need to be added to header files

Import restriction: XMLNS: p = "http://www.springframework.org/schema/p"<! --P(properties: properties) namespace, property still set method -->
 <bean id="user" class="com.kuang.pojo.User" p:name="Crazy god" p:age="18"/>
Copy the code

C namespace injection: constraint files need to be added to header files

Import restriction: XMLNS: c = "http://www.springframework.org/schema/c"<! --C(Constructor: Constructor) namespace, attribute still set method -->
 <bean id="user" class="com.kuang.pojo.User" c:name="Crazy god" c:age="18"/>
Copy the code

Found the problem: burst red, just we did not write with reference to the structure!

Solution: add the parameter constructor, here also can see, c is called constructor injection!

Test code:

 @Test
 public void test02(a){
     ApplicationContext context = newClassPathXmlApplicationContext("applicationContext.xml");
     User user = (User) context.getBean("user");
     System.out.println(user);
 }
Copy the code

The scope of the Bean

In Spring, the bodies that make up the application and the objects managed by the Spring IoC container are called beans. Simply put, beans are objects that are initialized, assembled, and managed by the IoC container.

The Request and Session scopes are only used in Web-based applications (regardless of which Web application framework you are using), and only in web-based Spring ApplicationContext.

Singleton

When a bean is scoped to a Singleton, there will be only one shared bean instance in the Spring IoC container, and all requests for the bean will return only the same instance of the bean as long as the ID matches the bean definition. A Singleton is a Singleton type that automatically creates a bean object when the container is created. It exists regardless of whether you use it or not, and the object you get is the same object each time. Note that the Singleton scope is the default scope in Spring. To define a bean as a singleton in XML, configure it as follows:

 <bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">
Copy the code

Testing:

 @Test
 public void test03(a){
     ApplicationContext context = newClassPathXmlApplicationContext("applicationContext.xml");
     User user = (User) context.getBean("user");
     User user2 = (User) context.getBean("user");
     System.out.println(user==user2);
 }
Copy the code

Prototype

When a bean is scoped to Prototype, a bean definition corresponds to multiple object instances. A prototype-scoped bean results in a new bean instance being created each time the bean is requested (injected into another bean, or programmatically called on the container’s getBean() method). Prototype is the Prototype type, which is not instantiated when we create the container. Instead, we create an object when we get the bean, and we get a different object each time. As a rule of thumb, you should use the Prototype scope for stateful beans and the Singleton scope for stateless beans. Defining the bean as prototype in XML can be configured as follows:

 <bean id="account" class="com.foo.DefaultAccount" scope="prototype"/>or<bean id="account" class="com.foo.DefaultAccount" singleton="false"/>
Copy the code

Request

When the scope of a bean is Request, it means that in an HTTP Request, one bean definition corresponds to one instance. That is, each HTTP request has its own bean instance, which is created from a bean definition. This scope is valid only in the case of web-based Spring ApplicationContext. Consider the following bean definition:

 <bean id="loginAction" class=cn.csdn.LoginAction" scope="request"/>
Copy the code

For each HTTP request, the Spring container will create a new loginAction bean instance based on the loginAction bean definition, which is valid only within the current HTTP Request. Therefore, you can safely change the internal state of the instance you build as needed, while instances created based on the loginAction bean definition in other requests will not see these request-specific state changes. When the processing of the request ends, the request scoped bean instance is destroyed.

Session

When the scope of a bean is Session, it means that in an HTTP Session, one bean definition corresponds to one instance. This scope is valid only in the case of web-based Spring ApplicationContext. Consider the following bean definition:

 <bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
Copy the code

For an HTTP Session, the Spring container creates a brand new userPreferences Bean instance based on the userPreferences Bean definition, And the userPreferences Bean is only valid for the current HTTP Session. As with the Request scope, you can safely change the internal state of the instance you create as needed, whereas other HTTP Session instances created under userPreferences will not see these session-specific state changes. When an HTTP Session is finally discarded, the beans scoped by that HTTP Session are also discarded.

Automatically.

Automatic assembly of beans

Automatic assembly instruction

  • Autowiring is one way to use Spring to satisfy bean dependencies
  • Spring finds the dependent beans for a bean in the application context.

There are three assembly mechanisms for beans in Spring:

  1. Explicitly configured in XML;
  2. Explicitly configured in Java;
  3. Implicit bean discovery mechanisms and autowiring.

Here we focus on the third type: automated assembly beans.

Spring autowiring needs to be done from two perspectives, or two operations:

  1. Component scanning: Spring automatically discovers beans created in the application context;
  2. Autowiring: Spring automatically satisfies dependencies between beans, known as IoC/DI;

The combination of component scanning and auto-assembly is powerful enough to minimize the configuration displayed.

It is recommended to use annotations instead of autoloading XML configurations.

Test environment setup

Create a new project

2, Create two new entity classes, Cat Dog each have a method called

public class Cat {
   public void shout(a) {
       System.out.println("miao~"); }}public class Dog {
   public void shout(a) {
       System.out.println("wang~"); }}Copy the code

3. Create a User class User

public class User {
   private Cat cat;
   private Dog dog;
   private String str;
}
Copy the code

4. Write the Spring configuration file


      
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="dog" class="com.kuang.pojo.Dog"/>
   <bean id="cat" class="com.kuang.pojo.Cat"/>

   <bean id="user" class="com.kuang.pojo.User">
       <property name="cat" ref="cat"/>
       <property name="dog" ref="dog"/>
       <property name="str" value="qinjiang"/>
   </bean>
</beans>
Copy the code

5, test,

public class MyTest {
   @Test
   public void testMethodAutowire(a) {
       ApplicationContext context = newClassPathXmlApplicationContext("beans.xml");
       User user = (User) context.getBean("user"); user.getCat().shout(); user.getDog().shout(); }}Copy the code

The output is normal and the environment is OK

byName

Autowire byName (automatic assembly byName)

During the manual configuration of XML, errors such as missing letters and case often occur and cannot be checked, which reduces the development efficiency.

Using autowiring will avoid these errors and simplify the configuration.

Testing:

Autowire = “byName”

<bean id="user" class="com.kuang.pojo.User" autowire="byName">
   <property name="str" value="qinjiang"/>
</bean>
Copy the code

2, test again, the results are still successful output!

3. Let’s change the bean ID of cat to catXXX

4, test again, the execution times null pointer Java lang. NullPointerException. Because the byName rule does not correspond to the set method, the real setCat is not executed and the object is not initialized, so nullpointer errors are reported when called.

Summary:

When a bean node has the property Autowire byName.

  1. It looks for all set method names in its class, such as setCat, to get the string with the set removed and its initial lowercase, cat.
  2. Go to the Spring container and look for an object with the string name ID.
  3. If so, remove and inject; If not, a null pointer exception is reported.

byType

Autowire byType (automatic assembly byType)

Using Autowire byType requires that objects of the same type are unique in the Spring container. If not, a unique exception is reported.

NoUniqueBeanDefinitionException
Copy the code

Testing:

Autowire = “byType”

2, test, normal output

3. Register a cat bean object!

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>

<bean id="user" class="com.kuang.pojo.User" autowire="byType">
   <property name="str" value="qinjiang"/>
</bean>
Copy the code

4, testing, error: NoUniqueBeanDefinitionException

5, delete cat2, change the name of cat bean! The test! Because it is assembled by type, no exceptions are reported and the final result is not affected. Even removing the ID attribute does not affect the results.

This is auto-assemble by type!

Using annotations

Open the annotation

Annotations are being supported in jdk1.5 and fully supported in spring2.5.

Preparation: Inject properties using annotations.

1. Introduce the context header in the Spring configuration file

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

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
Copy the code

2. Enable attribute annotation support!

<context:annotation-config/>
Copy the code

@Autowired

  • @autoWired is automatically configured by type and does not support ID matching.
  • Need to import the spring-AOP package!

Testing:

1. Remove the set method from the User class and use the @autowired annotation

public class User {
   @Autowired
   private Cat cat;
   @Autowired
   private Dog dog;
   private String str;

   public Cat getCat(a) {
       return cat;
  }
   public Dog getDog(a) {
       return dog;
  }
   public String getStr(a) {
       returnstr; }}Copy the code

2. Configure the content of the file

<context:annotation-config/>

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="user" class="com.kuang.pojo.User"/>
Copy the code

3, test, successful output results!

【 Little crazy God popular Science time 】

@autoWired (Required =false) True, object must hold object, cannot be null.

// If null is allowed, set required = false, which defaults to true
@Autowired(required = false)
private Cat cat;
Copy the code

@Qualifier

  • @autoWired is Autowired by type, and @qualifier is Autowired by byName
  • @qualifier cannot be used alone.

Test procedure:

1. Modify the configuration file to ensure that there are objects in the type. And the name is not the default name of the class!

<bean id="dog1" class="com.kuang.pojo.Dog"/>
<bean id="dog2" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>
Copy the code

Qualifier test was not added

Add Qualifier annotations to the properties

@Autowired
@Qualifier(value = "cat2")
private Cat cat;
@Autowired
@Qualifier(value = "dog2")
private Dog dog;
Copy the code

Test, successful output!

@Resource

  • If @resource has a specified name attribute, byName lookup assembly is performed according to this attribute.
  • Secondly, the default byName method is used for assembly.
  • If all else fails, byType is used for automatic assembly.
  • If none is successful, an exception is reported.

Entity class:

public class User {
   // If null is allowed, set required = false, which defaults to true
   @Resource(name = "cat2")
   private Cat cat;
    
   @Resource
   private Dog dog;
   private String str;
}
Copy the code

beans.xml

<bean id="dog" class="com.kuang.pojo.Dog"/>

<bean id="cat1" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>

<bean id="user" class="com.kuang.pojo.User"/>
Copy the code

Test: OK

Configuration file 2: beans.xml, drop cat2

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>
Copy the code

Only annotations are kept on the entity class

@Resource
private Cat cat;
@Resource
private Dog dog;
Copy the code

Results: OK

Conclusion: byName lookup fails; The byType search succeeds.

summary

@autowired vs. @resource:

1. @autoWired and @Resource can both be used to assemble beans. You can write it on a field, or you can write it on a setter method.

By default, @autowired must be assembled by type (belonging to the Spring specification). By default, dependent objects must exist. To allow null values, you can set its required property to false, as in: @autoWired (required=false), which can be used with the @qualifier annotation if we want to use name assemblies

3, @resource (belongs to J2EE return), by default the assembly is based on the name, the name can be specified by the name attribute. If the name attribute is not specified, the annotation defaults to the field name for lookup by name when written on a field, or the attribute name when written on a setter method for assembly. Assemble by type when no bean matching the name can be found. Note, however, that if the name attribute is specified, it will only be assembled by name.

They do the same thing: they annotate objects, but in a different order. @autoWired byType, @resource byName.

Development with annotations

instructions

After spring4, to use the annotation form, aop packages must be introduced

In the configuration file, you also need to introduce a context constraint


      
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

</beans>
Copy the code

The realization of the Bean

We used to use bean tags for bean injection, but in real development, we usually use annotations!

1. Configure which packages to scan for annotations

<! -- Specify the annotation scan package -->
<context:component-scan base-package="com.kuang.pojo"/>
Copy the code

2. Write classes under the specified package and add annotations

@Component("user")

      
public class User {
   public String name = "Qin jiang";
}
Copy the code

3, test,

@Test
public void test(a){
   ApplicationContext applicationContext =
       new ClassPathXmlApplicationContext("beans.xml");
   User user = (User) applicationContext.getBean("user");
   System.out.println(user.name);
}
Copy the code

Properties into

Use annotations to inject properties

@Component

1, you can add @value(” value “) to the direct name without providing a set method.

@Component("user")

      
public class User {
   @ Value (" qin jiang ")
   
      
   public String name;
}
Copy the code

2. If set is provided, add @value(” value “) to set.

@Component("user")
public class User {

   public String name;

   @ Value (" qin jiang ")
   public void setName(String name) {
       this.name = name; }}Copy the code

Derivative annotations

These annotations are a substitute for the configuration step in the configuration file. More convenient and fast!

@Component three derived annotations

For better layering, Spring can use three other annotations, which do the same thing and which are currently used.

  • @ Controller: the web tier
  • @ Service: the Service layer
  • @ Repository: dao layer

By writing these annotations, you hand the class over to the Spring-managed assembly!

Automatic assembly notes

The autoloading of beans has already been covered and can be recalled!

scope

@scope

  • Singleton: By default, Spring creates this object in singleton mode. Shut down the factory and all objects are destroyed.
  • Prototype: Multiple example mode. Close the factory and all objects will not be destroyed. The internal garbage collection mechanism will collect
@Controller("user")
@Scope("prototype")
public class User {
   @ Value (" qin jiang ")
   public String name;
}
Copy the code

Configuration class annotations

@Configuration

JavaConfig was originally a subproject of Spring that provides Bean definition information in the form of Java classes. In the Spring4 release, JavaConfig has officially become a core feature of Spring4.

Testing:

1. Write an entity class, Dog

@Component  // Mark this class as a component of Spring and put it in the container!
public class Dog {
   public String name = "dog";
}
Copy the code

2. Create a config package and write a MyConfig class

@Configuration  // indicates this is a configuration class
public class MyConfig {

   @Bean // Register a bean with a method. The return value is the bean type, and the method name is the bean ID!
   public Dog dog(a){
       return newDog(); }}Copy the code

3, test,

@Test
public void test2(a){
   ApplicationContext applicationContext =
           new AnnotationConfigApplicationContext(MyConfig.class);
   Dog dog = (Dog) applicationContext.getBean("dog");
   System.out.println(dog.name);
}
Copy the code

4. Output results successfully!

How do I import other configurations?

1. Let’s write another configuration class!

@Configuration  // indicates this is a configuration class
public class MyConfig2 {}Copy the code

2, in the previous configuration class we choose to import this configuration class

@Configuration
@Import(MyConfig2.class)  // Import and merge other configuration classes, similar to inculde tags in configuration files
public class MyConfig {

   @Bean
   public Dog dog(a){
       return newDog(); }}Copy the code

We’ll see a lot more about how Java classes are configured in SpringBoot and SpringCloud, but we need to know what these annotations are for!

summary

XML vs. annotations

  • XML can be used in any scenario, with a clear structure and easy maintenance
  • Annotations are not provided by their own class can not be used, simple and convenient development

Integrated XML and annotation development: Recommended best practices

  • The XML management Bean
  • Annotation completes property injection
  • You can use it without scanning for annotations on the class
<context:annotation-config/>  
Copy the code

Function:

  • Annotation-driven registration is performed to validate annotations
  • Annotations to activate beans that have already been registered with the Spring container, that is, registered with Spring
  • If you do not scan packages, you need to manually configure the beans
  • If not annotated, the injected value is NULL!

Static/dynamic proxy mode

Introduction to proxy Mode

Why learn the proxy pattern, because the underlying mechanism of AOP is dynamic proxies!

Proxy mode:

  • Static agent
  • A dynamic proxy

Before we learn about AOP, we need to look at the proxy pattern!

Static agent

Static proxy role analysis

  • Abstract roles: Typically implemented using interfaces or abstract classes
  • Real role: The role being represented
  • Proxy role: Proxy for the real role; After a real role is represented, it usually does some ancillary operations.
  • Customer: Use the agent role to perform some operations.

Code implementation

Rent.java is an abstract role

// Abstract role: rent a house
public interface Rent {
   public void rent(a);
}
Copy the code

Host. Java is a real role

// Real character: landlord, landlord wants to rent the house
public class Host implements Rent{
   public void rent(a) {
       System.out.println("House for Rent"); }}Copy the code

Proxy. Java is the Proxy role

// Proxy role: intermediary
public class Proxy implements Rent {

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

   / / rent
   public void rent(a){
       seeHouse();
       host.rent();
       fare();
  }
   / / the checking
   public void seeHouse(a){
       System.out.println("Show the tenant a house.");
  }
   // A broker fee is charged
   public void fare(a){
       System.out.println("Collect a broker's fee"); }}Copy the code

Client.java is a Client

// Client class, usually customers to find agent!
public class Client {
   public static void main(String[] args) {
       // The landlord wants to rent a house
       Host host = new Host();
       // The agent helps the landlord
       Proxy proxy = new Proxy(host);

       // You go to an agent!proxy.rent(); }}Copy the code

Analysis: in this process, you direct contact is intermediary, just as in real life, you can’t see the landlord, but you still rent to the landlord’s house through the agent, this is the so-called agency model, program is derived from life, so to learn programming, generally more abstract events in the way of looking at life.

Benefits of static proxies:

  • Can make our real role more pure. No longer pay attention to some public things.
  • The common business is completed by the agent. The division of business is realized.
  • Common services become more centralized and convenient when they are extended.

Disadvantages:

  • More classes, more proxy classes, the amount of work is larger. Development efficiency is reduced.

We want the benefits of static proxies without the disadvantages, so here we have dynamic proxies!

Static proxies understand again

After the exercises, let’s give another example to consolidate our learning!

Practice steps:

1, create an abstract role, such as we usually do user business, abstract is to add, delete, change and check!

// Abstract roles: add, delete, change and check services
public interface UserService {
   void add(a);
   void delete(a);
   void update(a);
   void query(a);
}
Copy the code

2. We need a real object to do this

// The real object, the person who completed the add, delete, change and check operation
public class UserServiceImpl implements UserService {

   public void add(a) {
       System.out.println("Added a user.");
  }

   public void delete(a) {
       System.out.println("Deleted a user");
  }

   public void update(a) {
       System.out.println("Updated a user");
  }

   public void query(a) {
       System.out.println("Query a user"); }}Copy the code

Demand comes, now we need to add a log function, how to achieve!

  • Idea 1: Add code to the implementation class.
  • Idea 2: Using proxies is the best way to do this without changing the business.

4. Set up a proxy class to handle logging! The agent role

// Proxy role, in which to add logging implementation
public class UserServiceProxy implements UserService {
   private UserServiceImpl userService;

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

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

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

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

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

   public void log(String msg){
       System.out.println("Executed."+msg+"Method"); }}Copy the code

5, Test access class:

public class Client {
   public static void main(String[] args) {
       // Real business
       UserServiceImpl userService = new UserServiceImpl();
       / / the proxy class
       UserServiceProxy proxy = new UserServiceProxy();
       // Use proxy classes to implement logging!proxy.setUserService(userService); proxy.add(); }}Copy the code

OK, now we should have no problem with the proxy model, the key point is that we need to understand the idea;

The core idea in AOP is that we have implemented enhancements to the original functionality without changing the original code

Talk about AOP: vertical development, horizontal development.

A dynamic proxy

  • The role of a dynamic proxy is the same as that of a static proxy.
  • The proxy class for dynamic proxy is dynamically generated. The proxy class for static proxy is written in advance
  • Dynamic proxy can be divided into two types: dynamic proxy based on interface and dynamic proxy based on class
    • Interface based dynamic proxy —-JDK dynamic proxy
    • Class-based dynamic proxy – Cglib
    • Now more use is javasist to generate dynamic proxy. Baidu javasist
    • Here we use JDK native code to implement, the rest of the reason is the same! ,

There are two classes you need to know about dynamic proxies in the JDK

Core: InvocationHandler and Proxy, open the JDK help documentation to see

【InvocationHandler 】

Object invoke(Object Proxy, method, Object[] args);/ / parameters
//proxy - the proxy instance that calls the method
//method - The method corresponds to invoking an instance of an interface method on a proxy instance. The declaration class of a method object will be the interface that the method declares, which can be the superinterface of the proxy interface that the proxy class inherits from the method.
//args - Contains an array of objects for method calls that pass the proxy instance's parameter values, or null if the interface method has no parameters. Parameters of primitive types are contained in instances of the appropriate primitive wrapper classes, such as java.lang.Integer or java.lang.Boolean.
Copy the code

【Proxy 】

// Generate the proxy class
public Object getProxy(a){
   return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                               rent.getClass().getInterfaces(),this);
}
Copy the code

Code implementation

The abstract and real characters are the same as before!

Rent.java is an abstract role

// Abstract role: rent a house
public interface Rent {
   public void rent(a);
}
Copy the code

Host. Java is a real role

// Real character: landlord, landlord wants to rent the house
public class Host implements Rent{
   public void rent(a) {
       System.out.println("House for Rent"); }}Copy the code

Proxyinvocationhandler. Java is the proxy role

public class ProxyInvocationHandler implements InvocationHandler {
   private Rent rent;

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

   // Generate the proxy class, focusing on the second argument, to get the abstract role to proxy! It used to be one role, but now it can represent a class of roles
   public Object getProxy(a){
       return Proxy.newProxyInstance(this.getClass().getClassLoader(),
               rent.getClass().getInterfaces(),this);
  }

   // proxy: method: method object of the invocation handler of the proxy class.
   // Process method calls on proxy instances and return results
   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throwsThrowable {
       seeHouse();
       // Core: Essence is realized by reflection!
       Object result = method.invoke(rent, args);
       fare();
       return result;
  }

   / / the checking
   public void seeHouse(a){
       System.out.println("Show the tenant a house.");
  }
   // A broker fee is charged
   public void fare(a){
       System.out.println("Collect a broker's fee"); }}Copy the code

Client . java

/ / tenant
public class Client {

   public static void main(String[] args) {
       // Real characters
       Host host = new Host();
       // The invocation handler for the proxy instance
       ProxyInvocationHandler pih = new ProxyInvocationHandler();
       pih.setRent(host); // Put the real character in!
       Rent proxy = (Rent)pih.getProxy(); // Dynamically generate the corresponding proxy class!proxy.rent(); }}Copy the code

Core: a dynamic proxy, general proxy of a certain kind of business, a dynamic proxy can proxy multiple classes, proxy is interface!

Dynamic proxy understanding again

Let’s implement the proxy using the dynamic proxy we’ll write later UserService!

We could also write a generic dynamic proxy implementation class! Set all proxy objects to Object!

public class ProxyInvocationHandler implements InvocationHandler {
   private Object target;

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

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

   // proxy: proxy class
   // method: the method object of the invocation handler of the proxy class.
   public Object invoke(Object proxy, Method method, Object[] args) throwsThrowable {
       log(method.getName());
       Object result = method.invoke(target, args);
       return result;
  }

   public void log(String methodName){
       System.out.println("Executed."+methodName+"Method"); }}Copy the code

The test!

public class Test {
   public static void main(String[] args) {
       // Real objects
       UserServiceImpl userService = new UserServiceImpl();
       // The invocation handler for the proxy object
       ProxyInvocationHandler pih = new ProxyInvocationHandler();
       pih.setTarget(userService); // Set the object to be proxied
       UserService proxy = (UserService)pih.getProxy(); // Dynamically generate proxy classes!proxy.delete(); }}Copy the code

Test, add, delete, check, check the results!

Benefits of dynamic proxies

Static proxy has it, static proxy does not have, it also has!

  • Can make our real role more pure. No longer pay attention to some public things.
  • The common business is completed by the agent. The division of business is realized.
  • Common services become more centralized and convenient when they are extended.
  • A dynamic proxy, typically for a certain type of service
  • A dynamic proxy can proxy multiple classes, proxy is the interface!

AOP is faceted oriented programming

What is the AOP

AOP (Aspect Oriented Programming) means: section-oriented Programming, through pre-compilation and runtime dynamic proxy to achieve unified maintenance of program functions of a technology. AOP is a continuation of OOP, a hot topic in software development, and an important content in Spring framework. It is a derivative paradigm of functional programming. Using AOP, each part of the business logic can be isolated, thus reducing the degree of coupling between each part of the business logic, improving the reusability of the program, and improving the efficiency of development.

Aop’s role in Spring

Provide declarative transactions; Allows user – defined facets

The following terms need to be understood:

  • Crosscutting concerns: Methods or functions that span multiple modules of an application. That is, the part that is irrelevant to our business logic, but that we need to focus on, is crosscutting concerns. Such as logging, security, caching, transactions…
  • ASPECT: A special object whose crosscutting concerns are modularized. That is, it is a class.
  • Advice: Work that must be done by the aspect. That is, it is a method in a class.
  • Target: indicates the notified object.
  • Proxy: Object created after notification is applied to the target object.
  • PointCut: The definition of the “place” where a tangent notification is executed.
  • Join Point: The execution point that matches the pointcut.

In SpringAOP, crosscutting logic is defined through Advice, and there are five types of Advice supported in Spring:

That is, Aop adds new functionality without changing the original code.

Use Spring to implement Aop

【 key 】 use AOP weave, need to import a dependency package!

<! -- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.9.4</version>
</dependency>
Copy the code

The first is implemented through the Spring API

Start by writing our business interface and implementation classes

public interface UserService {

   public void add(a);

   public void delete(a);

   public void update(a);

   public void search(a);

}
public class UserServiceImpl implements UserService{

   @Override
   public void add(a) {
       System.out.println("Add users");
  }

   @Override
   public void delete(a) {
       System.out.println("Delete user");
  }

   @Override
   public void update(a) {
       System.out.println("Update user");
  }

   @Override
   public void search(a) {
       System.out.println("Query user"); }}Copy the code

Then to write our enhancement class, we write two, one pre-enhancement and one post-enhancement

public class Log implements MethodBeforeAdvice {

   //method: the method of the target object to execute
   //objects: arguments to the called method
   //Object: indicates the target Object
   @Override
   public void before(Method method, Object[] objects, Object o) throws Throwable {
       System.out.println( o.getClass().getName() + "The" + method.getName() + "Method is executed."); }}public class AfterLog implements AfterReturningAdvice {
   / / the returnValue return values
   //method Specifies the method to be called
   //args is the argument to the object of the called method
   //target Specifies the target object to be called
   @Override
   public void afterReturning(Object returnValue, Method method, Object[] args,Object target) throws Throwable {
       System.out.println("Executed." + target.getClass().getName()
       +"The"+method.getName()+"Method."
       +"Return value:"+returnValue); }}Copy the code

Finally go to the spring file registration, and implement AOP cut implementation, pay attention to import constraints.


      
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

   <! Registered bean -- -- -- >
   <bean id="userService" class="com.kuang.service.UserServiceImpl"/>
   <bean id="log" class="com.kuang.log.Log"/>
   <bean id="afterLog" class="com.kuang.log.AfterLog"/>

   <! Aop configuration -->
   <aop:config>
       <! Pointcut expression: expression matches the method to execute -->
       <aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..) )"/>
       <! -- Implementation surround; Advice-ref execute method.pointcut-ref pointcut -->
       <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
       <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
   </aop:config>

</beans>
Copy the code

test

public class MyTest {
   @Test
   public void test(a){
       ApplicationContext context = newClassPathXmlApplicationContext("beans.xml");
       UserService userService = (UserService) context.getBean("userService"); userService.search(); }}Copy the code

Importance of Aop: very important. It is important to understand the thinking, mainly the understanding of the idea of this piece.

Spring’s Aop combines the common business (logging, security, etc.) with the domain business, and when the domain business is executed, the common business will be added. Realize the reuse of common business. Domain business is more pure, and the program focuses on domain business, whose essence is still dynamic proxy.

The second way is to implement custom classes

The target business class remains the same as userServiceImpl

Step 1: Write our own cut class

public class DiyPointcut {

   public void before(a){
       System.out.println("--------- method before execution ---------");
  }
   public void after(a){
       System.out.println("--------- method executed after ---------"); }}Copy the code

Go to Spring to configure

<! Second way to customize the implementation --> <! -- Register bean--> <bean id="diy" class="com.kuang.config.DiyPointcut"/ > <! Aop configuration --> <aop:config> <! The second way: use AOP's tag implementation --> < AOP :aspect ref="diy">
       <aop:pointcut id="diyPonitcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..) )"/>
       <aop:before pointcut-ref="diyPonitcut" method="before"/>
       <aop:after pointcut-ref="diyPonitcut" method="after"/>
   </aop:aspect>
</aop:config>
Copy the code

Testing:

public class MyTest {
   @Test
   public void test(a){
       ApplicationContext context = newClassPathXmlApplicationContext("beans.xml");
       UserService userService = (UserService) context.getBean("userService"); userService.add(); }}Copy the code

The third approach is implemented using annotations

Step 1: Write an enhanced class for the annotation implementation

package com.kuang.config;

import org.aspectj.lang.ProceedingJoinPoint;
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
public class AnnotationPointcut {
   @Before("execution(* com.kuang.service.UserServiceImpl.*(..) )"
   public void before(a){
       System.out.println("--------- method before execution ---------");
  }

   @After("execution(* com.kuang.service.UserServiceImpl.*(..) )"
   public void after(a){
       System.out.println("--------- method executed after ---------");
  }

   @Around("execution(* com.kuang.service.UserServiceImpl.*(..) )"
   public void around(ProceedingJoinPoint jp) throws Throwable {
       System.out.println("Around the front");
       System.out.println("Signature."+jp.getSignature());
       // Execute the target method proceed
       Object proceed = jp.proceed();
       System.out.println("Around the back"); System.out.println(proceed); }}Copy the code

Step 2: In the Spring configuration file, register the bean and add the configuration to support annotations

<! Third way: Annotation implementation -->
<bean id="annotationPointcut" class="com.kuang.config.AnnotationPointcut"/>
<aop:aspectj-autoproxy/>
Copy the code

Aop: aspectj – autoproxy: description

Through the AOP namespace<aop:aspectj-autoproxy />The declaration automatically creates proxies for beans in the Spring container that are configured with the @AspectJ aspect, woven into the aspect. , of course, the spring inside still adopt AnnotationAwareAspectJAutoProxyCreator automatically agent for the creation of the work, but the specific implementation details have been<aop:aspectj-autoproxy />Hidden away<aop:aspectj-autoproxy />There is a proxy-target-class attribute, which defaults to false, indicating that JDK dynamic proxy weaving enhancement is used<aop:aspectj-autoproxy  poxy-target-class="true"/>, indicates that CGLib dynamic proxy technology is used to weave enhancement. But even if proxy-target-class is set to false, Spring will automatically use CGLib dynamic proxies if the target class does not declare an interface.Copy the code

Spring integration MyBatis

steps

1. Import related JAR packages

junit

<dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.12</version>
</dependency>
Copy the code

mybatis

<dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis</artifactId>
   <version>3.5.2</version>
</dependency>
Copy the code

mysql-connector-java

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.47</version>
</dependency>
Copy the code

Spring related

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>5.1.10. RELEASE</version>
</dependency>
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-jdbc</artifactId>
   <version>5.1.10. RELEASE</version>
</dependency>
Copy the code

AspectJ AOP weaver

<! -- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjweaver</artifactId>
   <version>1.9.4</version>
</dependency>
Copy the code

Mybatis – Spring integration package

<dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis-spring</artifactId>
   <version>2.0.2</version>
</dependency>
Copy the code

Configure Static resource filtering for Maven!

<build>
   <resources>
       <resource>
           <directory>src/main/java</directory>
           <includes>
               <include>**/*.properties</include>
               <include>**/*.xml</include>
           </includes>
           <filtering>true</filtering>
       </resource>
   </resources>
</build>
Copy the code

2. Write a configuration file

3. Code implementation

Memories MyBatis

Write poJO entity classes

package com.kuang.pojo;

public class User {
   private int id;  //id
   private String name;   / / name
   private String pwd;   / / password
}
Copy the code

Implement mybatis profile


      
<! DOCTYPEconfiguration
       PUBLIC "- / / mybatis.org//DTD Config / 3.0 / EN"
       "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

   <typeAliases>
       <package name="com.kuang.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=utf8"/>
               <property name="username" value="root"/>
               <property name="password" value="123456"/>
           </dataSource>
       </environment>
   </environments>

   <mappers>
       <package name="com.kuang.dao"/>
   </mappers>
</configuration>
Copy the code

UserDao interface written

public interface UserMapper {
   public List<User> selectUser(a);
}
Copy the code

Mapper mapping file of the interface


      
<! DOCTYPEmapper
       PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.dao.UserMapper">

   <select id="selectUser" resultType="User">
    select * from user
   </select>

</mapper>
Copy the code

The test class

@Test
public void selectUser(a) throws IOException {

   String resource = "mybatis-config.xml";
   InputStream inputStream = Resources.getResourceAsStream(resource);
   SqlSessionFactory sqlSessionFactory = newSqlSessionFactoryBuilder().build(inputStream);
   SqlSession sqlSession = sqlSessionFactory.openSession();

   UserMapper mapper = sqlSession.getMapper(UserMapper.class);

   List<User> userList = mapper.selectUser();
   for (User user: userList){
       System.out.println(user);
  }

   sqlSession.close();
}
Copy the code

MyBatis – Spring learning

Before introducing Spring, you need to know some important classes in the Mybatis – Spring package;

www.mybatis.org/spring/zh/i…

What is MyBatis-Spring?

MyBatis-Spring will help you integrate MyBatis code seamlessly into Spring.

Knowledge base

Before you can start using MyBatis, you need to familiarize yourself with the Spring and MyBatis frameworks and their terminology. This is very important

MyBatis-Spring requires the following versions:

MyBatis-Spring MyBatis The Spring framework Spring Batch Java
2.0 3.5 + 5.0 + 4.0 + Java 8+
1.3 3.4 + 3.2.2 + 2.1 + Java 6+

If you use Maven as a build tool, simply add the following code to pom.xml:

<dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis-spring</artifactId>
   <version>2.0.2</version>
</dependency>
Copy the code

To use MyBatis with Spring, you need to define at least two things in the Spring application context: an SqlSessionFactory and at least one data mapper class.

In MyBatis-Spring, SqlSessionFactory can be created using SqlSessionFactoryBean. To configure the factory bean, simply place the following code in Spring’s XML configuration file:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
 <property name="dataSource" ref="dataSource" />
</bean>
Copy the code

Note: SqlSessionFactory requires a DataSource. This can be any DataSource, just configure it as you would any other Spring database connection.

In the basic MyBatis usage, the SqlSessionFactory is created using the SqlSessionFactoryBuilder. In MyBatis-Spring, SqlSessionFactoryBean is used to create it.

In MyBatis, you can use SqlSessionFactory to create a SqlSession. Once you have a session, you can use it to execute mapped statements, commit or roll back connections, and finally close the session when it is no longer needed.

The SqlSessionFactory has only one required attribute: the DataSource for JDBC. This can be any DataSource object and is configured the same way as any other Spring database connection.

A commonly used attribute is configLocation, which specifies the XML configuration file path for MyBatis. It is very useful when you need to modify the basic configuration of MyBatis. In general, base configuration refers to < Settings > or < typeAliases> elements.

Note that this configuration file does not need to be a complete MyBatis configuration. Specifically, any environment configuration (), data source () and MyBatis transaction manager () are ignored. The SqlSessionFactoryBean creates its own MyBatis Environment configuration (Environment) and sets the value of the custom Environment as required.

The SqlSessionTemplate is the heart of MyBatis-Spring. As an implementation of SqlSession, this means you can use it seamlessly to replace the SqlSession you are already using in your code.

Templates can participate in Spring’s transaction management, and because they are thread-safe and can be used by multiple mapper classes, you should always replace MyBatis’ default DefaultSqlSession implementation with the SqlSessionTemplate. Intermingling between classes in the same application can cause data consistency problems.

You can create a SqlSessionTemplate object using the SqlSessionFactory as an argument to the constructor.

<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
 <constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
Copy the code

This bean can now be injected directly into your DAO bean. You need to add a SqlSession property to your bean like this:

public class UserDaoImpl implements UserDao {

 private SqlSession sqlSession;

 public void setSqlSession(SqlSession sqlSession) {
   this.sqlSession = sqlSession;
}

 public User getUser(String userId) {
   return sqlSession.getMapper...;
 }
}
Copy the code

Inject the SqlSessionTemplate as follows:

<bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl">
 <property name="sqlSession" ref="sqlSession" />
</bean>
Copy the code

Integration Implementation 1

1. Introduce the Spring configuration file beans.xml


      
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
Copy the code

2. Configure the data source to replace the data source of mybaits

<! Configure the data source: there are many data sources, you can use a third party, or you can use Spring -->
<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=utf8"/>
   <property name="username" value="root"/>
   <property name="password" value="123456"/>
</bean>
Copy the code

3. Configure SqlSessionFactory and associate it with MyBatis

<! - the configuration SqlSessionFactory -- -- >
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
   <property name="dataSource" ref="dataSource"/>
   <! - associated Mybatis -- -- >
   <property name="configLocation" value="classpath:mybatis-config.xml"/>
   <property name="mapperLocations" value="classpath:com/kuang/dao/*.xml"/>
</bean>
Copy the code

4. Register sqlSessionTemplate and associate it with sqlSessionFactory.

<! SqlSessionFactory = sqlSessionFactory
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
   <! Constructor injection -->
   <constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
Copy the code

5. Add the implementation class of Dao interface; Privatisation sqlSessionTemplate

public class UserDaoImpl implements UserMapper {

   //sqlSession is not created by Spring
   private SqlSessionTemplate sqlSession;

   public void setSqlSession(SqlSessionTemplate sqlSession) {
       this.sqlSession = sqlSession;
  }

   public List<User> selectUser(a) {
       UserMapper mapper = sqlSession.getMapper(UserMapper.class);
       returnmapper.selectUser(); }}Copy the code

Register the bean implementation

<bean id="userDao" class="com.kuang.dao.UserDaoImpl">
   <property name="sqlSession" ref="sqlSession"/>
</bean>
Copy the code

7, test,

   @Test
   public void test2(a){
       ApplicationContext context = newClassPathXmlApplicationContext("beans.xml");
       UserMapper mapper = (UserMapper) context.getBean("userDao");
       List<User> user = mapper.selectUser();
       System.out.println(user);
  }
Copy the code

The result is successful! Now our Mybatis profile is in state! Found that all can be integrated by Spring!


      
<! DOCTYPEconfiguration
       PUBLIC "- / / mybatis.org//DTD Config / 3.0 / EN"
       "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
   <typeAliases>
       <package name="com.kuang.pojo"/>
   </typeAliases>
</configuration>
Copy the code

Integration Implementation two

Mybatis – Spring version 1.2.3 and above only have this.

Official document screenshot:

The DAO inherits the Support class, obtains it directly from getSqlSession(), and then directly injects SqlSessionFactory. There is no need to manage the SqlSessionTemplate and transaction friendly support compared to option 1. Can trace source view

Testing:

1. Modify the UserDaoImpl we wrote above

public class UserDaoImpl extends SqlSessionDaoSupport implements UserMapper {
   public List<User> selectUser(a) {
       UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
       returnmapper.selectUser(); }}Copy the code

2. Modify the bean configuration

<bean id="userDao" class="com.kuang.dao.UserDaoImpl">
   <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
Copy the code

3, test,

@Test
public void test2(a){
   ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
   UserMapper mapper = (UserMapper) context.getBean("userDao");
   List<User> user = mapper.selectUser();
   System.out.println(user);
}
Copy the code

Summary: After the integration into spring can completely do not mybatis configuration file, in addition to these ways to achieve integration, we can also use annotations to achieve this, such as we later learn SpringBoot when we will test integration!

Spring declarative transactions

Review of the transaction

  • Transaction is very important in the process of project development, involving the consistency of data, not to be careless!
  • Transaction management is an essential technology in enterprise application development to ensure data integrity and consistency.

A transaction is a series of actions that are treated as a single unit of work, all of which either complete or do not work.

Transaction four properties ACID

  1. Atomicity
    • A transaction is an atomic operation, consisting of a series of actions, and the atomicity of the transaction ensures that the actions either complete completely or do not work at all
  2. Consistency
    • Once all transaction actions are completed, the transaction is committed. Data and resources are in a consistent state that meets business rules
  3. Isolation
    • It is possible for multiple transactions to process the same data at the same time, so each transaction should be isolated from others to prevent data corruption
  4. “Durability”
    • Once a transaction completes, the results are unaffected by whatever errors occur to the system. Typically, the results of a transaction are written to persistent storage

test

Copy the above code into a new project

In the previous case, we added two new methods to the userDao interface: delete and add users;

// Add a user
int addUser(User user);

// Delete the user based on the ID
int deleteUser(int id);
Copy the code

· Mapper file, we deliberately miswrite deletes, test!

<insert id="addUser" parameterType="com.kuang.pojo.User">
insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
</insert>

<delete id="deleteUser" parameterType="int">
deletes from user where id = #{id}
</delete>
Copy the code

Write the implementation class of the interface, in which we operate on a wave

public class UserDaoImpl extends SqlSessionDaoSupport implements UserMapper {

   // Add some operations
   public List<User> selectUser(a) {
       User user = new User(4."Xiao Ming"."123456");
       UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
       mapper.addUser(user);
       mapper.deleteUser(4);
       return mapper.selectUser();
  }

   / / new
   public int addUser(User user) {
       UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
       return mapper.addUser(user);
  }
   / / delete
   public int deleteUser(int id) {
       UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
       returnmapper.deleteUser(id); }}Copy the code

test

@Test
public void test2(a){
   ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
   UserMapper mapper = (UserMapper) context.getBean("userDao");
   List<User> user = mapper.selectUser();
   System.out.println(user);
}
Copy the code

Error: SQL exception, delete write error

Result: Insert successful!

Not managing transactions; We want them all to succeed, there is a failure, they all fail, we should need business!

In the past, we all had to manage things manually, which was very troublesome!

But Spring gives us transaction management, and we just need to configure it;

Transaction management in Spring

Spring defines an abstraction layer on top of the different transaction management apis, allowing developers to use Spring’s transaction management mechanism without having to understand the underlying transaction management API. Spring supports both programmatic and declarative transaction management.

Programmatic transaction management

  • Embed transaction management code in business methods to control the commit and rollback of transactions
  • Disadvantages: Additional transaction management code must be included in each transaction operation business logic

Declarative transaction management

  • Generally better than programmatic transactions.
  • Separate transaction management code from business methods and implement transaction management declaratively.
  • Modularize transaction management as a crosscutting concern through an AOP approach. Declarative transaction management is supported in Spring through the Spring AOP framework.

To manage transactions using Spring, note the constraint import of the header file: tx

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

http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
Copy the code

Transaction manager

  • A transaction manager is required regardless of which of Spring’s transaction management strategies (programmatic or declarative) are used.
  • Spring’s core transaction management abstraction, management encapsulates a set of technology-independent methods.

JDBC transaction

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

After configuring the transaction manager, we need to configure the notification of the transaction

<! -- Configure transaction notification -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
   <tx:attributes>
       <! Configure which methods use which transactions, and configure the propagation characteristics of transactions -->
       <tx:method name="add" propagation="REQUIRED"/>
       <tx:method name="delete" propagation="REQUIRED"/>
       <tx:method name="update" propagation="REQUIRED"/>
       <tx:method name="search*" propagation="REQUIRED"/>
       <tx:method name="get" read-only="true"/>
       <tx:method name="*" propagation="REQUIRED"/>
   </tx:attributes>
</tx:advice>
Copy the code

Spring transaction propagation features:

Transaction propagation behavior is how a transaction propagates between multiple transaction methods when they call each other. Spring supports seven transaction propagation behaviors:

  • Propagation_requierd: Create a new transaction if no one currently exists, and join it if one already exists, which is the most common choice.
  • Propagation_supports: Supports the current transaction. If there is no current transaction, execute as a non-transactional method.
  • Propagation_mandatory: Use the current transaction, or throw an exception if there is no current transaction.
  • Propagation_required_new: Create a transaction, and suspend the current transaction, if one exists.
  • Propagation_not_supported: Executes an operation in a non-transactional manner, and suspends the current transaction, if one exists.
  • Propagation_never: Executes an operation in a non-transactional manner, throws an exception if the current transaction exists.
  • Propagation_nested: Executes within a nested transaction if a transaction currently exists. If there are no transactions currently, an operation similar to PROPAGation_REQUIRED is performed

Spring’s default transaction propagation behavior is PROPAGATION_REQUIRED, which is appropriate in most cases.

Assuming that ServiveX#methodX() is all working in a transactional environment (i.e., all enhanced by Spring transactions), assume that the following call chain exists in the program: Service1#method1()->Service2#method2()->Service3#method3(), so all three methods of these three service classes work in the same transaction through Spring’s transaction propagation mechanism.

For example, the methods we just called exist, so they are placed in a set of transactions!

The configuration of AOP

Import an AOP header file!

<! Configure AOP to weave into transactions -->
<aop:config>
   <aop:pointcut id="txPointcut" expression="execution(* com.kuang.dao.*.*(..) )"/>
   <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>
Copy the code

test

Delete the inserted data and test again!

@Test
public void test2(a){
   ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
   UserMapper mapper = (UserMapper) context.getBean("userDao");
   List<User> user = mapper.selectUser();
   System.out.println(user);
}
Copy the code

Thinking about a problem?

Why do YOU need to configure transactions?

  • If not, we need to manually commit the control transaction;
  • Transaction is very important in the process of project development, involving the consistency of data, not to be careless!