Thanks to the following bloggers for their notes:
https://blog.csdn.net/bell_love/article/details/107753674
https://blog.csdn.net/li643937579/article/details/109569887
1,Spring
1.1 INTRODUCTION
brief introduction
- Spring: spring -- > brings spring to the software industry
- In 2002, the prototype of Spring framework: interface framework was launched for the first time!
- Spring framework is based on interface21 framework. After redesign and constantly enriching its connotation, it released the official version of 1.0 on March 24, 2004
- Rod Johnson, founder and famous author of Spring Framework. It's hard to imagine that rod Johnson's degree really surprised many people. He is a doctor at the University of Sydney. However, his major is not computer, but musicology.
- spring concept: making existing technologies easier to use is a hodgepodge in itself.
- SSH: Struct2 + Spring + Hibernate
- SSM: SpringMVC + Spring + Mybatis
Spring official website: https://spring.io/projects/spring-framework#overview
Official download: https://repo.spring.io/release/org/springframework/spring/
GitHub: https://github.com/spring-projects/spring-framework
Spring Web MVC: Spring webmvc latest edition
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.7.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.7.RELEASE</version> </dependency>
1.2 advantages
- Spring is an open source free framework (container)!
- Spring is a lightweight, non intrusive framework
- Inversion of control (IOC), aspect oriented programming (AOP)!
- Support transaction processing and framework integration
Open source free container, lightweight, non intrusive, control inversion, aspect oriented, support transaction, support framework integration
Spring is a lightweight framework for inversion of control (IOC) and aspect oriented (AOP) programming
1.3 composition
1.4. Expansion
Modern java development - > Spring based development
- Spring Boot
- A rapid development of scaffolding.
- Based on SpringBoot, you can quickly develop a single microservice.
- The contract is greater than the configuration.
- Spring Cloud
- Spring cloud is implemented based on SpringBoot.
Because most companies are now using SpringBoot for rapid development, the premise of learning SpringBoot is to fully master Spring and Spring MVC! The role of connecting the preceding and the following!
Disadvantages: after developing for too long, it violates the original concept! Configuration is very cumbersome, known as "configuration hell!"
2. IOC theoretical derivation
- UserDao interface
package com.kuang.dao; public interface UserDao { void getUser(); }
- UserDaoImp
package com.kuang.dao; public class UserDaoImpl implements UserDao{ public void getUser() { System.out.println("Get user data by default!"); } }
- UserSevice
package com.kuang.service; public interface UserService { void getUser(); }
- UserServiceImp
package com.kuang.service; import com.kuang.dao.UserDao; import com.kuang.dao.UserDaoImpl; public class UserServiceImpl implements UserService{ UserDao userDao = new UserDaoImpl(); public void getUser(){ userDao.getUser(); } }
Test:
import com.kuang.service.UserService; import com.kuang.service.UserServiceImpl; public class MyTest { public static void main(String[] args) { // What users actually call is the business layer, and they do not need to touch the dao layer UserService userService = new UserServiceImpl(); userService.getUser(); } }
In our previous business, the needs of users may affect our original code. We need to modify the original code according to the needs of users! If the amount of program code is very large, the cost of modifying once is very expensive!
We use a Set interface implementation, which has undergone revolutionary changes!
//Add a Set() method to the implementation class (UserServiceImpl) of the Service layer //Use set to dynamically realize value injection! private UserDao userDao; public void setUserDao(UserDao userDao){ this.userDao = userDao; }
The set() method actually dynamically changes the initialization part of userdao (new UserDaoImpl())
Add to the test:
((UserServiceImpl)userService).setUserDao(new UserDaoImpl());
- Before, the program was actively creating objects! Control is in the hands of the program ape!
- After using set injection, the program is no longer active, but becomes a passive receiving object!
Essentially, the problem is solved, and programmers no longer have to manage the creation of objects
The coupling of the system is greatly reduced, so we can focus more on the implementation of business
This is the prototype of IOC (control inversion). Inversion (understanding): the initiative is handed over to the user
IOC essence
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,HolleSpring
Import the jar package in the parent module
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.11.RELEASE</version> </dependency>
- Create a maven project and write entity classes
package com.kuang.pojo; public class Hello { private String str; public String getStr() { return str; } public void setStr(String str) { this.str = str; } @Override public String toString() { return "Hello{" + "str='" + str + '\'' + '}'; } }
- Write xml configuration file in resources
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <!--use Spring To create an object, in Spring These are called Bean Type variable name = new type(); Hello hello = new Hello(); id = Variable name class = new Object of property It is equivalent to setting a value for the attribute in the object! --> <bean id="hello" class="com.kuang.pojo.Hello"> <property name="str" value="Spring"/> </bean> </beans>
- Test class MyTest
import com.kuang.pojo.Hello; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { public static void main(String[] args) { //Get the context object of Spring ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //Our objects can be managed in spring. We need to use them and just take them out directly Hello holle = (Hello) context.getBean("hello"); System.out.println(holle.toString()); } }
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.
This process is called control reversal:
Control: who controls the creation of objects? Traditional application objects are created by the program itself. After using Spring, objects are created by Spring.
Inversion: the program itself does not create an object, but becomes a passive receiving object.
Dependency injection: it uses the set method to inject.
IOC is a programming idea, from active programming to passive reception.
You can browse the underlying source code through the new ClassPathXmlApplicationContext.
OK, up to now, we don't need to change it in the program at all. To realize different operations, we only need to modify it in the xml configuration file. The so-called IOC is done in one sentence: objects are created, managed and assembled by Spring!
**Simple understanding of bullet screen boss: * * is equivalent to inviting someone to dinner
The original procedure is: you write the menu and buy the dishes. When the guests come, fry the dishes and serve them
Now this procedure is: you tell the downstairs restaurant what dishes you want. When the guests come, the restaurant will deliver the dishes you need
IoC: cooking is no longer done by yourself, but entrusted to a third party – > restaurant
The difference at this time is that if I need to cook other dishes, I don't need to make recipes and buy materials myself, but tell the restaurant what dishes I want and when to send them
Try introducing Spring in the first module
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="userDaomSql" class="com.kuang.dao.UserDaoMysqlImpl"></bean> <bean id="userServiceImpl" class="com.kuang.service.UserServiceImpl"> <!--ref quote spring A good object has been created in--> <!--value Is a specific value,Basic data type--> <property name="userDao" ref="userDaomSql"/> </bean> </beans>
The first module is tested after improvement
import com.kuang.service.UserServiceImpl; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean("userServiceImpl"); userServiceImpl.getUser(); } }
Summary:
All classes should be assembled in beans.xml (spring configuration file);
All bean s should be fetched through the container;
The bean obtained in the container is an object, which can be used to call the method;
4. How IOC creates objects
-
Create objects using parameterless construction, default.
-
Use parametric construction (as follows)
1. Subscript assignment
index refers to the subscript of the parameter in the parameterized structure, starting from 0;
<!--The first method: subscript assignment --> <bean id="user" class="com.kuang.pojo.User"> <constructor-arg index="0" value="Madness theory Java"/> </bean>
2. Type assignment (not recommended)
<!--The second method is to create a type. It is not recommended --> <bean id="user" class="com.kuang.pojo.User"> <constructor-arg type="java.lang.String" value="qinjiang"/> </bean>
3. Directly pass the parameter name (Master)
<!--The third method: set directly through the parameter name --> <bean id="user" class="com.kuang.pojo.User"> <constructor-arg name="name" value="kuangshen"/> </bean>
The name method also needs no parameter construction and set method, and the index and type only need parameter construction
Even if there are two new objects, there is only one instance (singleton mode: globally unique)
After registering the bean, the object is initialized (similar to the new class name ())
public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); User user = (User) context.getBean("user"); User user2 = (User) context.getBean("user"); System.out.println(user==user2);//true }
Summary: when the configuration file is loaded, the objects managed in the container have been initialized!
5. Spring configuration
5.1 alias
<bean id="user" class="pojo.User"> <constructor-arg name="name" value="chen"></constructor-arg> </bean> <alias name="user" alias="user2"/> <!-- When used User user2 = (User) context.getBean("user2"); -->
5.2 Bean configuration
<!--id: bean The unique identifier of, which is equivalent to the object name we learned class: bean The qualified name corresponding to the object: package name+type name: It's also an alias,and name Multiple aliases can be taken at the same time, Separate aliases with spaces and commas--> <bean id="user" class="pojo.User" name="u1 u2,u3;u4"> <property name="name" value="chen"/> </bean> <!-- When used User user2 = (User) context.getBean("u1"); -->
5.3,import
import is generally used for team development. It can merge multiple configuration files into one
Suppose that there are multiple developers in the project. These three developers copy different classes for development. Different classes need to be registered in different bean s. We can make use of them
Use import to merge everyone's beans.xml into a total!
- Zhang San (beans.xm1)
- Li Si (beans2.xm1)
- Wang Wu (beans3.xm1)
- applicationContext.xml
<import resource="beans.xm1"/> <import resource="beans2.xml"/> <import resource="beans3.xm1"/>
When using, just use the general configuration directly
Barrage comments:
Create according to the import order in the total xml. The later imported object will overwrite the first imported object, and the final instantiated object will be the one in the later imported xml
6. Dependency injection (DI)
6.1. Constructor injection
As described earlier, refer to 4. How IOC creates objects
6.2 set mode injection [ key ]
Dependency injection: set injection!
- Dependency: the creation of bean objects depends on the container
- Injection: all attributes in the bean object are injected by the container
[environment construction]
-
Complex type
Address class
package com.kuang.pojo; public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Address{" + "address='" + address + '\'' + '}'; } }
-
Real test object
Student class
package com.kuang.pojo; import java.util.*; //Here, copy omits the get/set method and toString method public class Student { private String name; private Address address; private String[] books; private List<String> hobbies; private Map<String,String> card; private Set<String> games; private String wife; private Properties info; }
-
beans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="student" class="com.kuang.pojo.Student"> <!--The first: normal value injection, value --> <property name="name" value="kuangshen"/> </bean> </beans>
-
test
MyTest
public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Student student = (Student) context.getBean("student"); System.out.println(student.getName()); } }
-
Perfect injection information
<?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="address" class="com.kuang.pojo.Address"> <property name="address" value="Xi'an"/> </bean> <bean id="student" class="com.kuang.pojo.Student"> <!--The first: normal value injection, value--> <property name="name" value="Qin Jiang"/> <!--The second is reference injection, ref--> <property name="address" ref="address"/> <!--array--> <property name="books"> <array> <value>The Dream of Red Mansion</value> <value>Journey to the West</value> <value>Water Margin</value> <value>Romance of the Three Kingdoms</value> </array> </property> <!--List--> <property name="hobbies"> <list> <value>having dinner</value> <value>sleep</value> <value>Beat beans</value> </list> </property> <!--Map--> <property name="card"> <map> <entry key="Mobile card" value="12345678910"/> <entry key="Student card" value="1809064005"/> </map> </property> <!--Set--> <property name="games"> <set> <value>LOL</value> <value>COC</value> <value>BOB</value> </set> </property> <!--null--> <property name="wife"> <null/> </property> <!--Properties--> <property name="info"> <props> <prop key="driver">com.mysql.jdbc.Driver</prop> <prop key="url">jdbc:mysql://localhost:3306/</prop> <prop key="username">root</prop> <prop key="password">123456</prop> </props> </property> </bean> </beans>
-
MyTest
public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Student student = (Student) context.getBean("student"); System.out.println(student); /* * Student{ * name='Qin Jiang ', * address=Address{address='Xi'an '}, * books=[Dream of Red Mansions, journey to the west, outlaws of the marsh, romance of the Three Kingdoms], * hobbies=[Eat, sleep, beat beans], * card={Mobile card = 12345678910, * Student card = 1809064005}, * games=[LOL, COC, BOB], * wife='null', * info={password=123456, * url=jdbc:mysql://localhost:3306/, * driver=com.mysql.jdbc.Driver, * username=root} * } * */ } }
6.3 expansion and injection
We can use the p namespace and the c namespace for injection
Official interpretation:
Official document location
pojo add User class
package com.kuang.pojo; public class User { private String name; private int age; public User() { } public User(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
Note: add the following two lines to beans
Using the p and c namespaces requires importing xml constraints
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--p Namespace injection, you can directly inject the value of the attribute: property--> <bean id="user" class="com.kuang.pojo.User" p:name="Qin Jiang" p:age="20"/> <!--c Namespace injection through constructor(You need to write a parameterized and nonparametric constructor): constructor-args--> <bean id="user2" class="com.kuang.pojo.User" c:name="Mad God" c:age="22" /> </beans>
Test:
@Test public void test01(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); User user = context.getBean("user",User.class); System.out.println(user); User user2 = context.getBean("user2",User.class); System.out.println(user2); }
Note: the p naming and c namespace cannot be used directly. You need to import xml constraints!
xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
6.4 Bean scope
- Singleton mode (Spring default mechanism)
<bean id="user" class="com.kuang.pojo.User" p:name="Qin Jiang" p:age="20" scope="singleton"/>
@Test public void test01(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); User user = context.getBean("user",User.class); System.out.println(user.hashCode());//797925218 User user2 = context.getBean("user",User.class); System.out.println(user2.hashCode());//797925218 System.out.println(user==user2);//true }
- Prototype pattern: every time you get from the container, a new object will be generated!
<bean id="user2" class="com.kuang.pojo.User" c:name="Mad God" c:age="22" scope="prototype" />
@Test public void test01(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); User user = context.getBean("user2",User.class); System.out.println(user.hashCode());//1615039080 User user2 = context.getBean("user2",User.class); System.out.println(user2.hashCode());//336484883 System.out.println(user==user2);//false }
- The rest of the request s, session s, and applications can only be used in open web applications!
7. Automatic assembly of Bean
- 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
There are three ways to assemble in Spring
-
Display configuration in xml
-
Display configuration in java
-
Implicit automatic assembly bean [important]
-
byName auto assembly: byName will automatically find the id corresponding to the value corresponding to its own object set
Ensure that all IDs are unique and consistent with the values injected by set
7.1 testing
Environment construction: create a project, one person has two pets!
- Dog
package com.kuang.pojo; public class Dog { public void shout(){ System.out.println("wang~"); } }
- Cat
package com.kuang.pojo; public class Cat { public void shout(){ System.out.println("miao~"); } }
3.Person
package com.kuang.pojo; public class Person { private Cat cat; private Dog dog; private String 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; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "cat=" + cat + ", dog=" + dog + ", name='" + name + '\'' + '}'; } }
- beans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans 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="person" class="com.kuang.pojo.Person"> <property name="name" value="kuangshen"/> <property name="cat" ref="cat"/> <property name="dog" ref="dog"/> </bean> </beans>
- MyTest
@Test public void Test01(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Person person = context.getBean("person", Person.class); person.getCat().shout(); person.getDog().shout(); }
7.2 ByName auto assembly
byName: the bean id corresponding to the value after the set method of your own object will be automatically found in the container context!
Ensure that all IDs are unique and consistent with the values injected by set
<!--byName: It will automatically find its own objects in the container context set Method bean id! Guarantee all id Unique, and set The injected values are consistent for example:setDog(),take set The following characters are used as id,Then id = dog Before automatic assembly --> <bean id="person" class="com.kuang.pojo.Person" autowire="byName"> <property name="name" value="kuangshen"/> </bean>
7.3 ByType automatic assembly
<!--byType: byType: It will automatically find the object with the same property type as its own object in the container context bean! Guarantee all class only(Class is globally unique),Even if not id Can also succeed For example, Dog dog; Then it will find pojo of Dog Class, and then conduct automatic assembly --> <bean id="person" class="com.kuang.pojo.Person" autowire="byType"> <property name="name" value="kuangshen"/> </bean>
Summary:
- When ByName, it is necessary to ensure that the IDs of all beans are unique, and the bean must be consistent with the value of the set method of the automatically injected attribute!
- For 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!
7.4 automatic assembly using annotations
jdk1.5 supports annotations, and spring 2.5 supports annotations!
The introduction of annotation-based configuration raised the question of whether this approach is "better" than XML.
To use notes:
-
Import constraint.context
-
Configuration annotation support [important!]
<?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"> <!--Enable annotation support--> <context:annotation-config/> </beans>
@Autowired
You can use it directly on the attribute! You can also use it on the set method!
Using Autowired, we don't need to write the set method, provided that your automatically configured attribute exists in the IOC (Spring) container and conforms to the name ByName!
polular science:
@Nullable The field is marked with this annotation, indicating that this field can be null;
public @interface Autowired { boolean required() default true; }
If the require attribute of defined Autowire is false, it means that the object can be null, otherwise it is not allowed to be empty (false means that the assembly cannot be found and no exception is thrown)
Test code:
public class Person { //If the required property of Autowired is explicitly defined as false, it means that the object can be null, otherwise it is not allowed to be empty @Autowired(required = false) private Cat cat; @Autowired private Dog dog; private String name; }
@Autowired+@Qualifier
If the environment of @ Autowired automatic assembly is complex and the automatic assembly cannot be completed through an annotation [@ Autowired], we can use @ Qualifier(value = "xxx") to cooperate with @ Autowired and specify a unique bean object injection!
public class Person { @Autowired @Qualifier(value = "cat111") private Cat cat; @Autowired @Qualifier(value = "dog222") private Dog dog; private String name; }
Barrage comment: if the same object in the xml file is used by multiple bean s, Autowired cannot find it by type, you can use @ Qualifier to specify the id
@Resource
public class Person { @Resource private Cat cat; @Resource private Dog dog; }
Summary:
@Difference between Resource and @ Autowired:
-
They are used for automatic assembly and can be placed in the attribute field
-
@Autowired is implemented by byType. When multiple objects of the same type are matched, ByName is used for assembly, and the object must exist! [common]
-
@Resource is implemented by byName by default. If the name cannot be found, it is implemented by byType! If both cannot be found, an error will be reported! [common]
-
Different execution order: @ Autowired is implemented by byType@ Resource is implemented by byName by default.
8. Using annotation development
You need to import constraints to use annotations, and configure 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"> <!--Enable annotation support--> <context:annotation-config/> </beans>
-
bean
<!--Specify the package to be scanned, and the annotations under the package will take effect--> <context:component-scan base-package="com.kuang"/> <!--Enable annotation support--> <context:annotation-config/>
< context: component scan / > in addition to the function of context: annotation config, < context: component scan / > can also scan and register Java beans under the specified package. It also has the function of automatically registering objects annotated with @ component,@service,@Repository, etc. into the spring container. Therefore, after using < context: component scan / >, you can remove < context: annotation config / >.
-
How do properties inject @ Value
//Equivalent to < bean id = "user" class = "com. Kuang. POJO. User" / > //@Component component @Component public class User { //Equivalent to < property name = "name" value = "kuangshen" / > @Value("kuangshen") public String name; //It can also be placed on the set method //@value("kuangshen") public void setName(String name) { this.name = name; } }
-
Derived annotation
@Component has several derived annotations, which will be layered according to the mvc architecture in web development.
- dao (@Repository)
- service(@Service)
- controller(@Controller)
The four annotation functions are the same. They all represent registering a class in the Spring container and assembling beans
-
automatic assembly
@Autowired: byType is used by default. If it does not match, byName will be used. If Autowired cannot uniquely and automatically assemble attributes, it needs to be configured through @ Qualifier(value = "xxx").
@Nullable: the field is marked with this annotation, indicating that the field can be empty
@Resource: byName is used by default. If it does not match, byType will be used
-
Scope @ scope
//Equivalent to < bean id = "user" class = "com. Kuang. POJO. User" / > //@Component component @Component //scope("prototype") is equivalent to < bean scope = "prototype" > < / bean > @Scope("prototype") public class User { //Equivalent to < property name = "name" value = "kuangshen" / > @Value("kuangshen") public String name; }
-
Summary
xml and annotations:
- xml is more versatile, easy to maintain and suitable for any situation
- Annotations are not their own classes and cannot be used. Maintenance is relatively complex
Best practices:
- xml is used to manage bean s
- Annotations are only used to complete attribute injection
- In the process of using, we only need to pay attention to one problem: to make the annotation effective, we need to turn on the annotation support
<!--Specify the package to be scanned, and the annotations under the package will take effect--> <context:component-scan base-package="com.kuang"/> <!--Enable annotation support--> <context:annotation-config/>
9. Configure Spring in Java
We will not use the xml configuration of Spring at all now, and leave it to Java!
JavaConfig is a sub project of Spring. After Spring 4, it has become a core function!
Entity class User
//The annotation here means that this class is taken over by Spring and registered in the container @Component public class User { private String name; public String getName() { return name; } @Value("QINIIANG")//Attribute injection value public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "name='" + name + '\'' + '}'; } }
Configuration file AppConfig
// This will also be managed by the Spring container and registered in the container, because it is originally a @ Component // @Configuration table this is a configuration class, just like beans.xml we saw earlier, similar to the < beans > tag @Configuration @ComponentScan("com.kuang.pojo") //Turn on scan @Import(KuangConfig.class)//Import merges all @ configurations into one total! public class AppConfig { //Registering a bean is equivalent to a bean tag we wrote earlier //The name of this method is equivalent to the id attribute - > getuser in the bean tag //The return value of this method is equivalent to the class attribute - > user in the bean tag @Bean public User getUser(){ return new User();//Is to return the object to be injected into the bean! } }
@Configuration public class KuangConfig { }
Test class MyTest
public class MyTest { @Test public void Test01(){ //If the configuration class method is completely used, we can only obtain the container through the annotation config context and load it through the class object of the configuration class! ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);//class object User user = (User) context.getBean("getUser");//Method name getUser System.out.println(user.getName()); } }
This pure Java configuration method can be seen everywhere in SpringBoot!
10. Agent mode
Why learn agent mode? Because this is the bottom layer of spring AOP! [spring AOP and spring MVC]
Classification of agent mode:
- Static proxy
- Dynamic agent
10.1 static agent
Role analysis:
- Abstract role: it is usually solved by using interfaces or abstract classes
- Real role: the role represented
- Agent role: represent the real role. After representing the real role, we usually do some ancillary operations
- Customer: the person who accesses the proxy object!
Code steps:
- Interface
//Rent a house public interface Rent { public void rent(); }
- Real role
//landlord or landlady public class Host implements Rent{ public void rent() { System.out.println("The landlord rents the house!"); } }
- delegable role
public class Proxy implements Rent{ private Host host; public Proxy() { } public Proxy(Host host) { this.host = host; } public void rent() { host.rent(); seeHouse(); sign(); fee(); } //House viewing public void seeHouse(){ System.out.println("Look at the house with the intermediary!"); } //sign a contract public void sign(){ System.out.println("Sign a lease contract with an intermediary!"); } //Charge public void fee(){ System.out.println("Intermediary charges!"); } }
- Client access agent role
public class Client { public static void main(String[] args) { //The landlord wants to rent the house Host host = new Host(); //host.rent(); //Agent, the intermediary helps the landlord rent the house, and the agent role generally has some ancillary operations! Proxy proxy = new Proxy(host); //Do not face the landlord, directly find an intermediary to rent a house! proxy.rent(); } }
Benefits of agent mode:
- It can make the operation of real characters more pure! Don't pay attention to some public business
- The public business is handed over to the agent role! Realize the division of business!
- When the public business is expanded, it is convenient for centralized management!
Disadvantages:
- A real role will produce a proxy role, the amount of code will double, and the development efficiency will be low~
10.2 deepen understanding
Code steps:
-
Interface
public interface UserService { public void add(); public void delete(); public void update(); public void query(); }
-
Real role
//Real role public class UserServiceImpl implements UserService{ public void add() { System.out.println("Added a user!"); } public void delete() { System.out.println("Deleted a user!"); } public void update() { System.out.println("Modified a user!"); } public void query() { System.out.println("Queried a user!"); } }
-
delegable role
public class UserServiceProxy implements UserService{ private UserServiceImpl userService; public void setUserService(UserServiceImpl userService) { this.userService = userService; } public void add() { log("add"); userService.add(); } public void delete() { log("delete"); userService.delete(); } public void update() { log("update"); userService.update(); } public void query() { log("query"); userService.query(); } public void log(String msg){ System.out.println("[Debug] One was used"+msg+"method"); } }
-
Client access agent role
public class Client { public static void main(String[] args) { UserServiceImpl userService = new UserServiceImpl(); UserServiceProxy proxy = new UserServiceProxy(); proxy.setUserService(userService); proxy.delete(); } }
Talk about AOP
10.3 dynamic agent
- Dynamic agents have the same role as static agents
- The agent class of dynamic agent is dynamically generated, which is not written directly by us!
- Dynamic agents are divided into two categories: interface based dynamic agents and class based dynamic agents
- Interface based - JDK dynamic proxy [we use it here]
- Class based: cglib
- java bytecode implementation: javassist
You need to understand two classes: Proxy: Proxy; InvocationHandler: invokes the handler.
Code steps:
- Interface
public interface Rent { public void rent(); }
- Real role
public class Host implements Rent{ public void rent() { System.out.println("The landlord wants to rent the house!"); } }
- ProxyInvocationHandler class
//We will use this class to automatically generate proxy classes! public class ProxyInvocationHandler implements InvocationHandler { //Proxy interface private Rent rent; public void setRent(Rent rent) { this.rent = rent; } //Automatically generate proxy classes // Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), // new Class<?>[] { Foo.class }, // handler); public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this); } //Process the proxy instance and return the result public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //The essence of dynamic agent is to use reflection mechanism! Object result = method.invoke(rent, args); seeHose(); fee(); return result; } public void seeHose(){ System.out.println("Look at the house with the intermediary!"); } public void fee(){ System.out.println("Intermediary charges!"); } }
- Customer call test
public class Client { public static void main(String[] args) { //Real role Host host = new Host(); //Agent role, not now ProxyInvocationHandler pih = new ProxyInvocationHandler(); //Handle the interface object we want to call by calling the program processing role! pih.setRent(host);//Pass in an interface that requires a proxy Rent proxy = (Rent) pih.getProxy();//The proxy here is generated dynamically. We didn't write it proxy.rent();//Calling methods using proxy objects } }
Here, we can extract ProxyInvocationHandler as a tool class
//We will use this class to automatically generate proxy classes! public class ProxyInvocationHandler implements InvocationHandler { //Proxy interface private Object target; public void setTarget(Object target) { this.target = target; } //Automatically generate proxy classes // Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), // new Class<?>[] { Foo.class }, // handler); public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this); } //Process the proxy instance and return the result public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { log(method.getName()); //The essence of dynamic agent is to use reflection mechanism! Object result = method.invoke(target, args); return result; } public void log(String msg){ System.out.println("[Debug] One was used"+msg+"method"); } }
Demo02 user test
public class Client2 { public static void main(String[] args) { //Real object UserServiceImpl userService = new UserServiceImpl(); //new is a dynamic proxy class that automatically generates the corresponding proxy object ProxyInvocationHandler pih = new ProxyInvocationHandler(); //Pass in an interface that requires a proxy pih.setTarget(userService); UserService proxy = (UserService) pih.getProxy();//Call method to automatically generate proxy object //Use the proxy object to complete the business proxy.add(); } }
Benefits of dynamic agents:
- It can make the operation of real characters more pure! Don't pay attention to some public business
- The public role will be handed over to the agent role! 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!
11,AOP
11.1 what is AOP
Barrage explanation and understanding: in fact, aop is to separate the core code from the non core code, cut into the non core code in the core code, and complete the recording of things and logs in the main project.
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.
11.2 role of AOP in Spring
Provide declarative transactions; Allows you to customize the cut plane
-
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: the notified object.
-
Proxy: an object created after notification is applied to the target object.
-
PointCut: the definition of the "place" where the aspect notification is executed.
-
Join point: the execution point that matches the pointcut.
In spring AOP, crosscutting logic is defined through Advice. Spring supports five types of Advice:
That is, AOP adds new functions without changing the original code. (agent)
11.3 using Spring to implement AOP
[key] to use AOP weaving, you 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>
Method 1: use Spring API interface [mainly Spring API interface implementation]
- Under service package, define UserService business interface and UserServiceImpl implementation class
public interface UserService { public void add(); public void delete(); public void update(); public void select(); }
public class UserServiceImpl implements UserService { public void add() { System.out.println("Added a user!"); } public void delete() { System.out.println("Deleted a user!"); } public void update() { System.out.println("Updated a user!"); } public void select() { System.out.println("Queried a user!"); } }
- Under the log package, define our enhancement classes, a log pre enhancement class and an AfterLog post enhancement class
public class Log implements MethodBeforeAdvice { //Method: the method of the target object to execute //args: parameter //Target: target object public void before(Method method, Object[] agrs, Object target) throws Throwable { System.out.println(target.getClass().getName()+"of"+method.getName()+"Executed"); } }
public class AfterLog implements AfterReturningAdvice { //returnValue: return value public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("Yes"+method.getName()+"Method, the return result is:"+returnValue); } }
- Finally, register in the spring file, implement the aop cut in implementation, pay attention to the import constraints, and configure the applicationContext.xml file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--register bean--> <bean id="userService" class="com.kuang.service.UserServiceImpl"/> <bean id="log" class="com.kuang.log.Log"/> <bean id="afterLog" class="com.kuang.log.AfterLog"/> <!--Method 1: use native Spring API Interface--> <!--to configure aop:Import required aop Constraints of--> <aop:config> <!--Entry point: expression: expression, execution(Location to execute!* * * * *)--> <aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/> <!--Execute surround increase!--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config> </beans>
Pointcut expression:
The whole expression can be divided into five parts:
1. execution(): expression body.
2. The first * sign: the method return type. The * sign indicates all types.
3. Package name: indicates the package name to be intercepted.
4. The second * sign indicates the class name, and the * sign indicates all classes.
5. * (...): the last asterisk represents the method name, * represents all methods, followed by () represents the method parameters, and two periods represent any parameters
- test
public class MyTest { @Test public void Test01(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //Dynamic proxy interface: Note UserService userService = (UserService) context.getBean("userService"); userService.add(); //userService.select(); } }
Method 2: user defined classes to implement AOP [mainly section definition]
- Define your own DiyPointCut cut in class under the diy package
public class DiyPointCut { public void before(){ System.out.println("======Before method execution======"); } public void after(){ System.out.println("======After method execution======"); } }
- Go to the configuration file in spring
<!--Method 2: user defined class--> <bean id="diy" class="com.kuang.diy.DiyPointCut"/> <aop:config> <!--Custom cut, ref Class to reference--> <aop:aspect ref="diy"> <!--breakthrough point--> <aop:pointcut id="point" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/> <!--notice--> <aop:before method="before" pointcut-ref="point"/> <aop:after method="after" pointcut-ref="point"/> </aop:aspect> </aop:config>
- test
Method 3: use annotation to realize!
- The AnnotationPointCut enhancement class for annotation implementation is defined under the diy package
//Declarative transaction! @Aspect //Label this class as a facet public class AnnotationPointCut { @Before("execution(* com.kuang.service.UserServiceImpl.*(..))") public void before(){ System.out.println("====Before method execution===="); } @After("execution(* com.kuang.service.UserServiceImpl.*(..))") public void after(){ System.out.println("====After method execution===="); } //In surround enhancement, we can give a parameter to represent the point where we want to get the processing entry point; @Around("execution(* com.kuang.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint jp) throws Throwable{ System.out.println("Surround front"); Signature signature = jp.getSignature();// Get signature System.out.println("signature:"+signature); Object proceed = jp.proceed(); //Execution method System.out.println("After surround"); System.out.println(proceed); } }
- In the Spring configuration file, register bean s and add configurations that support annotations.
<!--Method 3: use annotation--> <bean id="annotationPointCut" class="com.kuang.diy.AnnotationPointCut"/> <!--Enable annotation support! JDK(The default is proxy-target-class="false") cglib(proxy-target-class="true")--> <aop:aspectj-autoproxy/>
- test result
Surround front signature:void com.kuang.service.UserService.add() ====Before method execution==== Added a user! ====After method execution==== After surround null
12. Integrate Mybatis (November 21, 2020)
Mybatis spring official website: https://mybatis.org/spring/zh/
Steps:
- Import related jar packages
- junit
- mybatis
- mysql database
- spring related
- aop Weaver
- Mybatis spring integration package [key] lombok package is also imported here.
- Configure Maven static resource filtering problem!
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.0.RELEASE</version> </dependency> <!--Spring If you operate the database, you also need one spring-jdbc --> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.13</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --> <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.18.10</version> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build>
-
Write configuration file
-
test
12.1 recall mybatis
- Writing pojo entity classes
@Data public class User { private int id; private String name; private String pwd; }
- Write the configuration file mybatis-config.xml to implement mybatis
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typeAliases> <package name="com.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=false&useUnicode=true&characterEncoding=utf8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <package name="com.kuang.dao"/> </mappers> </configuration>
- Write UserMapper interface
public interface UserMapper { public List<User> selectUser(); }
- Write the UserMapper.xml file
<?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.kuang.mapper.UserMapper"> <!--sql--> <select id="selectUser" resultType="user"> select * from mybatis.user </select> </mapper>
- test
@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(); }
12.2 Mybatis-Spring
What is mybatis spring?
MyBatis Spring will help you seamlessly integrate MyBatis code into Spring.
Document link: http://mybatis.org/spring/zh/index.html
If Maven is used as a build tool, you only need to add the following code to pom.xml:
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.2</version> </dependency>
Integration to achieve one:
- Introduce the Spring configuration file spring-dao.xml
<?xml version="1.0" encoding="GBK"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd </beans>
- Configure the data source to replace the data source of mybaits
<!--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=false&useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean>
- Configure SqlSessionFactory and associate MyBatis
<!--sqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!--relation mybatis configuration file--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath:com/kuang/mapper/*.xml"/> </bean>
- Register sqlSessionTemplate and associate sqlSessionFactory
<!--SqlSessionTemplate:That's what we use sqlSession--> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <!--Only constructor injection can be used sqlSessionFactory,Because it doesn't set method--> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>
- The UserMapperImpl implementation class of the UserMapper interface is required, and the sqlSessionTemplate is privatized
public class UserMapperImpl implements UserMapper{ //All our operations are executed using sqlSession. In the past, SqlsessionTemplate is used now private SqlSessionTemplate sqlSession; public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; } public List<User> selectUser() { UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.selectUser(); } }
- Inject the implementation class written by yourself into the Spring configuration file.
<bean id="userMapper" class="com.kuang.mapper.UserMapperImpl"> <property name="sqlSession" ref="sqlSession"/> </bean>
- Test and use!
@Test public void test () throws IOException { ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml"); UserMapper userMapper = context.getBean("userMapper", UserMapper.class); for (User user : userMapper.selectUser()) { System.out.println(user); } }
The result is output successfully! Now the status of our Mybatis configuration file! Discovery can be integrated by Spring!
Integration realization II:
This is only available for mybatis spring version 1.2.3 and above. Screenshot of the official document:
dao inherits the Support class, obtains it directly by using getSqlSession(), and then injects it directly into SqlSessionFactory. Compared with integration mode 1, it does not need to manage SqlSessionTemplate, and the Support for transactions is more friendly. You can view the tracking source code.
Test:
- Change the UserMapperImpl we wrote above to UserMapperImpl2
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{ public List<User> selectUser() { return getSqlSession().getMapper(UserMapper.class).selectUser(); } }
- Inject into the Spring configuration file
<bean id="userMapper2" class="com.kuang.mapper.UserMapperImpl2"> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean>
- test
@Test public void test () throws IOException { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserMapper userMapper = context.getBean("userMapper2", UserMapper.class); for (User user : userMapper.selectUser()) { System.out.println(user); } }
After integration, the configuration files are:
mybatis-config.xml:
<?xml version="1.0" encoding="GBK" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <!--configuration core file--> <configuration> <typeAliases> <package name="com.kuang.pojo"/> </typeAliases> </configuration>
spring-dao.xml: focus on Dao layer
<?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"> <!--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=false&useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean> <!--sqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!--relation mybatis configuration file--> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath:com/kuang/mapper/*.xml"/> </bean> <!-- Integration implementation method 2: SqlSessionTemplate You can stop writing--> <!--SqlSessionTemplate:That's what we use sqlSession--> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <!--Only constructor injection can be used sqlSessionFactory,Because it doesn't set method--> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> </beans>
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <import resource="spring-dao.xml"/> <bean id="userMapper" class="com.kuang.mapper.UserMapperImpl"> <property name="sqlSession" ref="sqlSession"/> </bean> <bean id="userMapper2" class="com.kuang.mapper.UserMapperImpl2"> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean> </beans>
13. Declarative transaction
13.1 review
- Treat a group of business as a business; Either all succeed or all fail!
- Transaction is very important in project development. It involves the consistency of data. You can't be careless!
- Ensure integrity and consistency.
Transaction ACID principle:
-
atomicity
- A transaction is an atomic operation, which consists of a series of actions. The atomicity of a transaction ensures that the actions are either completed or do not work at all.
-
consistency
- Once all transaction actions are completed, the transaction is committed. Data and resources are in a consistent state that meets business rules.
-
isolation
- Multiple transactions may process the same data at the same time, so each transaction should be isolated from other transactions to prevent data corruption.
-
Persistence
- Once the transaction is completed, no matter what error occurs in the system, the result will not be affected. Typically, the results of a transaction are written to persistent storage.
Test:
Copy the code from Chapter 12 above to a new project
In the previous case, we added two methods to the userMapper interface, delete and add users;
//Add a user int addUser(User user); //Delete user by id int deleteUser(int id);
UserMapper.xml file, we deliberately write deletes wrong, 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} <!-- deletes It was a deliberate mistake --> </delete>
Write the UserMapperImpl implementation class of the interface. In the implementation class, we operate a wave
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{ public List<User> selectUser() { UserMapper mapper = getSqlSession().getMapper(UserMapper.class); //Add and delete objects in the test to check whether the transaction is consistent and successful, but consistent and failed mapper.addUser(new User(5,"Test object","888888")); mapper.deleteUser(5); return mapper.selectUser(); } //newly added public int addUser(User user) { return getSqlSession().getMapper(UserMapper.class).addUser(user); } //delete public int deleteUser(int id) { return getSqlSession().getMapper(UserMapper.class).deleteUser(id); } }
test
@Test public void Test01(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserMapper userMapper = context.getBean("userMapper", UserMapper.class); List<User> userList = userMapper.selectUser(); for (User user : userList) { System.out.println(user); } }
Error reporting: sql exception. The deleteSQL statement is written incorrectly
Result: the database result shows that the insertion is successful!
No transaction management; We want them to succeed only when they succeed. If there is a failure, they will all fail. We should need affairs!
In the past, we all needed to manage affairs manually, which was very troublesome!
However, Spring provides us with transaction management, and we only need to configure it;
13.2 transaction management in spring
Spring defines an abstraction layer on top of different transaction management APIs, so that developers can use spring's transaction management mechanism without understanding the underlying transaction management API. Spring supports programmatic transaction management and declarative transaction management.
Programming transaction management
- Embed transaction management code into business methods to control transaction commit and rollback
- Disadvantages: additional transaction management code must be included in each transaction operation business logic
Declarative transaction management
- 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.
1. Use Spring to manage transactions, and pay attention to the constraint import of 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">
2. JDBC transaction
<!--Declarative transaction--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="dataSource" /> </bean>
3. After configuring the transaction manager, we need to configure the transaction notification
<!--combination aop Implement transaction weaving--> <!--Configure notification classes for transactions--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!--For which methods are transactions configured--> <!--What's new: the propagation feature of configuration transactions new propagation--> <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"/>--> <!-- *No. includes the above four methods:--> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
spring transaction propagation characteristics: (just understand)
Transaction propagation behavior is how transactions propagate among multiple transaction methods when they call each other. spring supports seven transaction propagation behaviors:
-
propagation_ Requisited: if there is no transaction at present, create a new transaction. If there is already a transaction, join it. This is the most common choice.
-
propagation_supports: supports the current transaction. If there is no current transaction, it will be executed in a non transaction method.
-
propagation_mandatory: use the current transaction. If there is no current transaction, an exception will be thrown.
-
propagation_required_new: create a new transaction. If there is a current transaction, suspend the current transaction.
-
propagation_not_supported: perform operations in a non transactional manner. If there is a transaction, suspend the current transaction.
-
propagation_never: execute the operation in a non transactional manner. If the current transaction exists, an exception will be thrown.
-
propagation_nested: if a transaction currently exists, it is executed within a nested transaction. If there is no transaction at present, the and propagation are executed_ Required similar operations.
The default transaction propagation behavior of Spring is PROPAGATION_REQUIRED, which is suitable for most situations.
For example, the methods we just mentioned are called, so they will be placed in a group of transactions!
4. Configure AOP and import the header file of AOP
xmlns:aop="http://www.springframework.org/schema/aop" http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"
<!--Configure transaction entry--> <aop:config> <!--mapper All classes, methods and arbitrary parameters under the package--> <aop:pointcut id="txPointCut" expression="execution(* mapper.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config>
5. Delete the data just inserted and test again!
@Test public void Test01(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserMapper userMapper = context.getBean("userMapper", UserMapper.class); List<User> userList = userMapper.selectUser(); for (User user : userList) { System.out.println(user); } }
reflection:
Why transactions are needed?
- If transactions are not configured, there may be inconsistent data submission;
- If we do not configure declarative transactions in Spring, we need to manually configure transactions in the code!
-tx.xsd">
**2. JDBC affair** ```xml <!--Declarative transaction--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="dataSource" /> </bean>
3. After configuring the transaction manager, we need to configure the transaction notification
<!--combination aop Implement transaction weaving--> <!--Configure notification classes for transactions--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!--For which methods are transactions configured--> <!--What's new: the propagation feature of configuration transactions new propagation--> <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"/>--> <!-- *No. includes the above four methods:--> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
spring transaction propagation characteristics: (just understand)
Transaction propagation behavior is how transactions propagate among multiple transaction methods when they call each other. spring supports seven transaction propagation behaviors:
-
propagation_ Requisited: if there is no transaction at present, create a new transaction. If there is already a transaction, join it. This is the most common choice.
-
propagation_supports: supports the current transaction. If there is no current transaction, it will be executed in a non transaction method.
-
propagation_mandatory: use the current transaction. If there is no current transaction, an exception will be thrown.
-
propagation_required_new: create a new transaction. If there is a current transaction, suspend the current transaction.
-
propagation_not_supported: perform operations in a non transactional manner. If there is a transaction, suspend the current transaction.
-
propagation_never: execute the operation in a non transactional manner. If the current transaction exists, an exception will be thrown.
-
propagation_nested: if a transaction currently exists, it is executed within a nested transaction. If there is no transaction at present, the and propagation are executed_ Required similar operations.
The default transaction propagation behavior of Spring is PROPAGATION_REQUIRED, which is suitable for most situations.
For example, the methods we just mentioned are called, so they will be placed in a group of transactions!
4. Configure AOP and import the header file of AOP
xmlns:aop="http://www.springframework.org/schema/aop" http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"
<!--Configure transaction entry--> <aop:config> <!--mapper All classes, methods and arbitrary parameters under the package--> <aop:pointcut id="txPointCut" expression="execution(* mapper.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/> </aop:config>
5. Delete the data just inserted and test again!
@Test public void Test01(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserMapper userMapper = context.getBean("userMapper", UserMapper.class); List<User> userList = userMapper.selectUser(); for (User user : userList) { System.out.println(user); } }
reflection:
Why transactions are needed?
- If transactions are not configured, there may be inconsistent data submission;
- If we do not configure declarative transactions in Spring, we need to manually configure transactions in the code!
- Transaction is very important in the development of the project. It involves the consistency and integrity of data, which should not be careless!