1,Spring
1.1 INTRODUCTION
-
Spring: Spring - > brings spring to the software industry
-
In 2002, the prototype of Spring framework, interface21 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 the existing technology easier to use is a hodgepodge, integrating the existing technology framework.
-
SSH: Struts + Spring + Hibernate
-
SSM: SpringMVC + Spring + Mybatis
Official website: https://spring.io/projects/spring-framework#overview
Official download address: http://repo.spring.io/release/org/springframework/spring
GitHub: https://github.com/spring-projects/spring-framework
Import maven package:
<!-- Import mvc The required packages will be imported successively --> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.18</version> </dependency> <!-- integration JDBC --> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.18</version> </dependency>
1.2 advantages
- Spring is an open source free framework (container)
- spring is a lightweight, non intrusive framework (non intrusive - after importing, it will not affect your original project, unavailability, etc.)
- Inversion of control (IOC), aspect oriented programming (AOP)
- Support transaction processing and framework integration
To sum up: Spring is a lightweight inversion of control (IOC) and aspect oriented programming (AOP) framework
1.3 composition
1.4 expansion
Introduction to spring official website: Modern Java development. (Spring Based Development)
- Spring Boot
- A rapidly developed scaffold
- Based on SpringBoot, you can quickly develop a single microservice
- Contract greater than configuration
- Spring Cloud
- Spring cloud is implemented based on SpringBoot
The premise of learning SpringBoot is to master Spring and Spring MVC. form a connecting link between the preceding and the following
Disadvantages of Spring: after developing for too long, it goes against the original idea of making existing technology easier to use. Configuration is very cumbersome. Known as "configuration hell"
2. IOC theoretical derivation
give an example:
One development idea:
First, a dao layer interface will be defined:
package com.wong.dao; public interface UserDao { void getUser(); }
Define an implementation class of dao layer:
package com.wong.dao; public class UserDaoImpl implements UserDao { @Override public void getUser() { System.out.println("Get user data by default"); } }
Then a service layer interface will be defined:
package com.wong.service; public interface UserService { void getUser(); }
Define an implementation class of the service layer:
package com.wong.service; import com.wong.dao.UserDao; import com.wong.dao.UserDaoImpl; public class UserServiceImpl implements UserService { //Testing will be done here, so this method needs to be injected private UserDao userDao = new UserDaoImpl(); @Override public void getUser() { userDao.getUser(); } }
Test:
import com.wong.service.UserService; import com.wong.service.UserServiceImpl; public class MyTest { public static void main(String[] args) { //Users actually call the business layer, and users in dao layer do not need to contact UserService userService = new UserServiceImpl(); userService.getUser(); } }
If you need to add a new implementation class in dao layer:
package com.wong.dao; public class UserDaoMysqlImpl implements UserDao { @Override public void getUser() { System.out.println("Mysql Get user data"); } }
When the service calls this method, the injected object needs to be modified again:
package com.wong.service; import com.wong.dao.UserDao; import com.wong.dao.UserDaoImpl; import com.wong.dao.UserDaoMysqlImpl; public class UserServiceImpl implements UserService { //You need to modify the injection again //private UserDao userDao = new UserDaoImpl(); private UserDao userDao = new UserDaoMysqlImpl(); @Override public void getUser() { userDao.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 it once is very expensive.
Here, a set interface is used:
package com.wong.service; import com.wong.dao.UserDao; import com.wong.dao.UserDaoImpl; import com.wong.dao.UserDaoMysqlImpl; public class UserServiceImpl implements UserService { private UserDao userDao; //Dynamic value injection using set public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void getUser() { userDao.getUser(); } }
Test:
import com.wong.dao.UserDaoImpl; import com.wong.dao.UserDaoMysqlImpl; import com.wong.service.UserService; import com.wong.service.UserServiceImpl; public class MyTest { public static void main(String[] args) { //Users actually call the business layer, and users in dao layer do not need to contact UserService userService = new UserServiceImpl(); //((UserServiceImpl) userService).setUserDao(new UserDaoImpl()); ((UserServiceImpl) userService).setUserDao(new UserDaoMysqlImpl()); userService.getUser(); } }
Using a Set interface, revolutionary changes have taken place here
private UserDao userDao; //Dynamic value injection using set public void setUserDao(UserDao userDao) { this.userDao = userDao; }
-
Previously, the program actively created objects. Control is in the hands of programmers.
private UserDao userDao = new UserDaoImpl(); private UserDao userDao = new UserDaoMysqlImpl() private UserDao userDao = new UserDaoOracleImpl() private UserDao userDao = new UserDaoSqlServerImpl() ......
-
After using set injection, the program no longer has the initiative, but becomes a passive acceptance object
((UserServiceImpl) userService).setUserDao(new UserDaoImpl()); ((UserServiceImpl) userService).setUserDao(new UserDaoMysqlImpl()); ((UserServiceImpl) userService).setUserDao(new UserDaoOracleImpl()); ((UserServiceImpl) userService).setUserDao(new UserDaoSqlServerImpl()); ......
This idea essentially solves the problem, and programmers no longer need 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.
IOC essence
Inversion of control (loC) is a design idea. Di (dependency injection) is a method to realize loC. Some people think that Dl is just another way of saying loC. In the program without loC, we use object-oriented programming. The creation of objects and the dependencies between objects are completely hard coded. In the program, the creation of objects is controlled by the program itself. After the control is reversed, the creation of objects is transferred to a third party. The so-called inversion of control is that the way to obtain dependent objects is reversed.
When configuring beans in XML, the definition information of beans is separated from the implementation, and the annotation method can integrate the two. The definition information of beans 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 ROC container implements control inversion, and its implementation method is dependency injection (DL).
3,HelloSpring
3.1. The first Spring program
-
Create an entity:
package com.wong.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 + '\'' + '}'; } }
-
Add the configuration file named 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"> <!--use Spring Create objects, in Spring These are called bean Previously used new keyword: Type variable name = new type(); Hello hello = new Hello(); bean = object new Hello() id = Variable name class = new Object of property This is equivalent to setting a value for an attribute in an object --> <bean id="hello" class="com.wong.pojo.Hello"> <property name="str" value="Spring"/> </bean> </beans>
-
test
import com.wong.service.UserServiceImpl; 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 //Parse beans XML file to generate and manage the corresponding Bean object ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //Objects are now managed in Spring. If you want to use them, just take them out directly //getBean: the parameter is the id of the bean in the spring configuration file Hello hello = (Hello) context.getBean("hello"); System.out.println(hello.toString()); } }
3.2. Examples of modifying IOC theoretical derivation
Register the required objects into the container in the configuration file:
<bean id="user" class="com.wong.dao.UserDaoImpl"/> <bean id="mysqlimpl" class="com.wong.dao.UserDaoMysqlImpl"/>
If you need to modify and call another method, you only need to modify the value in the configuration file:
<bean id="userService" class="com.wong.service.UserServiceImpl"> <!--<property name="userDao" ref="user"></property>--> <property name="userDao" ref="mysqlimpl"></property> </bean>
Let's explain that name="userDao" is actually the set method in UserServiceImpl (click in xml to jump to the corresponding place)
package com.wong.service; import com.wong.dao.UserDao; public class UserServiceImpl implements UserService { private UserDao userDao; //Dynamic value injection using set public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void getUser() { userDao.getUser(); } }
beans.xml 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"> <bean id="user" class="com.wong.dao.UserDaoImpl"/> <bean id="mysqlimpl" class="com.wong.dao.UserDaoMysqlImpl"/> <bean id="userService" class="com.wong.service.UserServiceImpl"> <!-- ref: quote Spring Created object in container value: Specific value, basic data type --> <property name="userDao" ref="user"></property> </bean> </beans>
Test:
import com.wong.service.UserServiceImpl; 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 and get the container of spring ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserServiceImpl userService = (UserServiceImpl) context.getBean("userService"); userService.getUser(); } }
Control: who controls the creation of objects? The objects of traditional applications are created by the program itself. After using Spring, the 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, which changes from active programming to passive reception.
You can browse the underlying source code through newClassPathXmlApplicationContext.
Now, we don't have to change it in the program at all. To implement different operations, you only need to modify them in the xml configuration file. The so-called loC: objects are created, managed and assembled by Spring.
4. How IOC creates objects
4.1. Original new method test
-
Create a new entity class
package com.wang.pojo; public class User { private String name; //Whether defined or not, there is a default parameterless construction //For the definition of parameterless construction shown here, see printing parameterless construction when this class is initialized public User() { System.out.println("User Nonparametric structure of"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public void show() { System.out.println("name=" + name); } }
-
Test:
import com.wang.pojo.User; public class MyTest { public static void main(String[] args) { User user = new User(); } }
It is found that when this method is executed, the "User's parameterless structure" is printed out
4.2. Test with Spring method
Configure beans XML file:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="user" class="com.wang.pojo.User"> <property name="name" value="Xiao Hong"></property> </bean> </beans>
The test print is as follows:
//Nonparametric construction of User
//name = Xiao Hong
import com.wang.pojo.User; 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"); User user = (User) context.getBean("user"); user.show(); } }
Then remove the parameterless construction method in the entity class (add a method with parameterless construction without defining parameterless construction):
package com.wang.pojo; public class User { private String name; public User(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void show() { System.out.println("name=" + name); } }
It is found that an error is reported in the xml file, and the test console will also report an error
<?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="user" class="com.wang.pojo.User"><!--The error reported here is in class 'User' No matching constructor found in--> <property name="name" value="Xiao Hong"></property> </bean> </beans>
Therefore, it is concluded that the creation method is the default nonparametric construction object
Suppose we want to create an object using a parametric construct:
-
Subscript assignment
<bean id="user" class="com.wang.pojo.User"> <constructor-arg index="0" value="Xiao Huang"/> </bean>
-
By type (not recommended), the same type of data is not excluded
<bean id="user" class="com.wang.pojo.User"> <constructor-arg type="java.lang.String" value="Galen"/> </bean>
-
Parameter name
<bean id="user" class="com.wang.pojo.User"> <constructor-arg name="name" value="Xiao Ming"/> </bean>
Summary: when the configuration file is loaded, the objects managed in the container have been initialized
5. Spring configuration
5.1 alias
If you add an alias, you can also use the alias to get this object
<bean id="user" class="com.wang.pojo.User"> <constructor-arg name="name" value="Xiao Ming"/> </bean> <alias name="user" alias="user2"/>
5.2 Bean configuration
id: the unique identifier of the bean, which is equivalent to the object name of the object
class: the fully qualified name corresponding to the bean object: package name + type
Name: it is also an alias, and name can take multiple aliases at the same time. The separators described below can be recognized
<bean id="user" class="com.wang.pojo.User" name="user2 user3,user4;user5"> <constructor-arg name="name" value="Xiao Ming"/> </bean>
5.3,import
This import is generally used for team development. It can import and merge multiple configuration files into one
Suppose that there are multiple developers in the project. These three people are responsible for the development of different classes. Different classes need to be registered in different beans. We can use import to import everyone's beans XML is merged into a total.
- Zhang San
- Li Si
- applicationContext.xml
<import resource="beans1.xml"/> <import resource="beans2.xml"/> <import resource="beans3.xml"/>
When using, just use the general configuration directly.
6. DI dependency injection
6.1 structural injection
The parameter free construction and parameter construction described in the way IOC creates objects
6.2 Set mode injection
- 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
package com.wang.pojo; public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
-
Real test object
package com.wang.pojo; import java.util.*; public class User { private String name; private Address address; private String[] books; private List<String> hobbys; private Map<String, String> card; private Set<String> games; private Properties info; private String ss; //get and set methods }
-
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="address" class="com.wang.pojo.Address"> <property name="address" value="Shenzhen"/> </bean> <bean id="user" class="com.wang.pojo.User"> <!--First, normal value injection, value--> <property name="name" value="Whoa, whoa, whoa"/> <!--Second, bean Injection, ref--> <property name="address" ref="address"/> <!--Array injection--> <property name="books"> <array> <value>Journey to the West</value> <value>Romance of the Three Kingdoms</value> <value>The Dream of Red Mansion</value> </array> </property> <!--list injection--> <property name="hobbys"> <list> <value>Play basketball</value> <value>Listen to the music</value> </list> </property> <!--map injection--> <property name="card"> <map> <entry key="Telephone" value="15641881641"/> <entry key="Campus card" value="784412"/> </map> </property> <!--set injection--> <property name="games"> <set> <value>LOL</value> <value>PUBG</value> <value>DNF</value> </set> </property> <!--null injection--> <property name="ss"> <null/> </property> <!--Properties injection--> <property name="info"> <props> <prop key="Student number">20220212</prop> <prop key="Gender">male</prop> <prop key="full name">Xiao Ming</prop> <prop key="root">Xiao Ming</prop> <prop key="url">Xiao Ming</prop> </props> </property> </bean> </beans>
-
test
import com.wang.pojo.User; 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"); User user = (User) context.getBean("user"); System.out.println(user.toString()); } }
6.3. Expansion injection (other methods)
xml constraints need to be imported
p namespace:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!--Import p Namespace usage--> 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"> </beans>
use:
<bean id="user" class="com.wang.pojo.User"> <property name="name" value="name"/> <property name="ss" value="Name 2"/> </bean> <!--p Namespace injection, you can directly inject the value of the attribute: property--> <bean id="user2" class="com.wang.pojo.User" p:name="name" p:ss="Name 2"/>
C namespace:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!--Import C Namespace usage--> 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"> </beans>
Usage: you need to have a parameterized constructor and a nonparametric constructor, because it is a constructor injection method
<bean id="user" class="com.wang.pojo.User"> <property name="name" value="name"/> <property name="ss" value="Name 2"/> </bean> <!--c Namespace injection through constructor: constructor-arg--> <bean id="user2" class="com.wang.pojo.User" c:name="name" c:ss="Name 2"/>
6.4 scope of Bean
-
Singleton mode (Spring default mechanism)
<bean id="user" class="com.wang.pojo.User" scope="singleton"> <property name="name" value="name"/> <property name="ss" value="Name 2"/> </bean>
The "user" and "user2" obtained here are equal, and the same object is "true" no matter how many are obtained
public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); User user = (User) context.getBean("user"); User user2 = context.getBean("user", User.class); System.out.println(user == user2);//true }
-
Prototype pattern: every time you get from the container, a new object will be generated
<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>
- Other request s, session s, and application s can only be used in Web development
7. Automatic assembly of Bean
- Automatic assembly is a way for Spring to meet bean dependencies
- Spring will automatically find in the context and automatically assemble properties for the bean
There are three assembly methods in Spring:
- Explicit configuration in xml (upper part)
- Explicit configuration in java
- Implicit auto assembly bean
7.1 test
-
Environment construction: a person has two pets
Person:
package com.wang.pojo; public class People { 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 "People{" + "cat=" + cat + ", dog=" + dog + ", name='" + name + '\'' + '}'; } }
Cats and dogs:
package com.wang.pojo; public class Cat { public void shout() { System.out.println("CatCatCatCatCatCatCat"); } }
package com.wang.pojo; public class Dog { public void shout() { System.out.println("DogDogDogDogDogDog"); } }
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="cat" class="com.wang.pojo.Cat"/> <bean id="dog" class="com.wang.pojo.Dog"/> <bean id="people" class="com.wang.pojo.People"> <property name="name" value="Xiao Ming"/> <property name="dog" ref="dog"/> <property name="cat" ref="cat"/> </bean> </beans>
Test:
import com.wang.pojo.People; 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"); People people = context.getBean("people", People.class); people.getCat().shout(); people.getDog().shout(); } }
7.2 byName automatic assembly
If the bean id is changed to uppercase, an error will also be reported:
For example:
<bean id="Cat" class="com.wang.pojo.Cat"/>
<bean id="cat" class="com.wang.pojo.Cat"/> <bean id="dog" class="com.wang.pojo.Dog"/> <!-- byName: Automatically finds and its own objects in the context of the container set The value after the method corresponds to bean id For example, in this example: setDog,setCat --> <bean id="people" class="com.wang.pojo.People" autowire="byName"> <property name="name" value="Xiao Ming"/> </bean>
7.3 byType automatic assembly
If there are two same types, it will also report errors and the compilation cannot pass: This is not possible
The bean id can be absent. It is thought to be based on the type
<bean id="cat" class="com.wang.pojo.Cat"/> <bean id="dog" class="com.wang.pojo.Dog"/> <bean id="dog11" class="com.wang.pojo.Dog"/> <!-- byType: It will automatically find the object with the same property type as its own object in the container context bean --> <bean id="people" class="com.wang.pojo.People" autowire="byType"> <property name="name" value="Xiao Ming"/> </bean>
<bean id="cat" class="com.wang.pojo.Cat"/> <bean id="dog" class="com.wang.pojo.Dog"/> <!-- byType: It will automatically find the object with the same property type as its own object in the container context bean --> <bean id="people" class="com.wang.pojo.People" autowire="byType"> <property name="name" value="Xiao Ming"/> </bean>
Summary:
- When byname, it is necessary to ensure that the IDs of all beans are unique, and the bean needs to be consistent with the value of the set method of the automatically injected attribute.
- When bytype, you need to ensure that the class of all beans is unique, and the bean needs to be consistent with the type of automatically injected attributes.
7.4. Use notes to realize automatic assembly
jdk1.5 supported annotations, spring 2 5 supports annotation.
To use notes:
-
Import constraints
<?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 http://www.springframework.org/schema/context/spring-context.xsd"> </beans>
-
Configuration annotation support
<context:annotation-config/>
@Autowired
It can be used directly on attributes or set mode.
Using Autowired, we don't need to write the Set method. The premise is that your auto assembled attribute exists in the IOC(Spring) container and conforms to the name byname
<?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 http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <bean id="cat" class="com.wang.pojo.Cat"/> <bean id="dog" class="com.wang.pojo.Dog"/> <bean id="people" class="com.wang.pojo.People"/> </beans>
package com.wang.pojo; import org.springframework.beans.factory.annotation.Autowired; public class People { @Autowired private Cat cat; @Autowired 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 "People{" + "cat=" + cat + ", dog=" + dog + ", name='" + name + '\'' + '}'; } }
explain:
@Nullable The field is marked with this annotation, indicating that this field can be null
If the required property of Autowired is false, it means that the object can be null, otherwise it is not allowed to be empty:
@Autowired(required = false)
public @interface Autowired { boolean required() default true; }
If the environment of @ Autowired automatic assembly is complex and the automatic assembly cannot be completed through an annotation [@ Autowired], we can use @ Qualifier(value = "xxx") to configure the use of @ Autowired and specify a unique bean object injection
This situation is in beans When the id or class of the bean configured in XML is confused
public class People { @Autowired(required = false) @Qualifier(value = "cat1111") private Cat cat; @Autowired @Qualifier(value = "dog111") private Dog dog; private String name; }
<?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 http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <bean id="cat" class="com.wang.pojo.Cat"/> <bean id="cat111" class="com.wang.pojo.Cat"/> <bean id="dog" class="com.wang.pojo.Dog"/> <bean id="dog111" class="com.wang.pojo.Dog"/> <bean id="people" class="com.wang.pojo.People"/> </beans>
@Resource annotation
public class People { @Resource(name = "cat2") private Cat cat; @Resource private Dog dog; private String name; }
Summary:
@Difference between Resource and @ Autowired:
- They are used for automatic assembly and can be placed in the attribute field
- @Autowired is implemented by byType, and this object must exist
- @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.
- The execution order is different: @ Autowired is implemented by byType@ Resource is implemented by byname by default.
8. Using annotation development
After spring 4, if you want to develop with annotations, you must ensure the aop package import
To use annotations, you need to import context constraints and add annotation support
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> </beans>
<!--Specify the package to be scanned, and the annotation under this package will take effect--> <context:component-scan base-package="com.wang.pojo"/>
@Component: the component is placed on the class, which indicates that the class is managed by Spring, that is, bean
-
bean
-
How to inject attributes
package com.wang.pojo; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; //Equivalent to < bean id = "user" class = "com. Wang. POJO. User" / > //@Component @Component public class User { private String name; //Equivalent to < property name = "name" value = "Xiao Ming" / > @Value("Xiao Ming") public void setName(String name) { this.name = name; } }
-
Derived annotation
@Component has several derived annotations. In web development, it will be layered according to MVC three-tier architecture
-
dao[@Repository]
-
service[@Service]
-
controller[@Controller]
These four annotation functions are the same. They all represent registering a class in Spring and assembling beans
-
-
automatic assembly
See 7.4
-
Scope
As configured in xml. Add it to the class here
//Equivalent to < bean id = "user" class = "com. Wang. POJO. User" / > //@Component component @Component //@Scope("singleton") //@Scope("prototype") public class User { private String name; //Equivalent to < property name = "name" value = "Xiao Ming" / > @Value("Xiao Ming") public void setName(String name) { this.name = name; } }
-
Summary
xml and annotations:
-
xml is more versatile and suitable for any occasion. Maintenance is simple and convenient.
-
Annotations are not their own classes and cannot be used. Their maintenance is relatively complex.
xml and annotation best practices:
-
xml is used to manage bean s
-
Annotations are only responsible for completing attribute injection
-
In the process of using, you should pay attention to: to make the annotation effective, you need to turn on the annotation support
<context:annotation-config/> <!--Specify the package to be scanned, and the annotation under this package will take effect--> <context:component-scan base-package="com.wang.pojo"/>
-
9. Configure Spring in Java
Now we don't use Spring's xml configuration at all, and leave it to Java.
JavaConfig is a subproject of Spring. After Spring 4, it has become a core function.
Example: use Java configuration instead of xml
Entity class:
package com.wong.pojo; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; //The annotation here means that this class is taken over by Spring and registered in the container @Component public class User { private String name; public String getName() { return name; } @Value("Zhang San")//Attribute injection value public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "name='" + name + '\'' + '}'; } }
Configuration class: (instead of xml)
package com.wong.config; import com.wong.pojo.User; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @Configuration //This will also be hosted by the Spring container and registered in the container, because it is a @ Component //@Configuration. Beans represents this class XML @ComponentScan("com.wong.pojo")//Scan package @Import(User.class)//Introduce other classes public class MyConfig { //Registering a bean is equivalent to the bean tag in the previous xml //The name of this method is equivalent to the id attribute in the bean tag //The return value of this method is equivalent to the class attribute in the bean tag @Bean public User getUser() { return new User();//Returns the object to be injected into the bean } }
Test:
import com.wong.config.MyConfig; import com.wong.pojo.User; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class MyTest { public static void main(String[] args) { //If the configuration class method is fully used, the container can only be obtained through the AnnotationConfig context and loaded through the class object of the configuration class. ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class); User getUser = (User) context.getBean("getUser"); System.out.println(getUser.getName()); } }
10. Agent mode
The proxy pattern is the bottom layer of spring AOP
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: that is, the role represented
- Acting role: acting as a real role. After acting as a real role, you will generally do some ancillary operations
- Client: the person who accesses the proxy object
Example: example of renting a house (interface - renting a house, real role - landlord, agent role - intermediary, customer - renter)
Rental:
package com.wong.demo01; //Rental interface public interface Rent { void rent(); }
landlord or landlady:
package com.wong.demo01; //landlord or landlady public class Host implements Rent { public void rent() { System.out.println("The landlord wants to rent the house"); } }
tenant:
package com.wong.demo01; public class Client { public static void main(String[] args) { //The tenant has direct contact with the landlord before there is no agent Host host = new Host(); host.rent(); } }
Intermediary:
package com.wong.demo01; public class Proxy implements Rent { private Host host; public Proxy() { } public Proxy(Host host) { this.host = host; } public void rent() { seeHouse(); host.rent(); } //Without affecting the original code, the function expansion is realized //Intermediaries can now do other things. For example: show you the house and pay the agency fee public void seeHouse() { System.out.println("The agent will show you the house"); } }
Tenants after adding proxy object (intermediary):
package com.wong.demo01; public class Client { public static void main(String[] args) { //The landlord wants to rent the house Host host = new Host(); host.rent(); //The agent helps the landlord rent a house. It can be attached to other operations, such as taking tenants to see the house, signing contracts and so on Proxy proxy = new Proxy(host); //The tenant does not have to face the landlord and can directly find an intermediary to rent a house proxy.rent(); } }
Benefits of agent mode:
- It can make the operation of real roles more pure, without paying attention to some public businesses
- The public is handed over to the agent role to realize the division of business
- When the public business is expanded, it is convenient for centralized management
Disadvantages:
- A real role will produce a proxy role, the amount of code will double, and the development efficiency will be low
10.2 dynamic agent
- The roles of dynamic agent and static agent are the same
- The agent class of dynamic agent is generated dynamically, which is not written directly.
- Dynamic agent can be divided into two types: dynamic agent-based; Class based dynamic agent
- Interface based: JDK dynamic agent (Demo)
- Class based: cglib
- java bytecode implementation: javasist
Two classes need to be understood: proxy and invocationhandler
Benefits of dynamic agents:
- It can make the operation of real roles more pure, without paying attention to some public businesses
- The public is handed over to the agent role to realize the division of business
- When the public business is expanded, it is convenient for centralized management
- 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!
example:
Interface:
//Rental interface public interface Rent { void rent(); }
Real role:
//landlord or landlady public class Host implements Rent { public void rent() { System.out.println("The landlord wants to rent the house"); } }
Dynamic proxy class:
package com.wong.demo02; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //Use this class to automatically generate proxy classes public class ProxyInvocationHandler implements InvocationHandler { //Implement InvocationHandler and override the method invoke //Proxy interface private Rent rent; public void setRent(Rent rent) { this.rent = rent; } //Generated proxy class public Object getProxy() { return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this); } //Process the proxy instance and return the result public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //The essence of dynamic agent is to use reflection mechanism seeHouse(); Object result = method.invoke(rent, args); return result; } //You can also implement ancillary operations before and after the call public void seeHouse() { System.out.println("The agent will show you the house"); } }
Customer test:
package com.wong.demo02; public class Client { public static void main(String[] args) { //Real role Host host = new Host(); //Proxy role: it doesn't exist yet ProxyInvocationHandler pih = new ProxyInvocationHandler(); //Handle the interface object we want to call by calling the program processing role pih.setRent(host); //The proxy here is generated dynamically Rent proxy = (Rent) pih.getProxy(); proxy.rent(); } }
11,AOP
11.1. What is AOP
AOP (Aspect Oriented Programming) means: aspect oriented programming, which realizes the unified maintenance of program functions through precompiled mode and runtime dynamic agent. AOP is the continuation of OOP, a hot spot in software development, an important content of Spring framework and a derivative paradigm of functional programming. AOP can isolate all parts of business logic, so as to reduce the coupling between all parts of business logic, improve the reusability of programs, and improve the efficiency of development.
11.2. The role of Aop in Spring
Provides declarative transactions that allow users to customize aspects.
- Crosscutting concerns: methods or functions that span multiple modules of an application. That is, the part that has nothing to do with our business logic, but we need to focus on is crosscutting concerns. Such as log, security, cache, transaction and so on
- Aspect: crosscutting concerns, special objects that 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.
- Jointpoint: 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.
11.3. Using Spring to implement AOP
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.8</version> </dependency>
Method 1: use Spring API interface [mainly Spring API interface implementation]
Example: add log before and after adding, deleting and modifying query methods
Interface:
package com.wong.service; public interface UserService { void add(); void delete(); void update(); void select(); }
Interface implementation class:
package com.wong.service; public class UserServiceImpl implements UserService { public void add() { System.out.println("Added a user"); } public void delete() { System.out.println("A user was deleted"); } public void update() { System.out.println("Updated a user"); } public void select() { System.out.println("Queried a user"); } }
Define crosscutting:
package com.wong.log; import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; 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[] args, Object target) throws Throwable { System.out.println(target.getClass().getName() + "---of---" + method.getName() + "Executed"); } }
package com.wong.log; import org.springframework.aop.AfterReturningAdvice; import java.lang.reflect.Method; 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); } }
xml 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.wong.service.UserServiceImpl"/> <bean id="log" class="com.wong.log.Log"/> <bean id="afterLog" class="com.wong.log.AfterLog"/> <!--Method 1: use the original Spring API Interface--> <!--to configure AOP:Import required aop Constraints of--> <aop:config> <!--breakthrough point--> <!--expression:expression--> <!--execution(Position modifier, return value, class name, method name and parameter of execution)--> <aop:pointcut id="pointcut" expression="execution(* com.wong.service.UserServiceImpl.*(..))"/> <!--Execute surround increase--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config> </beans>
Test:
import com.wong.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //The dynamic proxy is the interface, not the specific implementation class //An error is reported in this way: userserviceimpl userservice = context getBean("userservice", UserServiceImpl.class); UserService userservice = context.getBean("userservice", UserService.class); userservice.add(); } }
Method 2: Customize to implement AOP [mainly section definition]
Customize a slice:
package com.wong.diy; public class DiyPointcut { public void before() { System.out.println("=====Before method execution====="); } public void after() { System.out.println("=====After method execution====="); } }
xml configuration AOP:
<!--Method 2: user defined class--> <!--register bean--> <bean id="diy" class="com.wong.diy.DiyPointcut"/> <aop:config> <!--Custom section, ref Class to reference--> <aop:aspect ref="diy"> <!--breakthrough point--> <aop:pointcut id="point" expression="execution(* com.wong.service.UserServiceImpl.*(..))"/> <!--notice--> <aop:before method="before" pointcut-ref="point"/> <aop:after method="after" pointcut-ref="point"/> </aop:aspect> </aop:config>
Test (same as above)
Method 3: implement with annotation
Entity class:
package com.wong.diy; //Method 3: implement AOP by annotation 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; @Aspect//Mark that this class is a facet public class AnnotationPointCut { @Before("execution(* com.wong.service.UserServiceImpl.*(..))") public void before() { System.out.println("=====Before method execution====="); } @After("execution(* com.wong.service.UserServiceImpl.*(..))") public void after() { System.out.println("=====After method execution====="); } //In the surround addition, we can give a parameter to represent the point where we want to get the processing entry point @Around("execution(* com.wong.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("=====Surround front====="); Signature signature = joinPoint.getSignature();//Get signature System.out.println("signature:" + signature); //Execution method Object proceed = joinPoint.proceed(); System.out.println("=====After surround====="); System.out.println(proceed); } }
xml configuration:
<!--Mode 3:--> <bean id="annotationPointCut" class="com.wong.diy.AnnotationPointCut"/> <!--Enable annotation support JDK(default proxy-target-class="false") If yes ture:cglib--> <aop:aspectj-autoproxy proxy-target-class="false"/>
Test (same as above)
12. Integrate Mybatis
13. Declarative transaction
13.1 affairs
- Treat a group of businesses as a business, and they will either succeed or fail
- Ensure data integrity and consistency
ACID principle of transaction:
- Atomicity
- uniformity
- Isolation
- Multiple businesses may operate the same resource to prevent data corruption
- persistence
- Once the transaction is committed, no matter what happens to the system, the result will not be affected and will be written to the memory persistently
13.2 transaction management in Spring
- Declarative transaction: AOP
- Programming transaction: it is necessary to manage the transaction in the code
There are seven propagation characteristics of transactions, which can be queried and understood.
Why transactions are needed:
- If transactions are not configured, there may be inconsistent data submission
- If you do not configure declarative transactions in Spring, you need to manually configure transactions in your code