Spring
Spring is a lightweight open source framework for layered Java SE/EE application full stack, with IOC (flip control) and AOP (aspect oriented programming) as the kernel
It provides many enterprise application technologies such as presentation layer spring MVC, persistence layer spring JDBC template and business layer transaction management. It can also integrate many third-party frameworks and class libraries in the open source world, and gradually become the most used open source framework for Java EE enterprise applications
1. Convenient decoupling and simplified development
Through the IOC container provided by Spring, the dependencies between objects can be controlled by Spring to avoid multiple coupling caused by hard coding. Users do not have to write code for the underlying requirements such as singleton mode and property file parsing, and can focus more on the application of the upper layer
2. AOP programming support
Through the AOP function of Spring, it is convenient for aspect oriented programming. Many functions that are not easy to be realized with traditional OOP can be easily realized through AOP
3. Declarative transaction support
It can free us from the monotonous and boring transaction agent code, and improve the development efficiency and quality through declarative and flexible transaction management
4. Facilitate program testing
You can use container independent programming to do almost all the testing work you want. Testing is no longer an expensive operation, but something you can do easily
5. It is convenient to inherit various excellent frameworks
Spring's support for various excellent frameworks (Struts, Hibemate, Hessian, Quartz, etc.)
6. Reduce the difficulty of using Java EE API
Spring encapsulates Java EE API s (JDBC, JavaMail, remote call, etc.), which greatly reduces the difficulty of using these APIs
7. Java source code is a classic learning example
Spring has exquisite source code design, clear structure and unique ingenuity, which everywhere reflects the master's flexible use of Java design patterns and his profound attainments in Java technology
1. Import the coordinates of the basic package developed by Spring
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.7</version> </dependency></dependencies>
2. Write Dao interface and implementation class
UserDao interface
package com.zg.dao; public interface UserDao { public void save(); }
UserDao implementation class
package com.zg.dao.impl; import com.zg.dao.UserDao; public class userDaoIMPL implements UserDao { @Override public void save() { System.out.println("save running....."); } }
3. Create Spring core 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"> <bean id="userDao"></bean> </beans>
4. Configure UserDaoImpl in the Spring configuration file
<bean id="userDao"></bean>
5. Use Spring's API to get Bean instances
package com.zg.demo; import com.zg.dao.UserDao; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.GenericApplicationContext; public class UserDaoDemo { public static void main(String[] args) { ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao)app.getBean("userDao"); userDao.save(); } }
Spring configuration file details
Bean tag basic configurationThe configuration object is created by Spring
By default, it calls the parameterless constructor in the class. If there is no parameterless constructor, it cannot be created successfully
id: the unique identifier of the Bean instance in the Spring container
class: the fully qualified name of the Bean
Scope: scope of instruction object
1. When the scope value is singleton < bean id = "userdao" class = "com. ZG. Dao. Impl. Userdaoimpl" scope = "Singleton" > < / bean >
The number of instantiations of Bean is 1
Bean instantiation timing: instantiate the configured bean instance when the Spring core file is loaded
Declaration cycle of Bean:
Object creation: when the application loads and creates a container, the object is created
Object running: the object remains alive as long as the container is
Object destruction: when the application is unloaded and the container is destroyed, the object is destroyed
2. When the value of scope is prototype, < bean id = "userdao" class = "com. ZG. Dao. Impl. Userdaoimpl" scope = "prototype" > < / bean >
There are multiple instantiations of beans
Bean instantiation timing: instantiate the configured bean instance when calling the getBean() method
Declaration cycle of Bean:
Object creation: creates a new object instance when using an object
Object running: as long as the object is in use, the object remains alive
Object destruction: the object is not used for a long time and is recycled by the Java garbage collector
<bean id="userDao" init-method="init" destroy-method="destroy"></bean>
Init method: Specifies the name of the initialization method in the class
Destroy method: Specifies the name of the destroy method in the class
1. Parameterless construction method instantiation
The above methods are instantiated by parameterless construction methods
public class userDaoIMPL implements UserDao { public userDaoIMPL() { } }
<!--Creating methods using parameterless constructs--> <bean id="userDao" ></bean>
2. Factory static method instantiation
package com.zg.factory; import com.zg.dao.UserDao; import com.zg.dao.impl.userDaoIMPL; //Factory static method instantiation public class StaticFactory { public static UserDao getUserDao(){ return new userDaoIMPL(); } }
<bean id="userDao" factory-method="getUserDao"></bean>
When obtaining the full class name, you can right-click its name and select Copy Reference
3. Factory instance method instantiation, many
<!--Let's go first Spring A factory object container is generated, and then a method inside the factory is invoked.--> <bean id="factory"></bean> <!--Generated by id="factory"Factory object container to find getUserDao This method--> <bean id="userDao" factory-bean="factory" factory-method="getUserDao"></bean>
package com.zg.factory; import com.zg.dao.UserDao; import com.zg.dao.impl.userDaoIMPL; //Factory static method instantiation public class StaticFactory { public static UserDao getUserDao(){ return new userDaoIMPL(); } }Spring configuration file Create a service layer without using Spring
When we do not use Spring, in the service layer, we need to rewrite the save() method in UserService through the UserServiceImpl implementation class, and then call the save method to get the UserDaoImpl object of UserDao implementation class in the Dao layer (the business layer save calls the Spring layer), and then go through the UserDao = Get the service to implement the specific business of Dao layer, because the service layer is not configured in the spring container.
1. Create UserService and call the save() method of UserDao inside UserServie
package com.zg.service.impl; import com.zg.dao.UserDao; import com.zg.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserServiceImpl implements UserService { @Override public void save() { //UserService wants to call UserDao, but now UserDao has been generated in Spring ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao)app.getBean("userDao"); userDao.save(); } }
2. The web layer does not use Spring to encapsulate service s
package com.zg.demo; import com.zg.service.UserService; import com.zg.service.impl.UserServiceImpl; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserController { //Its internal needs to get Service public static void main(String[] args) { //Do not use Spring to encapsulate service s UserService userService = new UserServiceImpl(); userService.save(); } }Configure the service layer into the Spring container as well
1. Give Spring the right to create UserServiceImpl in the configuration file applicationContext.xml
<bean id="userService"></bean>
2. Obtain UserService from Spring container for operation
package com.zg.demo; import com.zg.service.UserService; import com.zg.service.impl.UserServiceImpl; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserController { //Its internal needs to get Service public static void main(String[] args) { //Encapsulating service s with Spring ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) app.getBean("userService"); userService.save(); } }problem analysis
At present, both UserSrvice instance and UserDao instance exist in Spring. The current practice is to obtain UserService instance and UserDao instance outside the container, and then combine them in the program
Because both UserService and UserDao are in the Spring container, and the final program directly uses UserService, you can set UserDao inside UserService in the Spring container
Dependency Injection: it is the concrete implementation of the Spring framework core IOC
When writing the program, the creation of objects is handed over to Spring through control inversion, but there can be no dependency in the code.
IOC decoupling only reduces the relationship between them, but it will not be eliminated (the business layer will still call the methods of the persistence layer)
The dependency between the business layer and the persistence layer is maintained using Spring after using Spring, that is, the framework passes the persistence layer object into the business layer without us obtaining it
Dependency injection method of BeanInjecting UserDao into UserService can be realized through parameterized construction method and set method
set method injection (injection object)1. Add setUserDao method in UserServiceImpl
package com.zg.service.impl; import com.zg.dao.UserDao; import com.zg.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserServiceImpl implements UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void save() { /* //UserService I want to call UserDao, but now UserDao has been generated in Spring ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao)app.getBean("userDao");*/ //We don't need to get Dao from the container, because Dao has been injected into the service through the set method inside the container userDao.save(); } }
2, configure the Spring container to invoke the set method to inject.
<bean id="userDao" ></bean> <bean id="userService"> <!--there name Is the name of the attribute, that is (the method operates on the value of the member variable) set,The remaining attributes with lowercase initials are service Corresponding property name in--> <!--Here, the reference of the object is used ref--> <!--Put the in the container userDao adopt userService Internal setUserDao This method is injected into userService--> <property name="userDao" ref="userDao"></property> </bean>
However, you can't create a new UserService in the web layer because it doesn't get the injection of UserDao, so you can only use the service encapsulated by Spring to call dao's methods in the web layer
Simple method of set method injection – > P namespace injectionThe essence of P namespace injection is also set method injection, but it is more convenient than the above set method injection, which is mainly reflected in the configuration file
xmlns:p="http://www.springframework.org/schema/p"
Then replace the following code 1 with code 2
Code 1:
<bean id="userDao" ></bean> <bean id="userService"> <!--there name Is the name of the attribute, that is (the method operates on the value of the member variable) set,The remaining attributes with lowercase initials--> <!--Here, the reference of the object is used ref--> <!--Put the in the container userDao adopt userService Internal setUserDao This method is injected into userService--> <property name="userDao" ref="userDao"></property> </bean>
Code 2:
<bean id="userService" p:userDao-ref="userDao"></bean>Structural injection (parametric structure)
1. Create parametric structure
package com.zg.service.impl; import com.zg.dao.UserDao; import com.zg.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserServiceImpl implements UserService { private UserDao userDao;//Parametric structure public UserServiceImpl(UserDao userDao) { this.userDao = userDao; } public UserServiceImpl() {//Nonparametric structure } @Override public void save() { //We don't need to get Dao from the container, because Dao has been injected into the service through the set method inside the container userDao.save(); } }
2. Construction method injection
<bean id="userDao" ></bean> <!--If not used constructor-arg A parameterless constructor will be found, so service None of them dao--> <bean id="userService"> <!--So here is the parameter name inside the structure, ref Representative reference bean Container id--> <constructor-arg name="userDao" ref="userDao"></constructor-arg> </bean>Data type of Bean dependency injection
Both set and parameterized construction methods are injected reference beans. In addition to object references, ordinary data types and collections can be injected in the container
Three data types of injected data
Common data type
Reference data type
Collection data type
package com.zg.dao.impl; import com.zg.dao.UserDao; public class userDaoImpl implements UserDao { private String username; private int age; public void setUsername(String username) { this.username = username; } public void setAge(int age) { this.age = age; } @Override public void save() { System.out.println(username+"===="+age); System.out.println("save runningg....."); } }
<bean id="userDao" > <!--ref For object reference, while normal data type injection is used value--> <property name="username" value="Bob"></property> <property name="age" value="18"></property> </bean>Injection of collection data types
package com.zg.dao.impl; import com.zg.dao.UserDao; import com.zg.domain.User; import java.util.List; import java.util.Map; import java.util.Properties; public class userDaoImpl implements UserDao { private List<String> strList; private Map<String, User> userMap; private Properties properties; public void setStrList(List<String> strList) { this.strList = strList; } public void setUserMap(Map<String, User> userMap) { this.userMap = userMap; } public void setProperties(Properties properties) { this.properties = properties; } private String username; private int age; public void setUsername(String username) { this.username = username; } public void setAge(int age) { this.age = age; } @Override public void save() { //System.out.println(username+"===="+age); System.out.println("save runningg....."); System.out.println(strList); System.out.println(userMap); System.out.println(properties); } }
<bean id="userDao" > <!--Not here ref No value--> <property name="strList" > <!--stay list What we define in the set is String It is an ordinary number type, so it is used in it value--> <!--But if list Defined in the collection Bean Then use ref--> <list><value>aaa</value> <value>bbb</value> <value>ccc</value> </list> </property> <property name="userMap"> <!--map The set has keys and values, so write entry--> <map> <!--stay userDaoImpl in key Is a normal data type, and value yes user Object (reference data type)--> <!--here value-ref Is a reference, so reference data type injection is required--> <entry key="u1" value-ref="user1"></entry> <entry key="u2" value-ref="user2"></entry> </map> </property> <property name="properties"> <props> <prop key="p1" >ppp1</prop> <prop key="p2" >ppp3</prop> <prop key="p3" >ppp4</prop> </props> </property> </bean> <bean id="user1"> <property name="name" value="Alice"></property> <property name="addr" value="Beijing"></property> </bean> <bean id="user2"> <property name="name" value="Mallry"></property> <property name="addr" value="Xi'an"></property> </bean>
user prepared in Map collection
package com.zg.domain; public class User { private String name; private String addr; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", addr='" + addr + '\'' + '}'; } }Introduce other configuration files (sub module development)
In actual development, there are many Spring configurations, which leads to the complexity and volume of Spring configuration. Therefore, some configurations can be disassembled into other configuration files, and loaded in the Spring main configuration file through the import tag
<import resource="applicationConext-user.xml"></import> <import resource="applicationConext-product.xml"></import>
If the constructor reference is used instead of set method injection, the configuration of the tag is the same as that inside the tag.
Spring related API s
Inheritance system of ApplicationContextapplicationContext: interface type, which represents the application context. Bean objects in the Spring container can be obtained through its instance
1. ClassPathXmlApplicationContext: it is recommended to load configuration files from the root path of the class
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
2. FileSystemXmlApplicationContext: load the configuration file from the disk path. The configuration file can be anywhere on the disk
Right click the project name and select Copy path to copy the path of the file on the disk
FileSystemXmlApplicationContext fileSystemXmlApplicationContext = new FileSystemXmlApplicationContext("D:\\java\\Spring\\src\\main\\resources\\applicationContext.xml");
3. AnnotationConfigApplicationContext: when configuring container objects with annotations, you need to use this class to create a spring container to read annotations
Use of getBean() methodUse ID: UserService userService = (UserService) app.getBean("userService"); Bean s of the same type are allowed in the container
Type of bytecode used: UserService userService1 = app.getBean(UserService.class);
Where, when the data type of the parameter is a string, it means that the Bean instance is obtained from the container according to the Bean id, and the return is Object, which needs to be forced. When the data type of the parameter is Class, it means that Bean instances are matched from the container according to the type. When there are multiple beans of the same type in the container, this method will report an error.