Spring 5 learning notes
[!TIP]
The notes are summarized from Bili Bili crazy God said spring 5.
1. Introduction
1.1 INTRODUCTION
[!NOTE]
The Spring framework is due to software development Created by the complexity of. Spring uses a basic JavaBean to do this. Previously, it could only be done by EJB Things done. However, the use of Spring is not limited to server-side development. In terms of simplicity, testability and loose coupling, most Java applications can benefit from Spring.
Spring is a lightweight open source framework of full stack for layered java SE/EE applications. With IOC (Inverse of control) and AOP (Aspect Oriented Programming) as the kernel, spring provides enterprise application technologies such as presentation layer spring MVC, persistence layer spring JDBC template and business layer transaction management, and can integrate various third-party frameworks and class libraries, It's a hodgepodge of technology.
- Official website: http://spring.io/
- GitHub : https://github.com/spring-projects
1.2 development history
[!NOTE]
- In 2002, Rod Jahnson first launched the Spring framework prototype interface21 framework
- On March 24, 2004, the Spring framework was redesigned based on the interface 21 framework and released the official version of 1.0
1.3 concept
[!NOTE]
The utility model makes the prior art more practical and simpler.
1.4 advantages
- Open source free container framework
- Lightweight non intrusive framework
- Excellent transaction support
[!NOTE]
Spring is a lightweight container (framework) for inversion of control (IoC) and aspect oriented (AOP).
1.4 composition
1.4.1 Spring Core
[!NOTE]
The core container provides the basic functions of the Spring framework. The main component of the core container is BeanFactory, which is the implementation of the factory pattern. BeanFactory uses inversion of control (IOC) to separate the configuration and dependency specifications of the application from the actual application code.
1.4.2 Spring Context
[!NOTE]
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, checksum and scheduling capabilities.
1.4.3 Spring AOP
[!NOTE]
Through the configuration management feature, the Spring AOP module directly integrates the aspect oriented programming functions into the Spring framework. Therefore, you can easily make the Spring framework manage any object that supports AOP. The Spring AOP module provides transaction management services for objects in Spring based applications. By using Spring AOP, declarative transaction management can be integrated into applications without relying on components.
1.4.4 Spring DAO
[!NOTE]
The JDBC DAO abstraction layer provides a meaningful exception hierarchy that can be used to manage exception handling and error messages thrown by different database vendors. The exception hierarchy simplifies error handling and greatly reduces the amount of exception code that needs to be written (such as opening and closing connections). Spring DAO's JDBC oriented exceptions follow a common DAO exception hierarchy.
1.4.5 Spring ORM
[!NOTE]
The Spring framework inserts several ORM frameworks to provide ORM object relationship tools, including JDO, Hibernate and iBatis SQL Map. All of this follows Spring's common transaction and DAO exception hierarchy.
1.4.6 Spring Web
[!NOTE]
The Web context module is built on the application context module and provides context for web-based applications. Therefore, the Spring framework supports integration with Jakarta Struts. The web module also simplifies processing multipart requests and binding request parameters to domain objects.
1.4.7 Spring Web MVC
[!NOTE]
MVC framework is a full-featured MVC implementation for building Web applications. Through the policy interface, the MVC framework becomes highly configurable. MVC accommodates a large number of view technologies, including JSP, Velocity, Tiles, iText and POI.
1.5 expansion
- Modern java development is Spring based development
- Spring Boot
- Rapid development of scaffolding
- Spring Cloud
- Multiple spring boots
2. Control reversal
2.1 prototype
2.1.1 UserDao
package com.dingwen.stu.spr.dao; /** * User dao * * @author dingwen * @date 2021/10/05 */ public interface UserDao { /** * Query user information by ID * * @param id id */ void selectById(String id); }
2.1.2 UserDaoMysqlImpl
package com.dingwen.stu.spr.dao.impl; import com.dingwen.stu.spr.dao.UserDao; /** * User dao impl * mysql realization * * @author dingwen * @date 2021/10/05 */ public class UserDaoMysqlImpl implements UserDao { @Override public void selectById(String id) { System.out.println("dao By user ID Query user information, mysql realization"); } }
2.1.3 UserDaoOracleImpl
package com.dingwen.stu.spr.dao.impl; import com.dingwen.stu.spr.dao.UserDao; /** * User dao impl * mysql realization * * @author dingwen * @date 2021/10/05 */ public class UserDaoOracleImpl implements UserDao { @Override public void selectById(String id) { System.out.println("dao By user ID Query user information, Oracle realization"); } }
2.1.4 UserService
package com.dingwen.stu.spr.service; /** * User services * * @author dingwen * @date 2021/10/05 */ public interface UserService { /** * Query user information by ID * * @param id id */ void selectById(String id); }
2.1.5 UserServiceImpl
2.1.5.1 implementation mode I
package com.dingwen.stu.spr.service.impl; import com.dingwen.stu.spr.dao.UserDao; import com.dingwen.stu.spr.service.UserService; /** * User service impl * * @author dingwen * @date 2021/10/05 */ public class UserServiceImpl implements UserService { /** * User dao */ private UserDao userDao = new UserDaoMysqlImpl(); private UserDao userDao = new UserDaoOracleImpl(); @Override public void selectById(String id) { userDao.selectById(id); } }
[!NOTE]
The needs of users will 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 once is very expensive.
2.1.5.2 implementation mode II
package com.dingwen.stu.spr.service.impl; import com.dingwen.stu.spr.dao.UserDao; import com.dingwen.stu.spr.service.UserService; /** * User service impl * * @author dingwen * @date 2021/10/05 */ public class UserServiceImpl implements UserService { /** * User dao */ private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void selectById(String id) { userDao.selectById(id); } }
[!NOTE]
Previously, the program actively created objects, and the control was in the hands of the programmer. After using set injection, the program no longer had the initiative, but became a passive acceptance object. This idea essentially realizes the problem, and programmers no longer have to manage the creation of objects. The coupling of the system is greatly reduced, and you can focus more on the implementation of business. This is the prototype of IOC.
2.2 essence
[!NOTE]
Inversion of control (IoC) is a design idea. DI (dependency injection) is a method to realize IoC. Some people think that DI is just another 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 through a third party. In Spring, the IoC container implements control inversion, and its implementation method is dependency injection (DI).
3. Hello Spring
3.1 dependency
<!--spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.17.RELEASE</version> </dependency>
3.2 Hello entity
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 + '\'' + '}'; } }
3.3 Spring configuration file
[!TIP]
The file name is optional.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--bean namely java object , from Spring Create and manage Type variable name = new type(); Hello hello = new Hello(); bean = object new Hello(); id = Variable name class = new Object of property It is equivalent to setting a variable for the attribute in the object --> <bean id="hello" class="nuc.ss.pojo.Hello"> <property name="str" value="Spring"/> </bean> </beans>
3.4 testing
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); } }
3.5 summary
[!NOTE]
- The object created by the program is changed to Spring to create the object
- Inversion: the program itself does not create an object, but becomes a passive receiving object
- Dependency injection
4. Configuration
4.1 alias configuration
[!NOTE]
Multiple aliases can be added, and the object can also be obtained through the alias.
<alias name="userServiceImpl" alias="userService"></alias> <alias name="userServiceImpl" alias="test"></alias>
4.2 Bean configuration
[!NOTE]
- ID: the unique identifier of the bean, which is equivalent to the object name we learned
- class: the permission naming corresponding to the bean object: package name + type
- Name: is also an alias, and name is more advanced. It can have multiple aliases, separated by commas, spaces, semicolons, etc
<bean id="userDaoOracleImpl" class="com.dingwen.stu.spr.dao.impl.UserDaoOracleImpl" name="userDaoOracleImpl,t2 t3"> <property name="userDao" ref="userDaoOracleImpl"></property> </bean>
4.3 import
[!NOTE]
Team cooperation is realized through import, which can merge multiple configuration files into one.
<import resource="beans2.xml"></import>
5. Dependency injection
[!NOTE]
- Dependency: the creation of Bean objects depends on the container
- Injection: refers to the resources that the Bean object depends on, which are set and assembled by the container
5.1 constructor injection
[!NOTE]
Parameterless construction is used by default.
5.1.1 creating objects using nonparametric constructs
<!--Parameterless constructor--> <bean id="user" class="nuc.ss.pojo.User"> <!--set Method must--> <property name="name" value="dingwen"/> </bean>
5.1.2 creating objects with parametric constructs
private String name; private int age; public UserDaoOracleImpl(String name, int age) { System.out.println("name = " + name); System.out.println("age = " + age); System.out.println("UserDaoOracleImpl constructor"); }
5.1.2.1 subscript assignment
<bean id="userDaoOracleImpl" class="com.dingwen.stu.spr.dao.impl.UserDaoOracleImpl"> <constructor-arg index="0" value="dingwen"></constructor-arg> <constructor-arg index="1" value="23"></constructor-arg> </bean>
5.1.2.2 parameter type assignment
<bean id="userDaoOracleImpl" class="com.dingwen.stu.spr.dao.impl.UserDaoOracleImpl"> <constructor-arg type="java.lang.String" value="dingwen"></constructor-arg> <constructor-arg type="int" value="23"></constructor-arg> </bean>
[!NOTE]
It is only applicable when there is only one or more parameters of the same type.
5.1.2.3 parameter name assignment
<bean id="userDaoOracleImpl" class="com.dingwen.stu.spr.dao.impl.UserDaoOracleImpl"> <constructor-arg name="name" value="dingwen"></constructor-arg> <constructor-arg name="age" value="23"></constructor-arg> </bean>
5.2 set mode injection
5.2.1 entity preparation
5.2.1.1 Address
package com.dingwen.stu.spr.di.entity; /** * address * * @author dingwen * @date 2021/10/05 */ public class Address { /** * 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 + '\'' + '}'; } }
5.2.1.2 Student
package com.dingwen.stu.spr.di.entity; import java.util.*; /** * student * * @author dingwen * @date 2021/10/05 */ public class Student { /** * name */ private String name; /** * Home address */ private Address address; /** * book */ private String[] books; /** * hobby */ private List<String> hobbies; /** * bank card */ private Map<String,String> cards; /** * game */ private Set<String> games; /** * Are you married */ private boolean isWife; /** * information */ 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> getCards() { return cards; } public void setCards(Map<String, String> cards) { this.cards = cards; } public Set<String> getGames() { return games; } public void setGames(Set<String> games) { this.games = games; } public boolean isWife() { return isWife; } public void setWife(boolean wife) { isWife = 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 + ", cards=" + cards + ", games=" + games + ", isWife=" + isWife + ", info=" + info + '}'; } }
5.2.2 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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--Normal value injection--> <bean id="address" class="com.dingwen.stu.spr.di.entity.Address"> <property name="address" value="Kunming"></property> </bean> <bean id="student" class="com.dingwen.stu.spr.di.entity.Student"> <!--Normal value injection--> <property name="name" value="dingwen"/> <!--Object reference injection--> <property name="address" ref="address"/> <!--Array injection--> <property name="books"> <array> <value>Thinking in Java</value> <value>C Language programming</value> <value>data structure</value> </array> </property> <!--list injection--> <property name="hobbies"> <list> <value>watch movie</value> <value>listen to the music</value> <value>Dry wine</value> </list> </property> <!--map injection--> <property name="cards"> <map> <entry key="China Merchants Bank" value="8888888"></entry> <entry key="agricultural bank" value="6666666"></entry> </map> </property> <!--set injection--> <property name="games"> <set> <value>LOL</value> <value>COC</value> <value>BOB</value> </set> </property> <!--null injection--> <property name="developer"> <null/> </property> <!--Properties injection--> <property name="info"> <props> <prop key="username">root</prop> <prop key="password">123456</prop> </props> </property> </bean> </beans>
5.2.3 testing
import com.dingwen.stu.spr.di.entity.Address; import com.dingwen.stu.spr.di.entity.Student; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class DITest { @Test public void test01(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml"); Address address = applicationContext.getBean("address", Address.class); System.out.println("address = " + address); Student student = applicationContext.getBean("student", Student.class); System.out.println("student = " + student); } }
5.2.4 results
ideVersion5 -junit4 DITest,test01 address = Address{address='Kunming'} student = Student{name='dingwen', address=Address{address='Kunming'}, books=[Thinking in Java, C Language programming, data structure], hobbies=[watch movie, listen to the music, Dry wine], cards={China Merchants Bank=8888888, agricultural bank=6666666}, games=[LOL, COC, BOB], isWife=false, developer='null', info={password=123456, username=root}} Process finished with exit code 0
5.3 expansion mode injection
[!NOTE]
Explained on the official website.
5.3.1 C namespace injection
5.3.1.1 introducing constraints
xmlns:c="http://www.springframework.org/schema/c"
5.3.1.2 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:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--c Namespaces can be injected through constructors construct-args--> <bean id="userDaoOracleImpl" class="com.dingwen.stu.spr.dao.impl.UserDaoOracleImpl" c:name="dingwen" c:age="24"></bean> </beans>
[!DANGER]
Injected through the constructor.
5.3.2 P namespace injection
5.3.2.1 introducing constraints
xmlns:p="http://www.springframework.org/schema/p"
5.3.2.2 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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--p Namespace can inject the value of an attribute directly property--> <bean id="userDaoOracleImpl" class="com.dingwen.stu.spr.dao.impl.UserDaoOracleImpl" p:name="dingwen" p:age="24"></bean> </beans>
[!DANGER]
Injection through set() requires no parameter construction method.
5.4 scope of bean
[!NOTE]
The essence of creating a bean definition is to use the corresponding class of the bean definition to create the "recipe" of the real instance. It is meaningful to regard the bean definition as a recipe. It is very similar to class. Multiple instances can be created according to only one "recipe". You can control not only the various dependencies and configuration values injected into the object, but also the scope of the object. In this way, you can flexibly select the scope of the created object without defining the scope at the Java Class level. The Spring Framework supports five scopes, which are described in the following table.
category | explain |
---|---|
singleton | There is only one Bean instance in the Spring IOC container, which exists in singleton mode. The default is singleton mode |
prototype | In the prototype mode, each time a Bean is obtained from the container, a new instance is returned, which is similar to new Object() |
request | Each Http request will create a Bean, which is only applicable to the WebApplicationContext environment |
session | The same session environment shares a Bean, which is only applicable to the WebApplicationContext environment |
globalSession | It is generally used as a Portlet application environment and is only applicable to the WebApplicationContext environment |
5.4.1 singleton
[!DANGER]
Singleton type is to automatically create a bean object when creating a container. It exists whether you use it or not, and the object obtained each time is the same object. Note that the singleton scope is the default scope in Spring. To define a bean as a singleton in XML, you can configure it as follows:
<bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">
5.4.2 prototype
[!DANGER]
Prototype type, which is not instantiated when we create the container, but creates an object when we get the bean, and the object we get each time is not the same object. As a rule of thumb, you should use the prototype scope for stateful beans and the singleton scope for stateless beans. Define a bean as a prototype in XML, which can be configured as follows:
<bean id="account" class="com.foo.DefaultAccount" scope="prototype"/> <!--perhaps--> <bean id="account" class="com.foo.DefaultAccount" singleton="false"/>
5.4.3 request
[!GDNGER]
Each HTTP request has its own bean instance, which is created according to a bean definition. This scope is only valid in the case of web-based Spring ApplicationContext. Consider the following bean definitions:
<bean id="loginAction" class=com.foo.LoginAction" scope="request"/>
5.4.4 session
[!DANGER]
In an HTTP Session, a bean definition corresponds to an instance. This scope is only valid in the case of web-based Spring ApplicationContext. Consider the following bean definitions:
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
5.4.5 global session
[!DANGER]
Indicates that in a global HTTP Session, a bean definition corresponds to an instance. Typically, it is only valid when using portlet context. This scope is only valid in the case of web-based Spring ApplicationContext. Consider the following bean definitions:
<bean id="user" class="com.foo.Preferences "scope="globalSession"/>
[!TIP]
The global session scope is similar to the standard HTTP Session scope, but only meaningful in portlet based web applications. The portlet specification defines the concept of global session, which is shared by all the different portlets that make up a portlet web application. The bean s defined in the global session scope are limited to the life cycle of the global portlet Session.
6. Automatic assembly of bean
6.1 introduction
[!NOTE]
- Automatic assembly is a way for Spring to meet bean dependencies
- Spring will automatically find in the context and automatically assemble properties for the bean
6.2 three automatic assembly methods
[!NOTE]
- Configuration displayed in xml
- Display configuration in java
- Implicit auto assembly bean
6.3 test environment preparation
6.3.1 Cat
package com.dingwen.stu.spr.auto.entity; /** * cat * * @author dingwen * @date 2021/10/05 */ public class Cat { public void shut(){ System.out.println("Meow meow~"); } }
6.3.2 Dog
package com.dingwen.stu.spr.auto.entity; /** * @author dingwen * @date 2021/10/05 */ public class Dog { public void shut(){ System.out.println("Wangwang~"); } }
6.3.3 People
package com.dingwen.stu.spr.auto.entity; /** * people * * @author dingwen * @date 2021/10/05 */ public class People { /** * name */ private String name; /** * cat */ private Cat cat; /** * dog */ private Dog dog; public String getName() { return name; } public void setName(String name) { this.name = name; } public Cat getCat() { return cat; } public void setCat(Cat cat) { this.cat = cat; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } @Override public String toString() { return "People{" + "name='" + name + '\'' + ", cat=" + cat + ", dog=" + dog + '}'; } }
6.4 byName
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="cat" class="com.dingwen.stu.spr.auto.entity.Cat"></bean> <bean id="dog" class="com.dingwen.stu.spr.auto.entity.Dog"></bean> <!-- byName:It will automatically nest in the container context and connect with its own object set Corresponding to the value after the method bean id The current container meets the requirements of automatic assembly Bean of Id You must and properties in dependent objects set The value after the method corresponds to --> <bean id="people" class="com.dingwen.stu.spr.auto.entity.People" autowire="byName"> <property name="name" value="dingwen"></property> </bean> </beans>
6.5 byType
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="cat1" class="com.dingwen.stu.spr.auto.entity.Cat"></bean> <bean id="dog2" class="com.dingwen.stu.spr.auto.entity.Dog"></bean> <!-- byType:It will be automatically nested in the container context, with the same property type as its own object bean id The type of dependent object injection in the current container environment must be unique --> <bean id="people" class="com.dingwen.stu.spr.auto.entity.People" autowire="byType"> <property name="name" value="dingwen"></property> </bean> </beans>
6.6 summary
[!NOTE]
- 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 the bean needs to be consistent with the type of the automatically injected attribute
6.7 automatic assembly using annotations
6.7.1 opening notes
[!NOTE]
- Import constraints: context support
- 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>
6.7.2 @Autowired
[!NOTE]
- Packages that need to be imported into spring AOP
- It can be used directly on attributes or in set mode
- Using Autowired, we don't need to write a set method, provided that your auto assembled attribute exists in the IOC (Spring) container and conforms to the name byName and type byType
<!--Normal 1( byName)--> <bean id="cat" class="com.dingwen.entity.Cat"/> <bean id="dog" class="com.dingwen.entity.Dog"/> <bean id="people" class="com.dingwen.People"/> <!--Normal 2( byType)--> <bean id="cat111" class="com.dingwen.entity.Cat"/> <bean id="dog222" class="com.dingwen.entity.Dog"/> <bean id="people" class="com.dingwen.entity.People"/> <!--Normal 3 (mixed use, type before name)--> <bean id="cat11" class="com.dingwen.entity.Cat"/> <bean id="cat" class="com.dingwen.entity.Cat"/> <bean id="dog222" class="com.dingwen.entity.Dog"/> <bean id="people" class="com.dingwen.entity.People"/> <!--Abnormal (multiple types and names do not match, an error is reported--> <bean id="cat11" class="com.dingwen.entity.Cat"/> <bean id="cat111" class="com.dingwen.entity.Cat"/> <bean id="dog22" class="com.dingwen.entity.Dog"/> <bean id="dog222" class="com.dingwen.entity.Dog"/> <bean id="people" class="com.dingwen.entity.People"/>
package com.dingwen.stu.spr.auto.entity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import javax.annotation.Resource; /** * people * * @author dingwen * @date 2021/10/05 */ public class People { /** * name */ private String name; /** * cat * @Autowired Match based on byType first. When there are multiple beans of the same type and byName cannot complete the matching *,Use @ Qualifier to specify Bean Id */ @Autowired(required = false)If the displayed definition Autowired of required Attribute is false,Indicates that this object can be null,Otherwise, it is not allowed to be empty @Qualifier(value = "cat1") private Cat cat; /** * dog * @Resource First, match based on byName. When the name corresponding to the set method of the dependent object cannot be matched, use byType to match, *. If not, you need to specify Bean Id through name */ @Resource(name = "dog1") private Dog dog; public String getName() { return name; } public void setName(String name) { this.name = name; } public Cat getCat() { return cat; } public void setCat(Cat cat) { this.cat = cat; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } @Override public String toString() { return "People{" + "name='" + name + '\'' + ", cat=" + cat + ", dog=" + dog + '}'; } }
[!NOTE]
- @Autowired is implemented by bytype by default. If there are multiple types, it is implemented by byname. If both types cannot be found, an error is reported
- Conflict resolution: @ Autowired is used with @ Qualifier(value = "Bean Id")
- @Resource is implemented by byname by default. If the name cannot be found, it is implemented by bytype. If both names cannot be found, it is an error
- Conflict resolution: @ Resource directly uses @ Resource(name = "Bean Id")
7. Development using annotations
[!DANGER]
- Ensure that the AOP package is imported
- Enable annotation scanning
- Enable 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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--Configure annotation scanning--> <context:component-scan base-package="com.dingwen.stu.spr.auto"/> <!--Enable annotation support--> <context:annotation-config/> </beans>
7.1 @Component
[!NOTE]
Inject Bean, equivalent to:
<bean id="user" class="com.dingwen.entity.User"/>
7.1.1 derived notes
[!NOTE]
The four derived annotation functions are consistent, and all are injected into a Bean.
7.1.1.1 @Repository
[!NOTE]
Used for data access layer.
7.1.1.2 @Service
[!NOTE]
For the service layer.
7.1.1.3@Controller
[!NOTE]
Used to attempt to control the layer.
7.2 automatic assembly
7.2.1 @Autoried
[!NOTE]
By default, it is implemented by bytype. If there are multiple types, it is implemented by byname. If both types cannot be found, an error is reported. Cooperate with @ Qualifier(value = "Bean Id") to resolve conflicts.
7.2.2 @Resource
[!NOTE]
By default, it is implemented by byname. If the name cannot be found, it is implemented by bytype. If both names cannot be found, it is an error. Resolve the conflict by specifying the Bean Id with the name attribute.
8. Configure Spring in java
8.1 configuration file
//This is also managed by the Spring container and registered in the container, because it is originally a @ Component, // @Component means that this is a configuration class, which is the same as beans.xml we saw earlier // @Import merge other configuration classes @Configuration @ComponentScan("com.dingwen") @Import(MyConfig2.class) public class MyConfig { //Registering a bean is equivalent to a bean tag we wrote earlier, //The name of this method is equivalent to the id attribute of 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 injected into the bean! } }
8.2 testing
@Test public void test1() { // If the configuration class is completely used, we can only do it through AnnotationConfig //Context to get the container, and load it through the class object of the configuration class! ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class); User getUser = context.getBean("getUser", User.class); System.out.println(getUser.getName()); }
9. Agency mode
[!NOTE]
Agent mode is the bottom layer of AOP,
9.1 classification
[!NOTE]
- Static proxy
- Dynamic agent
9.2 role analysis
[!NOTE]
Abstract role: interface, abstract class, class
- Real role: the role represented
- Proxy role: proxy real role
- Customer role: the person who accesses the proxy object
9.3 static proxy
9.3.1 Abstract rental interface
package com.dingwen.pro.demo01; /** * Abstract excuse for renting a house * * @author dingwen * @date 2021/10/06 */ public interface Rent { /** * Rent a house */ void rent(); }
9.3.2 Abstract role (landlord)
package com.dingwen.pro.demo01; /** * landlord or landlady * * @author dingwen * @date 2021/10/06 */ public class Host implements Rent{ @Override public void rent() { System.out.println("The landlord wants to rent the house"); } }
9.3.3 agent role (intermediary)
package com.dingwen.pro.demo01; /** * intermediary * * @author dingwen * @date 2021/10/06 */ public class Intermediary implements Rent{ /** * landlord or landlady */ private Host host; public void setHost(Host host) { this.host = host; } @Override public void rent() { // Show me the house see(); host.rent(); sign(); // Sign a contract } public void see(){ System.out.println("House viewing"); } public void sign(){ System.out.println("sign a contract"); } }
9.3.4 testing
package com.dingwen.pro.demo01; /** * client * * @author dingwen * @date 2021/10/06 */ public class Client { public static void main(String[] args) { Host host = new Host(); Intermediary intermediary = new Intermediary(); intermediary.setHost(host); intermediary.rent(); } }
The landlord wants to rent the house and sign a contract
9.3.5 summary
[!NOTE]
- advantage
- Make the operation of real roles more pure without paying attention to some public businesses
- The role of public agent is given to realize the division of business
- When the public business is expanded, it is convenient for centralized management
- shortcoming
- A real role produces a proxy role
- The amount of code will double - development efficiency will become lower
9.3.6 deepen understanding
[!NOTE]
Add the function of logging without changing the original code.
We can enhance the original functions without changing the original code, which is the core idea of AOP
9.3.6.1 abstract interface
package com.dingwen.pro.demo02; /** * User services * * @author dingwen * @date 2021/10/06 */ public interface UserService { /** * add to */ void add(); /** * delete */ void remove(); /** * Query by id */ void findById(); /** * modify */ void modify(); }
9.3.6.2 real role
package com.dingwen.pro.demo02; /** * User service impl * * @author dingwen * @date 2021/10/06 */ public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("add"); } @Override public void remove() { System.out.println("remove"); } @Override public void findById() { System.out.println("findById"); } @Override public void modify() { System.out.println("modify"); } }
9.3.6.3 agent role
package com.dingwen.pro.demo02; /** * User service impl proxy * * @author dingwen * @date 2021/10/06 */ public class UserServiceImplProxy implements UserService { /** * User services */ private UserService userService; public void setUserService(UserService userService) { this.userService = userService; } @Override public void add() { userService.add(); log("add"); } @Override public void remove() { userService.remove(); log("remove"); } @Override public void findById() { userService.findById(); log("findById"); } @Override public void modify() { userService.modify(); log("modify"); } public void log(String msg){ System.out.println("journal: "+ msg); } }
9.3.6.3 testing
package com.dingwen.pro.demo02; /** * client * * @author dingwen * @date 2021/10/06 */ public class Client { public static void main(String[] args) { UserServiceImpl userService = new UserServiceImpl(); UserServiceImplProxy proxy = new UserServiceImplProxy(); proxy.setUserService(userService); proxy.add(); proxy.findById(); proxy.remove(); proxy.modify(); } } // result add journal: add findById journal: findById remove journal: remove modify journal: modify
9.4 dynamic agent
9.4.1 introduction
[!NOTE]
- The proxy class of dynamic proxy is generated dynamically, which is not written directly
- Dynamic agent classification
- Interface based: JDK dynamic agent
- Class based: cglib
- java bytecode implementation: javasist (Japan)
- Core class
- Proxy: generate proxy object
- InvocationHandler: call handler
9.4.2 advantages
- Make the operation of real roles more pure without paying attention to some public businesses
- The role of public agent is given to realize the division of business
- When the public business is expanded, it is convenient for centralized management
- A dynamic agent class represents an interface, which is generally a corresponding type of business
- A dynamic proxy class can proxy multiple classes as long as it implements the same interface [core]
9.4.3 code implementation
9.4.3.1 abstract interface
package com.dingwen.pro.demo03; /** * Abstract excuse for renting a house * * @author dingwen * @date 2021/10/06 */ public interface Rent { /** * Rent a house */ void rent(); }
9.4.3.2 real role
package com.dingwen.pro.demo03; /** * landlord or landlady * * @author dingwen * @date 2021/10/06 */ public class Host implements Rent { @Override public void rent() { System.out.println("The landlord wants to rent the house"); } }
9.4.3.3 event handling procedure
package com.dingwen.pro.demo03; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Proxy call handler * * @author dingwen * @date 2021/10/06 */ public class ProxyInvocationHandler implements InvocationHandler { /** * Abstract interface */ private Rent rent; public void setRent(Rent rent) { this.rent = rent; } /** * Get proxy object * * @return {@link Object} */ public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader() ,rent.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { see(); Object result = method.invoke(rent, args); sign(); return result; } public void see(){ System.out.println("House viewing"); } public void sign(){ System.out.println("sign a contract"); } }
9.4.5 summary
package com.dingwen.pro.demo04; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Proxy call handler * * @author dingwen * @date 2021/10/06 */ public class ProxyInvocationHandler implements InvocationHandler { /** * Target object */ private Object target; public void setTarget(Object target) { this.target = target; } /** * Get proxy object * * @return {@link Object} */ public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(target, args); log(method.getName()); return result; } public void log(String msg){ System.out.println("journal:"+ msg); } }
10. AOP
10.1 introduction
[!NOTE]
AOP (Aspect Oriented Programming) means: Aspect Oriented Programming, which realizes the unified maintenance of program functions through precompiled mode and runtime dynamic agent. AOP is the continuation of OOP, a hot spot in software development, an important content in Spring framework, and a derivative paradigm of functional programming. AOP can isolate each part of business logic, reduce the coupling between each part of business logic, improve the reusability of program, and improve the efficiency of development.
10.2 application in Spring
10.2.1 basic concepts
[!NOTE]
- Crosscutting concerns: methods or functions that span multiple modules of an application. That is, the part that has nothing to do with our business logic, but we need to focus on is crosscutting concerns. Such as log, security, cache, transaction and so on
- ASPECT: a special object whose crosscutting concerns are modularized. That is, it is a class
- Advice: work that must be completed in all aspects. That is, it is a method in a class
- Target: notified object, target object
- Proxy: object created after notification is applied to the target object, proxy object
- PointCut: the definition of the "place" where the aspect notification is executed, method
- Join point: the execution point that matches the pointcut, invoke
10.2.2 reanalysis combined with log cases
10.2.3 type of notice
Notification type | Connection point | Implementation interface |
---|---|---|
Before advice | Before method | org.springframework.aop.MethodBeforeAdvice |
Post notification | After method | org.springframework.aop.AfterReturningAdvice |
Around Advice | Before and after method | org.aopalliance.intercept.MethodInterceptor |
Exception throw notification | Method throws an exception | org.springframework.aop.ThrowsAdvice |
Introduction notice | Add a new method attribute to the class | org.springframework.aop.IntroductionInterceptor |
10.2.4 case use
[!NOTE]
Using AOP weaving requires importing aspectjweaver dependency packages.
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>
10.2.4.5 business preparation
// Abstract interface package com.dingwen.stu.spr.aop; /** * User services * * @author dingwen * @date 2021/10/06 */ public interface UserService { /** * add to */ void add(); /** * delete */ void remove(); /** * Query by id */ void findById(); /** * modify */ void modify(); } // Implementation class package com.dingwen.stu.spr.aop; /** * User service impl * * @author dingwen * @date 2021/10/06 */ public class UserServiceImpl implements UserService { @Override public void add() { System.out.println("add"); } @Override public void remove() { System.out.println("remove"); } @Override public void findById() { System.out.println("findById"); } @Override public void modify() { System.out.println("modify"); } }
10.2.4.2 using Spring API
10.2.4.2.1 code
// Post notification test package com.dingwen.stu.spr.advice; import org.springframework.aop.AfterReturningAdvice; import java.lang.reflect.Method; /** * Post notification test * * @author dingwen * @date 2021/10/07 */ public class AfterTest implements AfterReturningAdvice { @Override public void afterReturning(Object returnValue, Method method, Object[] objects, Object target) throws Throwable { System.out.println("Post notification execution, class" + target.getClass().getName() + "of" + method.getName() + "method. The return value is" + returnValue); } } // Pre notification test package com.dingwen.stu.spr.advice; import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; /** * Pre notification test * * @author dingwen * @date 2021/10/07 */ public class BeforeTest implements MethodBeforeAdvice { @Override public void before(Method method, Object[] objects, Object target) throws Throwable { System.out.println("Pre notification in"+target.getClass().getName()+ "of"+ method.getName()+ "Previous execution"); } }
10.2.4.2.1 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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--register bean--> <bean id="userService" class="com.dingwen.stu.spr.aop.UserServiceImpl"/> <bean id="before" class="com.dingwen.stu.spr.advice.BeforeTest"/> <bean id="after" class="com.dingwen.stu.spr.advice.AfterTest"/> <!--aop Configuration of--> <aop:config> <!--breakthrough point expression:The expression matches the method to execute--> <!--Permission package class method (parameter type)--> <aop:pointcut id="pointcut" expression="execution(* com.dingwen.stu.spr.aop.*.*(..))"/> <!--Perform wrap; advice-ref Execution method . pointcut-ref breakthrough point--> <aop:advisor advice-ref="before" pointcut-ref="pointcut"/> <aop:advisor advice-ref="after" pointcut-ref="pointcut"/> </aop:config> </beans>
10.2.4.2.3 test
import com.dingwen.stu.spr.aop.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AopTest { public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = applicationContext.getBean("userService", UserService.class); userService.add(); } } //result Pre notification in com.dingwen.stu.spr.aop.UserServiceImpl of add Previous execution add Post notification execution, class com.dingwen.stu.spr.aop.UserServiceImpl of add method. The return value is null
10.2.4.3 user defined implementation
10.2.4.3.1 custom section
package com.dingwen.stu.spr.diy; /** * Custom notification cut in class * * @author dingwen * @date 2021/10/07 */ public class DiyPointCut { /** * front */ public void before(){ System.out.println("Custom pre notification"); } /** * after */ public void after(){ System.out.println("Custom post notification"); } }
10.2.4.3.2 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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--register bean--> <bean id="userService" class="com.dingwen.stu.spr.aop.UserServiceImpl"/> <bean id="diyPointCut" class="com.dingwen.stu.spr.diy.DiyPointCut"></bean> <!--Custom section--> <aop:config> <aop:aspect ref="diyPointCut"> <aop:pointcut id="point" expression="execution(* com.dingwen.stu.spr.aop.*.*(..))"/> <aop:after method="after" pointcut-ref="point"></aop:after> <aop:before method="before" pointcut-ref="point"></aop:before> </aop:aspect> </aop:config> </beans>
10.2.4.4 annotation implementation
10.2.4.4.1 annotation implementation
package com.dingwen.stu.spr.ann; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; /** * Implementation of section based on annotation * * @author dingwen * @date 2021/10/07 */ @Aspect //@EnableAspectJAutoProxy public class AnnotationPointCut { @Before("execution(* com.dingwen.stu.spr.aop.*.*(..))") public void before(){ System.out.println("Custom annotation implementation, method execution notification"); } @After("execution(* com.dingwen.stu.spr.aop.*.*(..))") public void after(){ System.out.println("Custom annotation implementation, executed after method execution"); } @Around("execution(* com.dingwen.stu.spr.aop.*.*(..))") public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("Custom annotation implementation, execution around notification"); // Get method signature Signature signature = proceedingJoinPoint.getSignature(); // Method execution proceedingJoinPoint.proceed(); System.out.println("Custom annotation implementation, execution around notification"); } }
10.3.4.4.2 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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--register bean--> <bean id="userService" class="com.dingwen.stu.spr.aop.UserServiceImpl"/> <bean id="annotationPointCut" class="com.dingwen.stu.spr.ann.AnnotationPointCut"></bean> <!--Enable annotation support proxy-target-class The default value is false Dynamic agent based JDK realization true Means yes cglib realization --> <aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy> </beans>
10.2.5 After & AfterRunning
[!DANGER]
All are post notifications. The difference is whether there is a return value. The return value is the return value of the cut in method itself.
11. Integrate Mybatis
11.1 dependence
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>Spring-Study</artifactId> <groupId>nuc.ss</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-10-mybatis</artifactId> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.7.RELEASE</version> </dependency> <!--Spring If you operate the database, you also need one spring-jdbc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.7.RELEASE</version> </dependency> <!--Code weaving into packages to be imported--> <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.10</version> </dependency> </dependencies> <!--solve XML No packaging issues--> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build> </project>
11.3 preparation entity
package com.dingwen.entity; @Data public class User { private int id; private String name; private String pwd; }
11.4 mybatis-config.xml
<?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="nuc.ss.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&useUnicode=true&characterEncoding=utf8"/> <property name="username" value="root"/> <property name="password" value="admin"/> </dataSource> </environment> </environments> <mappers> <package name="nuc.ss.dao"/> </mappers> </configuration>
11.5 interface
public interface UserMapper { public List<User> selectUser(); }
11.6 mapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.dingwen.dao.UserMapper"> <select id="selectUser" resultType="User"> select * from user </select> </mapper>
11.7 testing
@Test public void selectUser() throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().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(); }
11.8 integration (mybatis spring)
11.8.1 dependence
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.2</version> </dependency>
11.8.2 import configuration file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
11.8.3 configuring data sources
<!--Configure data sources: there are many data sources. You can use third-party or Spring of--> <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&useUnicode=true&characterEncoding=utf8"/> <property name="username" value="root"/> <property name="password" value="admin"/> </bean>
11.8.4 sqlSessionFactory
<!--to configure SqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!--relation Mybatis--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath:nuc/ss/dao/*.xml"/> </bean>
11.8.5 sqlSessionTemplate
<!--register sqlSessionTemplate , relation sqlSessionFactory--> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <!--Using constructor injection,No, set Injection, only constructor injection can be used--> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean>
11.8.6 impl
public class UserDaoImpl implements UserMapper { //sqlSession does not need to be created by ourselves, but managed by Spring private SqlSessionTemplate sqlSession; public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; } public List<User> selectUser() { UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.selectUser(); } } // perhaps public class UserDaoImpl extends SqlSessionDaoSupport implements UserMapper { public List<User> selectUser() { UserMapper mapper = getSqlSession().getMapper(UserMapper.class); return mapper.selectUser(); } }
<bean id="userDao" class="com.dingwen.dao.UserDaoImpl"> <property name="sqlSession" ref="sqlSession"/> </bean>
// test @Test public void test2(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserMapper mapper = (UserMapper) context.getBean("userDao"); List<User> user = mapper.selectUser(); System.out.println(user); }
11.8.7 complete the integration of mybatis-config.xml
<?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> <!--You can also Spring Configuration completed in--> <typeAliases> <package name="com.dingwen.entity"/> </typeAliases> </configuration>
12. Declarative matters
12.1 meaning
[!NOTE]
Treat a group of business as a business; Either all succeed or all fail.
12.2 ACID
[!NOTE]
- Atomicity: a transaction is an atomic operation consisting of a series of actions. The atomicity of a transaction ensures that the actions are either completely completed or completely ineffective
- consistency: once all transaction actions are completed, the transaction will be committed. Data and resources are in a consistent state that meets business rules
- isolation: multiple services may operate the same resource to prevent data corruption
- Persistence: once a transaction is committed, no matter what happens to the system, the result will not be affected and will be written to the memory persistently
12.3 transaction management in spring
12.3.1 declarative transactions
[!NOTE]
- Generally, it works better than programmatic transactions
- The transaction management code is separated from the business method to realize the transaction management in a declarative way
- Transaction management is regarded as a crosscutting concern and modularized through aop method. Spring supports declarative transaction management through the Spring AOP framework
12.3.2 programmatic transactions
[!NOTE]
- Embed transaction management code into business methods to control transaction commit and rollback
- Additional transaction management code must be included in each transaction operation business logic
12.3.3 configuration and use
12.3.3.1 header file constraints
xmlns:tx="http://www.springframework.org/schema/tx" http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
12.3.3.3.2 transaction manager
[!NOTE]
- No matter which transaction management strategy (programmatic or declarative) Spring uses, the transaction manager is required
- Spring's core transaction management abstraction encapsulates a set of technology independent methods
12.3.3.3.3 JDBC transactions
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean>
12.3.3.3.4 notification of configuration transactions
<!--Configure transaction notifications--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!--What methods are configured and what transactions are used,Configure propagation properties 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>
12.3.3.3.5 weaving in transactions
<!--to configure aop Weaving transaction--> <aop:config> <aop:pointcut id="txPointcut" expression="execution(* nuc.ss.dao.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/> </aop:config>
12.3.4 complete configuration case
<?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:tx="http://www.springframework.org/schema/tx" 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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--DataSource: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&useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="admin"/> </bean> <!--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:nuc/ss/mapper/*.xml"/> </bean> <!--Configure declarative transactions--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--<constructor-arg ref="dataSource"/>--> <property name="dataSource" ref="dataSource" /> </bean> <!--combination AOP Implement transaction import--> <!--Configure transaction Notifications:--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!--For which methods are transactions configured--> <!--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="query" read-only="true"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!--Configure transaction weaving--> <aop:config> <aop:pointcut id="txPointCut" expression="execution(* nuc.ss.mapper.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config> </beans>
12.4 propagation characteristics of transactions
[!NOTE]
Transaction propagation behavior is how transactions propagate among multiple transaction methods when they call each other. spring supports seven transaction propagation behaviors.
12.4.1 propagation_requierd
[!NOTE]
If there is no current transaction, create a new transaction. If there is an existing transaction, join it. This is the most common choice.
12.4.2 propagation_supports
[!NOTE]
The current transaction is supported. If there is no current transaction, it will be executed in a non transaction method.
12.4.3 propagation_required_new
[!NOTE]
Create a new transaction. If there is a current transaction, suspend the current transaction.
12.4.4 propagation_not_supported
[!NOTE]
The operation is performed in a non transactional manner. If there is a current transaction, the current transaction is suspended.
12.4.5 propagation_neve
[!NOTE]
Execute the operation in a non transactional manner, and throw an exception if the current transaction exists.
12.4.6 propagation_mandatory
[!NOTE]
Use the current transaction. If there is no current transaction, throw an exception.
12.4.7 propagation_nested
[!NOTE]
If a transaction currently exists, it is executed within a nested transaction. If there is no transaction at present, the and propagation are executed_ Required similar operations.