Initial Spring
Various versions in software development
Alpha: it is an internal beta version. It is generally not released to the outside. There are many bugs. It is generally used only by testers.
Beta: it's also a beta version. New features will be added to the version at this stage. After Alpha.
RC: (Release Candidate) as the name suggests, it is a candidate version for software. The release candidate version is on the system platform. RC version will not add new functions, mainly focusing on repairing the defects found in the test.
GA: general availability, officially released version. In foreign countries, GA is usually used to identify the release version. GA version is the version that the development team thinks is Stable (some software may be identified as Stable version or Production version, which means the same as GA). It can be used in more critical occasions, such as Production environment.
snapshots snapshot version represents the version under development. It is generally in the development stage. There are still functions not completed or bug s to be repaired in version 0.0.1, so the code is updated frequently in this stage
Release represents a relatively stable release version. After all the functions of this iteration have been completed and passed the test, it can be released as 0.0.1-Release version. Once the release version is released, the code will not be changed. Therefore, if a bug is found in the 0.0.1-Release version and needs to be repaired, we should change the 0.0.1-Release version to 0.0.2-SNAPSHOT, Then modify the bug and test it. After that, change 0.0.2-SNAPSHOT to 0.0.2-Release release
brief introduction
-
Spring: spring brings spring to the software industry!
-
In 2002, the prototype of Spring framework, interface21 framework, was launched for the first time
-
Based on the interface 21 framework, the Spring framework has been redesigned and continuously enriched its connotation. The official version of 1.0 was released on March 24, 2004.
-
Rod Johnson is the founder of spring framework. His major is not computer, but musician.
-
Spring concept: make existing technology easier to use. Itself is a hodgepodge, integrating the existing technical framework!
-
SSH : Struct2 + Spring + Hibernate
-
SSM : SpringMVC + Spring + Mybatis
Official website: https://docs.spring.io/spring-framework/docs/current/reference/html/overview.html#overview
Official download address: https://repo.spring.io/ui/native/release/org/springframework/spring
<dependencies> <!-- https://mvnrepository.com/artifact/springframework/spring-webmvc --> <dependency> <groupId>springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>1.2.6</version> </dependency> </dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.9</version> </dependency>
advantage
- Spring is an open source and free framework (container)
- Spring is a lightweight, non intrusive framework
- Inversion of control (IOC), aspect oriented programming (AOP)
- Support transaction processing and framework integration
To sum up: Spring is a lightweight inversion of control (IOC) and aspect oriented programming (AOP)
form
Seven modules
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-8vkdl5cm-163511896031) (spring. Assets / image-20210910074329439. PNG)]
expand
-
Spring Boot
- A rapid development of scaffolding
- Based on SpringBoot, you can quickly develop a single service
- Agreed approximate configuration
-
Spring Cloud
- Spring Cloud is implemented based on SpringBoot
The premise of learning SpringBoot is to learn Spring and Spring MVC!
Disadvantages: it has developed for too long and violated the original concept! Configuration is very cumbersome, known as "configuration hell"!
IOC theoretical derivation
Guide Package
<dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.0.RELEASE</version> </dependency> </dependencies>
Conventional writing
-
UserDao
package com.hopeful.dao; public interface IUserDao { public void getUser(); }
-
UserDaoImpl
package com.hopeful.dao; public class UserDaoImpl implements IUserDao { public void getUser() { System.out.println("Get user by default"); } }
-
UserService
package com.hopeful.service; import com.hopeful.dao.IUserDao; import com.hopeful.dao.UserDaoImpl; public interface IUserService { public void getUser(); }
-
UserServiceImpl
package com.hopeful.service; import com.hopeful.dao.IUserDao; import com.hopeful.dao.UserDaoImpl; import com.hopeful.dao.UserMySQLImpl; public class UserServiceImpl implements IUserService { // public IUserDao userDao = new UserDaoImpl(); public IUserDao userDao = new UserMySQLImpl(); public void getUser() { userDao.getUser(); } }
-
test
package com.hopeful.service; public class MyTest { public static void main(String[] args) { IUserService userServie = new UserServiceImpl(); userServie.getUser(); } }
If you suddenly add an implementation class that implements IUserDao interface, you need to modify the code of the Service layer, which is very cumbersome. If the amount of code is particularly large, the maintenance cost is very expensive. The details are as follows:
package com.hopeful.dao; import com.hopeful.service.IUserService; public class UserMySQLImpl implements IUserDao { public void getUser() { System.out.println("obtain SQL user"); } }
UserServiceImpl is modified to:
package com.hopeful.service; import com.hopeful.dao.IUserDao; import com.hopeful.dao.UserDaoImpl; import com.hopeful.dao.UserMySQLImpl; public class UserServiceImpl implements IUserService { // public IUserDao userDao = new UserDaoImpl(); public IUserDao userDao = new UserMySQLImpl(); public void getUser() { userDao.getUser(); } }
Injection writing
Use the Setter interface to realize revolutionary changes, as follows:
UserServiceImpl is modified to
package com.hopeful.service; import com.hopeful.dao.IUserDao; import com.hopeful.dao.UserDaoImpl; import com.hopeful.dao.UserMySQLImpl; import java.util.Set; public class UserServiceImpl implements IUserService { // public IUserDao userDao = new UserDaoImpl(); // public IUserDao userDao = new UserMySQLImpl(); public IUserDao userDao; // Using set method to dynamically bind objects public void setUserDao(IUserDao userDao) { // this must be written here, otherwise a null pointer will appear this.userDao = userDao; } public void getUser() { userDao.getUser(); } }
test
package com.hopeful.service; import com.hopeful.dao.UserMySQLImpl; public class MyTest { public static void main(String[] args) { IUserService userServie = new UserServiceImpl(); ((UserServiceImpl)userServie).setUserDao(new UserMySQLImpl()); userServie.getUser(); } }
It turns out that the program actively creates objects, that is, it needs the program to actively create objects
After using set injection, the program no longer has the initiative, but passively receives objects, that is, the initiative created now is handed over to the user, which needs to be created.
The program coupling is low and easy to maintain.
Conclusion: this idea essentially solves the problem. Our programs no longer need to manage the creation of objects. The coupling of the system is greatly reduced, and we can focus more on the implementation of business. This is the prototype of IOC.
The essence of IOC
Inversion Of Control (ICO) is a design idea, and DI (dependency injection) is a way to implement IOC. Some people think that DI is just another expression of 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. Personal Wenwei's so-called control reversal is that the way to obtain dependent objects is reversed.
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-2DtGQjVP-1635118396033)(Spring.assets/image-20210914130702155.png)]
IOC container in Spring
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)
Hello spring case
Guide Package
<dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.0.RELEASE</version> </dependency> </dependencies>
If the parent project has been imported, you can omit here.
Write configuration file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <!--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"> <property name="name" value="Hello Spring"/> </bean> </beans>
Create entity class
@Data public class Hello { private String name; }
test
@Test public void TestStr() { //Get the context object of Spring! ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //Our objects are now managed in Spring. We need to use them. Just take them out! Hello hello = (Hello) context.getBean("hello"); System.out.println(hello.toString()); }
It can be seen from the above case that the object is used, and the keyword new is not used to create the object. That is, the spring framework manages objects, that is, creation, management and assembly.
ponder a problem
-
Who created the object?
Hello was 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 newClassPathXmlApplicationContext.
OK, up to now, we don't need to change it in the program. To realize different operations, we only need to modify it in the xml configuration file. The so-called IOC is done in one sentence: objects are created, managed and assembled by Spring!
Problems encountered
applicationContext cannot find the getBean methodSolution 1: add setter and getter methods
Answer 2: modify the loaded package to org.springframework.context.ApplicationContext
Solution 3: manually load dependencies, file - > project structure
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-e1k301xz-163511839605) (spring. Assets / image-20210917070107106. PNG)]
[the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-a90mwxct-163511896037) (spring. Assets / image-20210917070202185. PNG)]
Select the library you want
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-WYr10XYG-1635118396039)(Spring.assets/image-20210917070227706.png)]
Finally, don't forget to click application or application. Hee hee, my problem will be solved!
Compilation failed: internal java compiler errorThe edited version is inconsistent with the jdk version
Reference documents: https://blog.csdn.net/shizheng_Li/article/details/107050180
org.springframework.beans.factory.config.ConfigurableListableBeanFactory.getApplicationStartup()Lorg...This is caused by the difference between the dependent version and the loaded version. I used spring 5.3.9 at first, and then changed to 5.2.0, resulting in such an error
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-3ojejdv-163511896040) (spring. Assets / image-20210917070202185. PNG)]
Adjust to the version you need!
Conventional writing before integration
-
On the basis of the original conventional writing method, add the configuration file beans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="userDaoImpl" /> <bean id="userMySQLImpl" /> <bean id="userOracleImpl" /> <bean id="userServiceImpl"> <!-- ref quote spring In container bean --> <property name="userDao" ref="userOracleImpl"/><!-- Only modification is required here ref You can call different implementation classes --> </bean> </beans>
-
test
@Test public void testIOC() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserServiceImpl userServiceImpl = context.getBean("userServiceImpl", UserServiceImpl.class); userServiceImpl.getUser(); }
How Spring is created
- Environmental preparation
package com.hopeful.pojo; public class User { private String name; public User() { System.out.println("user Created with a parameterless constructor"); } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "name='" + name + '\'' + '}'; } }
-
test
package com.hopeful.pojo; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { public static void main(String[] args) { // The parameterless function was called User user = new User(); // user created the with a parameterless constructor } }
Setter based dependency setter method
Create 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"></bean> </beans>
test
package com.hopeful.pojo; 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"); // spring is built by default through parameterless construction User user = (User)context.getBean("user"); // user created the with a parameterless constructor } }
Constructor build
Constructor parameter index
<bean id="user"> <constructor-arg index="0" value="Hopeful"></constructor-arg> </bean>
Constructor parameter types match, not recommended
<bean id="user"> <constructor-arg type="java.lang.String" value="Hopeful2"></constructor-arg> </bean>
Constructor parameter name, recommended
<bean id="user"> <constructor-arg name="name" value="Hopeful3"/> </bean>
Summary: when the configuration file is loaded, the objects managed in the container have been initialized! The object obtained from the container more than once is the same object.
Spring configuration
Alias alias
<alias name="user" alias="userNew"/>
bean configuration
<!-- id:Unique identifier, which is equivalent to our object name--> <!-- class: bean Object's fully qualified class name, package name + type--> <!-- name: It is also an alias, and you can have multiple aliases with spaces/comma/Semicolons are divided--> <!-- scopt: Scope--> <bean id="user" name="user2,u2;u3 u4" scope="singleton"> <constructor-arg name="name" value="Hopeful3"/> </bean>
import
<import resource="beans.xml"/> <import resource="beans2.xml"/> <import resource="beans3.xml"/>
configuration file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- id:Unique identifier, which is equivalent to our object name--> <!-- class: bean Object's fully qualified class name, package name + type--> <!-- name: It is also an alias, and you can have multiple aliases with spaces/comma/Semicolons are divided--> <!-- scopt: Scope--> <bean id="user" name="user2,u2;u3 u4" scope="singleton"> <constructor-arg name="name" value="Hopeful3"/> </bean> </beans>
Dependency injection
Constructor Injection
As mentioned earlier
Set method injection [ key ]
-
Dependency injection: Set injection
- Dependency: bean creation requires dependency and container
- Injection: all attributes in the bean object are injected by the container
<?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="student" name="user2,u2;u3 u4">--> <!-- <constructor-arg name="name" value="Hopeful3"/>--> <!-- </bean>--> <bean id="address"></bean> <bean id="student" name="user2,u2;u3 u4"> <property name="name" value="StudentName"></property> <property name="address" ref="address"></property> <property name="books"> <array> <value>Journey to the West</value> <value>Romance of the Three Kingdoms</value> <value>Water Margin</value> <value>The Dream of Red Mansion</value> </array> </property> <property name="hobbys"> <list> <value>Basketball</value> <value>badminton</value> <value>Table Tennis</value> </list> </property> <property name="card"> <map> <entry key="ID" value="2334342343453453"></entry> <entry key="bank card" value="23434543545456456"/> </map> </property> <property name="games"> <set> <value>LOL</value> <value>Greedy snake</value> </set> </property> <!-- null value--> <property name="wife"> <null/> </property> <property name="info"> <props> <prop key="full name">Zhang San</prop> <prop key="Gender">male</prop> </props> </property> </bean> </beans>
Expansion mode injection
Official interpretation:
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-qtjiidi5-1635118396043) (spring. Assets / image-2021092321445504. PNG)]
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-nuwaiu4j-163511896045) (spring. Assets / image-20210923214532. PNG)]
Entity class
package com.hopeful.pojo; public class User { private String name; private String pwd; public User() { } public User(String name, String pwd) { this.name = name; this.pwd = pwd; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", pwd='" + pwd + '\'' + '}'; } }
xml files, c-namespace and p-namespace
<?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"> <bean id="user" > <property name="name" value="Hopeful"/> <property name="pwd" value="123456"/> </bean> <!-- p namespace property Injection is equivalent to the above--> <bean id="user2" p:name="Hopeful2" p:pwd="222222"></bean> <bean id="user3"> <constructor-arg name="name" value="Hopeful3"></constructor-arg> <constructor-arg name="pwd" value="33333333"/> </bean> <!-- c-namespace constructor Injection is equivalent to the above --> <bean id="user4" c:name="Hopeful3" c:pwd="3333333333"/> </beans>
test
package com.hopeful; import com.hopeful.pojo.User; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyUserTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("userBean.xml"); // User users = context.getBean("user1", User.class); // User users = context.getBean("user2", User.class); // User users = context.getBean("user3", User.class); User users = context.getBean("user4", User.class); System.out.println(users); } }
beans scope
[the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-oqbfx0y1-163511896046) (spring. Assets / image-20210924071723110. PNG)]
-
There is only one instance in a singleton application
<bean id="user" scope="singleton"> <property name="name" value="Hopeful"/> <property name="pwd" value="123456"/> </bean>
public class MyUserTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("userBean.xml"); User users = context.getBean("user", User.class); User users2 = context.getBean("user", User.class); System.out.println(users == users2); // true } }
Features: it is used for single thread. When using this mode during concurrency, it is easy to produce some delays
-
The prototype pattern creates different instances each time
<bean id="user" scope="prototype"> <property name="name" value="Hopeful"/> <property name="pwd" value="123456"/> </bean>
public class MyUserTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("userBean.xml"); User users = context.getBean("user", User.class); User users2 = context.getBean("user", User.class); System.out.println(users == users2); // false } }
Features: it wastes resources, but multithreading will not cause problems
automatic assembly
-
ByName assembly by name
<!-- ByName: It will automatically find its own objects in the container context Set Method beanId--> <bean id="person" autowire="byName"> <property name="name" value="Hopeful"/> </bean>
-
ByType assembly by type
<!-- ByType: It will automatically find the object with the same object type in the container context bean--> <bean id="person" autowire="byType"> <property name="name" value="Hopeful"/> </bean>
ByName is assembled by name. It is necessary to ensure that the IDs of all bean s are unique. The ID name must be consistent with the name behind the set method!
ByType is assembled by type. It is necessary to ensure that the class of all bean s is unique. This type needs to be globally unique in the application!
@Autowired
<?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 http://www.springframework.org/schema/context/spring-context.xsd"> <!-- Open use annotation --> <context:annotation-config/> <bean id="dog"/> <bean id="cat"/> <bean id="person"> <property name="name" value="Hopeful"/> </bean> </beans>
Entity class
package com.hopeful.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; @Data @AllArgsConstructor @NoArgsConstructor public class Person { private String name; @Autowired private Dog dog; @Autowired private Cat cat; }
test
package com.hopeful.pojo; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.transaction.annotation.Transactional; public class MyTest { @Test public void testAutowired() { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Person person = context.getBean("person", Person.class); person.getCat().shut(); person.getDog().shut(); } }
Use requirements:
- Import constraints: context constraints
- Support for configuring annotations: < context: annotation config / >
be careful:
- You can use it directly on the attribute! It can also be used on the set method
- Using Autowired, we don't need to write a Set to make it higher, provided that your auto assembled attribute is in the IOC container and the type conforms to ByType or byName
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 https://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/> <!--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="dog"/> <bean id="dog2"/> <bean id="person"> </bean> </beans>
package com.hopeful.pojo; import lombok.Data; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import javax.annotation.Resource; @Data public class Person { private String name; // Successfully assembled by ByName @Autowired private Animal dog; }
ByType
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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 http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <!--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="dog1"/> <bean id="person"> </bean> </beans>
package com.hopeful.pojo; import lombok.Data; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import javax.annotation.Resource; @Data public class Person { private String name; // Successfully assembled by ByType @Autowired private Animal dog; }
polular science:
// Add the required = false attribute, which means that the attribute can be null, otherwise it cannot be null (the default is true) @Autowired(required = false) // Annotation @ Autowired source code @Target() @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Autowired { boolean required() default true; }
If the environment of @ Autowired automatic assembly is complex and the automatic assembly cannot confirm the assembly of specific beans (there are beans of the same type), the @ Autowired annotation cannot complete the assembly alone. We can use @ Qualifier(value = "beanName") to assemble and specify the only bean for injection.
<?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 http://www.springframework.org/schema/context/spring-context.xsd"> <!-- Open use annotation --> <context:annotation-config/> <bean id="dog1"/> <bean id="dog2"/> <bean id="cat1"/> <bean id="cat2"/> <bean id="person"> <property name="name" value="Hopeful"/> </bean> </beans>
Entity class
package com.hopeful.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @Data @AllArgsConstructor @NoArgsConstructor public class Person { private String name; // Add the required = false attribute, which means that the attribute can be null, otherwise it cannot be null (the default is true) @Autowired(required = false) @Qualifier(value = "dog1") private Dog dog; @Autowired @Qualifier(value = "cat1") private Cat cat; }
Test, see above.
@Resource
<?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 http://www.springframework.org/schema/context/spring-context.xsd"> <!-- Open use annotation --> <context:annotation-config/> <bean id="dog1"/> <bean id="dog2"/> <bean id="cat1"/> <bean id="cat2"/> <bean id="person"> <property name="name" value="Hopeful"/> </bean> </beans>
Entity class
package com.hopeful.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.Value; import javax.annotation.Resource; import javax.annotation.Resources; /** * Person * * @author : yl * @version : [v1.0] * @createTime : [2021/9/24 7:36] */ @Data @AllArgsConstructor @NoArgsConstructor public class Person { private String name; @Resource(name = "dog1") public Dog dog; @Resource(name = "cat2") private Cat cat; }
test
package com.hopeful.pojo; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.transaction.annotation.Transactional; /** * MyTest * * @author : yl * @version : [v1.0] * @createTime : [2021/9/24 7:41] */ public class MyTest { @Test public void testAutowired() { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Person person = context.getBean("person", Person.class); person.getCat().shut(); person.getDog().shut(); } }
@Resource collects ByName and ByType features. By default, it is found by ByName. If it cannot be found, it is found by ByType. If it cannot be found, an error is reported, but a specific bean can be specified by the attribute name.
For ByName and ByType tests, please refer to @ Autowired test
@Similarities and differences between Autowired and @ Resource
Summary:
Same: @ Autowired and @ Resource are both used for automatic assembly and can be used on attributes
Different:
- @Autowired assembles bean s by ByType or ByName
- @The Resource is assembled by ByName first, if it cannot be found, and then by ByType. Otherwise, an error is reported, but a bean with a specific name can be specified through the name attribute
// @Autowired // @Qualifier(value = "dog1") @Resource(name = "dog1") // The above two annotations are equivalent to the following annotation, but the java annotation @ Resource does not prompt private Animal dog;
Spring annotation development
After spring 4, when developing with annotations, you must import aop packages.
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-iHuYDiev-1635118396047)(Spring.assets/image-20210928070605050.png)]
-
Use of bean s
automatic assembly
Specify package scan
<?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 http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <!-- Specify the path to scan and register the classes in it to spring In container --> <context:component-scan base-package="com.hopeful"/> <!-- <bean id="user">--> <!-- <property name="name" value="HOPEFUL_xml_INNER"/>--> <!-- </bean>--> </beans>
-
Property injection
package com.hopeful.pojo; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Repository; /** * User * * @author : yl * @version : [v1.0] * @createTime : [2021/9/27 20:57] */ @Repository @Data public class User { // Equivalent to < property name = "name" value = "Hope" / > in the xml file // @Value("HOPEFUL") private String name; @Value("HOPEFUL22") public void setName(String name) { this.name = name; } }
@Priority of value attribute:
xml configuration file location priority > set method > field attribute
-
Derived annotation
@Component has several derived annotations. In web development, we will layer according to mvc three-tier architecture
- dao [@Repository]
- service [@Service]
- controller [@controller]
These four annotation functions are the same, which represent the annotation of this class into the spring container.
-
automatic assembly
- @Autowired
- @Resource
-
Scope
@Scope("singleton | prototype")
package com.hopeful.pojo; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Repository; @Repository @Data @Scope("singleton") public class User { // Equivalent to < property name = "name" value = "Hope" / > in the xml file @Value("HOPEFUL") private String name; }
[TOC]
-
Best practices
-
xml and annotation
- xml is more versatile and suitable for any scenario
- Annotations are not their own classes and cannot be used (other types of bean s cannot be referenced), and maintenance is relatively complex.
-
xml and direct best practices
- xml is only used to manage bean s
- Annotations are only responsible for completing attribute injection
- In the process of using, we only need to pay attention to two points: turn on the use of annotations, and then scan the specified package.
<?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 http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <!-- Specify the path to scan and register the classes in it to spring In container --> <context:component-scan base-package="com.hopeful"/> </beans>
-
Using javaConfig to implement configuration
Now we will not use the xml configuration of Spring at all, and leave it to java!
javaConfig is a sub project of Spring. After Spring 4, it has become a core function!
Entity class
package com.hopeful.pojo; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Repository; public class User { @Value("Hopeful_appConfig") private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
Configuration class
package com.hopeful.config; import com.hopeful.pojo.User; import org.springframework.context.annotation.*; // It is still a component in essence, so it will also be managed by the spring container // @The Configuration annotation indicates that the annotation is a Configuration class, which is equivalent to applicationContext.xml in spring //Import profile //@ImportResource(locations={"classpath:applicationContext.xml"}) //Importing configuration classes before spring 4.2 //@Import() //Import ordinary Java beans after spring 4.2 //@Import(DemoService.class) / / not supported before spring 4.2 @Configuration @ComponentScan("com.hopeful.pojo") @Import(AppConfig2.class) @ImportResource(locations={"classpath:applicationContext.xml"}) public class AppConfig { // You cannot jump here, which only means idea is not supported // Registering a bean is equivalent to a bean tag we wrote earlier // The name of this method is equivalent to the id attribute of the bean tag // The return value of this method is equivalent to the class attribute of the bean tag // @Bean public User user() { return new User(); } }
test
package com.hopeful; import com.hopeful.config.AppConfig; import com.hopeful.pojo.User; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class MyTest { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); User user = context.getBean("user", User.class); System.out.println(user.getName()); } }
Previously, the IOC container was obtained through the ClassPathXmlApplicationContext class using the xml configuration file
Now configure javaConfig and get the IOC container through the AnnotationConfigApplicationContext class
[the external chain picture transfer fails, and the source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-r9efknyx-163511896048) (spring. Assets / image-20210928072839840. PNG)]
proxy pattern
Why learn agent mode? Because this is the bottom layer of spring AOP! [SpringAOP + SpringMVC]
Agent classification:
- Static proxy
- Dynamic agent
Take renting as an example
Landlord rental:
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-UttFW56i-1635118396048)(Spring.assets/image-20210928211516197.png)]
Intermediary rental house
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-y7mgfwsw-163511896049) (spring. Assets / image-20210928211736217. PNG)]
Static proxy
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 perform ancillary operations
- Client: the person who accesses the proxy object
Interface
package com.hopeful.demo1; public interface Rent { public void rent(); }
Real role
package com.hopeful.demo1; // landlord or landlady public class Landlord implements Rent { public void rent() { System.out.println("The landlord wants to rent a house..."); } }
delegable role
package com.hopeful.demo1; // intermediary public class Proxy implements Rent { private Landlord landlord; public Proxy(Landlord landlord) { this.landlord = landlord; } public Proxy() { } public void rent() { lookHouse(); landlord.rent(); signAContract(); } // Look at the house public void lookHouse() { System.out.println("Intermediary show~"); } // sign a contract public void signAContract(){ System.out.println("The intermediary signed a contract with us"); } }
test
package com.hopeful.demo1; public class Client { public static void main(String[] args) { // Rent the house directly to the landlord // Landlord landlord = new Landlord(); // landlord.rent(); // Rent a house through an intermediary Landlord landlord = new Landlord(); // Landlord rents house // Agent: the agent helps the landlord rent a house, but the agent usually has some ancillary operations Proxy proxy = new Proxy(landlord); // Directly find an intermediary to rent a house without looking for the landlord 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 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!
Disadvantages:
- A real role will produce a proxy role; Code will double - development efficiency will be lower!
Agent to deepen understanding
Add log module
Interface
package com.hopeful.demo2; public interface IUserService { public void add(); public void delete(); public void update(); public void query(); }
Real role
package com.hopeful.demo2; /** * UserDao * * @author : yl * @version : [v1.0] * @createTime : [2021/9/28 22:08] */ public class UserService implements IUserService { public void add() { System.out.println("Added a new user"); } public void delete() { System.out.println("A user was deleted"); } public void update() { System.out.println("A user has been updated"); } public void query() { System.out.println("A user was queried"); } // It is a taboo to change the business code in the company }
Proxy object
package com.hopeful.demo2; /** * Proxy * * @author : yl * @version : [v1.0] * @createTime : [2021/9/28 22:16] */ public class Proxy implements IUserService { private IUserService userService; public void setUserService(IUserService 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 method) { System.out.println("[debug] Yes" + method +"method"); } }
user
package com.hopeful.demo2; public class Client { public static void main(String[] args) { // UserService userService = new UserService(); // userService.add(); Proxy proxy = new Proxy(); proxy.setUserService(new UserService()); proxy.add(); } }
Dynamic agent
Benefits of agent mode:
-
It can make the operation of real characters more pure! Don't pay attention to some public business
-
The public 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!
-
Dynamic agents have the same role as static agents
-
The proxy class of dynamic proxy is generated dynamically, which is not written directly
-
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: javasist
-
Two classes need to be understood: Proxy proxy, invocationHandler and call handler
IUserService interface
package com.hopeful.demo2; public interfajavace IUserService { public void add(); public void delete(); public void update(); public void query(); }
UserService implementation class
package com.hopeful.demo2; /** * UserDao * * @author : yl * @version : [v1.0] * @createTime : [2021/9/28 22:08] */ public class UserService implements IUserService { public void add() { System.out.println("Added a new user"); } public void delete() { System.out.println("A user was deleted"); } public void update() { System.out.println("A user has been updated"); } public void query() { System.out.println("A user was queried"); } // It is a taboo to change the business code in the company }
Agent handler
package com.hopeful.demo4; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyInvocationHandler implements InvocationHandler { private Object target; public void setTarget(Object target) { this.target = target; } // Generate proxied objects public Object getProxy() { return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } // Process the proxy instance and return the result // The method in the proxy object calling interface - $proxy0 is the real body of the proxy object, and the corresponding method is called - -- this method internally calls the member h of its parent class and calls the invoke method of H - -- that is, it calls the invoke method passed in the InvocationHandler. As for the return value, it depends on how our InvocationHandler implementation class writes. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { log(method.getName()); Object object = method.invoke(target,args); return object; } public void log(String msg) { System.out.println("Yes"+ msg +"method"); } }
test
package com.hopeful.demo4; import com.hopeful.demo2.IUserService; import com.hopeful.demo2.UserService; /** * Client * * @author : yl * @version : [v1.0] * @createTime : [2021/10/12 7:19] */ public class Client { public static void main(String[] args) { // Real role UserService userService = new UserService(); // The agent role does not exist //Proxy call handler ProxyInvocationHandler pih = new ProxyInvocationHandler(); pih.setTarget(userService); // Get proxy class // The method in the proxy object calling interface - $proxy0 is the real body of the proxy object, and the corresponding method is called - -- this method internally calls the member h of its parent class and calls the invoke method of H - -- that is, it calls the invoke method passed in the InvocationHandler. As for the return value, it depends on how our InvocationHandler implementation class writes. IUserService proxy = (IUserService) pih.getProxy(); proxy.delete(); } }
Benefits of agent mode:
- It can make the operation of real characters more pure! Don't pay attention to some public business
- The public 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!
- The dynamic agent class represents an interface, which is generally the corresponding type of business
- A dynamic proxy class can proxy multiple classes as long as it implements the same interface.
Talk about AOP
[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-dz33h85j-163511896050) (spring. Assets / image-20210928224244233. PNG)]
AOP
Spring native implementation of AOP - using Spring API interface
1. Import dependency:
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.7</version> </dependency>
2. Write interface and implementation classes
package com.hopefu.service; public interface IUserService { public void add(); public void delete(); public void update(); public void select(); }
package com.hopefu.service; public class UserServiceImpl implements IUserService { @Override public void add() { System.out.println("Yes add method"); } @Override public void delete() { System.out.println("Yes delete method"); } @Override public void update() { System.out.println("Yes update method"); } @Override public void select() { System.out.println("Yes select method"); } }
3. Write log
package com.hopefu.log; import org.springframework.aop.AfterAdvice; import org.springframework.aop.AfterReturningAdvice; import java.lang.reflect.Method; public class AfterLog implements AfterReturningAdvice { public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { System.out.println("Yes"+method.getName()+"Method, the return value is"+o); } }
package com.hopefu.log; import org.springframework.aop.AfterAdvice; import org.springframework.aop.BeforeAdvice; import org.springframework.aop.MethodBeforeAdvice; import javax.sound.midi.Soundbank; import java.lang.reflect.Method; public class BeforeLog implements MethodBeforeAdvice { public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("Yes" + method.getName() + "Print log before method"); } }
4. Prepare configuration file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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"> <bean id="userService"></bean> <bean id="afterLog"></bean> <bean id="beforeLog"></bean> <aop:config> <!-- Entry point: expression:expression, execution(* * * * *)--> <aop:pointcut id="pointcut" expression="execution(* com.hopefu.service.UserServiceImpl.*(..))"/> <!-- Surround notification enhancement--> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> <aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/> </aop:config> </beans>
test
package com.hopeful.service; import com.hopefu.service.IUserService; import com.hopefu.service.UserServiceImpl; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * MyTest * * @author : yl * @version : [v1.0] * @createTime : [2021/10/13 21:06] */ public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); IUserService userService = context.getBean("userService", IUserService.class); userService.add(); } }
Custom AOP
package com.hopeful.diy; public class PoinCutDiy { public void before() { System.out.println("before"); } public void after() { System.out.println("after"); } }
Write the IUserService interface and implementation class UserServiceImpl. Refer to the case of using the spring API interface
configuration file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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"> <!-- Mode II --> <bean id="userService"/> <bean id="pointCutDiy"/> <aop:config> <aop:aspect ref="pointCutDiy"> <aop:pointcut id="point" expression="execution(* com.hopeful.service.UserServiceImpl.*(..))"/> <aop:before method="before" pointcut-ref="point"/> <aop:after method="after" pointcut-ref="point"/> </aop:aspect> </aop:config> </beans>
Test: refer to the case of using the spring API interface
Using annotations
Custom section
package com.hopeful.diy; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect // Mark section public class AnnotationPointDiy { // Before advice @Before("execution(* com.hopeful.service.UserServiceImpl.*(..))") public void before() { System.out.println("Before executing the method=========="); } // Post notification @After("execution(* com.hopeful.service.UserServiceImpl.*(..))") public void after() { System.out.println("After executing the method==========="); } // Around Advice @Around("execution(* com.hopeful.service.UserServiceImpl.*(..))") // The pj connection point can obtain some methods of executing the method public void around(ProceedingJoinPoint pj) throws Throwable { System.out.println("Before surround notification========="); // The method executed is called through the connection point Object proceed = pj.proceed(); System.out.println("After surround notification========="); } }
Write the IUserService interface and implementation class UserServiceImpl. Refer to the case of using the spring API interface
configuration file
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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="annotationPointDiy"/> <bean id="userService"/> <!-- Enable annotation support--> <aop:aspectj-autoproxy/> </beans>
Test: refer to the case of using the spring API interface
The role of AOP in Spring
Provide declarative transactions: allow users to customize aspects
- Crosscutting concerns: methods or functions that span multiple modules of an application, that is, those that have nothing to do with our business logic, but that we need to focus on are crosscutting concerns, such as logging, security, caching, transactions, etc
- Aspect (aspect): a special object whose crosscutting concerns are modularized, that is, it is a class
- Advice: the aspect must do, that is, it is a method in a class.
- Target: 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
Method 1: use the Spring API interface
Method 2: Customize AOP
Method 3: use annotation
Integrating Mybatis and Spring
Review Mybatis
- Add dependency
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.10</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.10</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.7</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.6</version> </dependency> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> <scope>provided</scope> </dependency> </dependencies>
[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-IeiMa3tg-1635118396051)(Spring.assets/image-20211019193427250.png)]
Summary: our biggest scope question is between provided and runtime. Just remember one principle. If the container has jars, use provided in the project pom.xml; If you need dynamically loaded jars, use runtime. The default scope is compile
-
Create entity class
package com.hopeful.pojo; import lombok.Data; @Data public class User { private int id; private String name; private String pwd; }
-
Write core configuration file
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typeAliases> <package name="com.hopeful.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=UTF-8"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/hopeful/mapper/UserMapper.xml"/> </mappers> </configuration>
-
Write interface
package com.hopeful.dao; import com.hopeful.pojo.User; import java.util.List; public interface UserMapper { List<User> selectUser(); }
-
Write the mapper.xml file
<?xml version="1.0" encoding="UTF8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.hopeful.dao.UserMapper"> <select id="selectUser" resultType="user"> select * from user; </select> </mapper>
-
test
package com.hopeful.test; import com.hopeful.dao.UserMapper; import com.hopeful.pojo.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.ognl.security.UserMethod; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.List; public class MyTest { @Test public void selectUsers() throws IOException { String resource = "mybatisConfig.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> usersList = mapper.selectUser(); for (User user : usersList) { System.out.println(user); } } }
Integration I
-
Configure data sources
-
Configure SqlSessionFactory
-
Configure SqlSessionTemplate
<?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"> <!-- dataSource:use spring in JDBC data source --> <bean id="dataSource"> <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="root"/> </bean> <!-- SqlSessionFactory --> <bean id="sqlSessionFactory"> <property name="dataSource" ref="dataSource" /> <!-- binding mybatis configuration file --> <property name="configLocation" value="classpath:mybatisConfig.xml"/> <property name="mapperLocations" value="classpath:com/hopeful/mapper/*.xml"/> </bean> <!-- sqlSessionTemplate:That's what we use sqlSession --> <bean id="sqlSession"> <!-- <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>--> <constructor-arg index="0" ref="sqlSessionFactory"/> </bean> <!-- Register the interface implementation class to spring In container --> <bean id="userMapper"> <property name="sqlSession" ref="sqlSession"/> </bean> </beans>
-
Write interface Mapper implementation class
package com.hopeful.dao; import com.hopeful.pojo.User; import org.mybatis.spring.SqlSessionTemplate; import java.util.List; public class UserMapperImpl implements UserMapper { private SqlSessionTemplate sqlSession; public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; } public List<User> selectUser() { UserMapper mapper = sqlSession.getMapper(UserMapper.class); return mapper.selectUser(); } }
-
test
package com.hopeful.test; import com.hopeful.dao.UserMapper; import com.hopeful.pojo.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.ognl.security.UserMethod; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import javax.jws.soap.SOAPBinding; import java.io.IOException; import java.io.InputStream; import java.util.List; public class MyTest { @Test public void selectUsers() throws IOException { ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml"); UserMapper userMapper = context.getBean("userMapper", UserMapper.class); List<User> users = userMapper.selectUser(); for (User user : users) { System.out.println(user); } } }
Method 2: use SqlSessionDaoSupport
Writing implementation classes
package com.hopeful.dao; import com.hopeful.pojo.User; import org.mybatis.spring.support.SqlSessionDaoSupport; import java.util.List; // SqlSessionDaoSupport provides SqlSessionTemplate // Inheriting sqlSessionDaoSupport, you can obtain sqlSession through getSqlSession public class UserMapperImpl3 extends SqlSessionDaoSupport implements UserMapper { public List<User> selectUser() { // Call the getSqlSession() method and you will get a SqlSessionTemplate return getSqlSession().getMapper(UserMapper.class).selectUser(); } }
test
package com.hopeful.test; import com.hopeful.dao.UserMapper; import com.hopeful.pojo.User; import org.apache.ibatis.io.Resources; import org.apache.ibatis.ognl.security.UserMethod; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import javax.jws.soap.SOAPBinding; import java.io.IOException; import java.io.InputStream; import java.util.List; public class MyTest { @Test public void selectUsers() throws IOException { ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml"); UserMapper userMapper = context.getBean("userMapper3", UserMapper.class); List<User> users = userMapper.selectUser(); for (User user : users) { System.out.println(user); } } }
Mode 2:
Adding interfaces to Spring through MapperFactoryBean
<bean id="userMapper2"> <property name="mapperInterface" value="com.hopeful.dao.UserMapper" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean>
Implementation class
package com.hopeful.dao; import com.hopeful.pojo.User; import org.mybatis.spring.SqlSessionTemplate; import java.util.List; public class UserMapperImpl2 implements UserMapper { private UserMapper userMapper; public List<User> selectUser() { return userMapper.selectUser(); } }
test
@Test public void selectUsers() throws IOException { ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml"); UserMapper userMapper = context.getBean("userMapper2", UserMapper.class); List<User> users = userMapper.selectUser(); for (User user : users) { System.out.println(user); } }
Problems encountered
Invalid byte 2 of 2-byte UTF-8 sequence
This also happens when using labels.
This problem is caused by the problem of Chinese annotation in xml files. There are two solutions:
1, Delete all the Chinese comments of the xml file to solve the problem
2, Changing encoding=UTF-8 at the top of the xml file to encoding=UTF8 can solve the problem
technical skill
If you want to adjust the speed of station B at will, press f12 and click console
Enter document.querySelector("video"). playbackRate = 3;
Spring configuration file
Basic 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 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"> <property name="name" value="Hello Spring"/> </bean> </beans>
Automatic assembly 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: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 http://www.springframework.org/schema/context/spring-context.xsd"> <!-- Open use annotation --> <context:annotation-config/> <bean id="dog"/> <bean id="cat"/> <bean id="person"> <property name="name" value="Hopeful"/> </bean> </beans>
Spring annotation
@Autowired
be careful:
- You can use it directly on the attribute! It can also be used on the set method
- Using Autowired, we don't need to write a Set to make it higher, provided that your auto assembled attribute is in the IOC container and the type conforms to ByName or ByType
@Resource
This annotation integrates ByName and ByType attributes. First find the bean by ByName, and then find the bean by ByType. No error message can be found, but the bean with a specific name can be specified through the name attribute.
Same: @ Autowired and @ Resource are both used for automatic assembly and can be used on attributes
Different:
- @Autowired assembles bean s by ByType or ByName
- @The Resource is assembled by ByName first, if it cannot be found, and then by ByType. Otherwise, an error is reported, but a bean with a specific name can be specified through the name attribute
@Nullable
Starting with Spring Framework 5.0, you can also use the @ Nullable annotation
@Nullable : an annotation that represents a specific parameter, and the return value or field can be null.
@Component
Use this annotation to indicate that this class is managed by the Spring container.
@ComponentScan
@ComponentScan("packageName") tells the Spring container which annotated classes under the package are scanned and loaded into the bean container automatically!
Note: @ Configuration annotation states that the current class is a Configuration class, which is equivalent to an xml Configuration file@ The reason why ComponentScan and @ Configuration are used together is based on the annotation in spring 2.0 and the implementation of xml Configuration file, that is, configure ComponentScan package scanning properties in xml Configuration file.
If one of the four annotation identifiers @ Controller, @ Repository, @ service and @ component is used in the class, Spring will not automatically scan any of the four annotations on the class if @ ComponentScan is not added, and the classes under the four annotations will not be scanned by Spring, let alone loaded into the Spring container. Therefore, the four annotations you configured will lose their function.