Tip: after the article is written, the directory can be generated automatically. Please refer to the help document on the right for how to generate it
preface
❤️ 1, Spring overview
🥇 1.1 INTRODUCTION
- Spring: Spring - > brings spring to the software industry
- In 2002, Rod Jahnson first launched the Spring framework prototype interface21 framework.
- On March 24, 2004, the Spring framework was redesigned based on the interface 21 framework and released the official version of 1.0.
- It's hard to imagine Rod Johnson's degree. He is a doctor at the University of Sydney. However, his major is not computer, but musicology.
- Spring concept: make the existing technology more practical Itself is a hodgepodge, integrating existing framework technologies
Official website: http://spring.io/
Official download address: https://repo.spring.io/libs-release-local/org/springframework/spring/
GitHub: https://github.com/spring-projects
🥇 1.2 advantages
-
Spring is an open source free framework, container
-
Spring is a lightweight framework, non - intrusive
-
Control inversion IoC, facing section Aop
-
Support for things, support for frameworks
-
In one sentence: Spring is a lightweight container (framework) for inversion of control (IoC) and aspect oriented (AOP).
🥇 1.3 composition
The spring framework is a layered architecture consisting of seven well-defined modules. Spring module is built on the core container, which defines the way to create, configure and manage bean s
Each module (or component) that makes up the Spring framework can exist alone or be implemented jointly with one or more other modules. The functions of each module are as follows:
- Core container: the core container provides the basic functions of the Spring framework. The main component of the core container is BeanFactory, which is the implementation of the factory pattern. BeanFactory uses the inversion of control (IOC) pattern to separate the configuration and dependency specifications of the application from the actual application code.
- Spring context: a spring context is a configuration file that provides context information to the spring framework. The spring context includes enterprise services such as JNDI, EJB, e-mail, internationalization, checksum and scheduling capabilities.
- Spring AOP: through the configuration management feature, the spring AOP module directly integrates aspect oriented programming functions into the spring framework. Therefore, you can easily make the spring framework manage any object that supports AOP. The spring AOP module provides transaction management services for objects in spring based applications. By using spring AOP, declarative transaction management can be integrated into applications without relying on components.
- Spring DAO: the JDBC DAO abstraction layer provides a meaningful exception hierarchy that can be used to manage exception handling and error messages thrown by different database vendors. The exception hierarchy simplifies error handling and greatly reduces the amount of exception code that needs to be written (such as opening and closing connections). Spring DAO's JDBC oriented exceptions follow a common DAO exception hierarchy.
- Spring ORM: the spring framework inserts several ORM frameworks to provide ORM object relationship tools, including JDO, Hibernate and iBatis SQL Map. All of this follows spring's common transaction and DAO exception hierarchy.
- Spring Web module: the Web context module is built on the application context module and provides context for web-based applications. Therefore, the spring framework supports integration with Jakarta Struts. The web module also simplifies processing multipart requests and binding request parameters to domain objects.
- Spring MVC framework: the MVC framework is a fully functional MVC implementation for building Web applications. Through the policy interface, the MVC framework becomes highly configurable. MVC accommodates a large number of view technologies, including JSP, Velocity, Tiles, iText and POI.
🥇 1.4 expansion
Spring Boot and Spring Cloud
- Spring Boot is a set of rapid configuration scaffolds of spring, which can quickly develop a single microservice based on Spring Boot;
- Spring Cloud is implemented based on Spring Boot;
- Spring Boot focuses on a single micro service individual that is fast and easy to integrate. Spring Cloud focuses on the overall service governance framework;
- Spring Boot uses the concept that constraints are better than configuration. Many integration schemes have been selected for you. You can't configure without configuration. A large part of Spring - Cloud is implemented based on Spring Boot. Spring Boot can use development projects independently of Spring Cloud, but Spring Cloud is inseparable from Spring Boot and belongs to dependency.
- SpringBoot plays a connecting role in SpringClound. If you want to learn spring cloud, you must learn SpringBoot.
❤️ 2, IoC Foundation
🥇 2.1 analysis and Implementation
Let's write a piece of code in our original way
- First write a UserDao interface
public interface UserDao { public void getUser(); }
- Then write Dao's implementation class
public class UserDaoImpl implements UserDao { @Override public void getUser() { System.out.println("Get user data"); } }
- Then write the UserService interface
public interface UserService { public void getUser(); }
- Finally, write the implementation class of Service
public class UserServiceImpl implements UserService { private UserDao userDao = new UserDaoImpl(); @Override public void getUser() { userDao.getUser(); } }
- Test it
@Test public void test(){ UserService service = new UserServiceImpl(); service.getUser(); }
This is our original way. At first, everyone wrote it like this, right Let's revise it now
- Add an implementation class of Userdao
public class UserDaoMySqlImpl implements UserDao { @Override public void getUser() { System.out.println("MySql Get user data"); } }
- Next, if we want to use MySql, we need to modify the corresponding implementation in the service implementation class
public class UserServiceImpl implements UserService { private UserDao userDao = new UserDaoMySqlImpl(); @Override public void getUser() { userDao.getUser(); } }
- In the assumption, we add another Userdao implementation class
public class UserDaoOracleImpl implements UserDao { @Override public void getUser() { System.out.println("Oracle Get user data"); } }
We need to modify the Oracle class to implement it Assuming that our demand is very large, this method is not applicable at all, even anti-human, right? Every change requires a lot of code modification The coupling of this design is so high that it will affect the whole body
How can we solve it?
Instead of implementing it, we can set aside an interface where we need it. Using set, we can modify it in the code
public class UserServiceImpl implements UserService { private UserDao userDao; // Using set public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void getUser() { userDao.getUser(); } }
Now go to our test class and test;
@Test public void test(){ UserServiceImpl service = new UserServiceImpl(); service.setUserDao( new UserDaoMySqlImpl() ); service.getUser(); //So now we want to use Oracle to implement it service.setUserDao( new UserDaoOracleImpl() ); service.getUser(); }
Fundamental changes have taken place and many places are different Think about it carefully. In the past, everything was controlled and created by the program, but now we control and create the object ourselves and give the initiative to the caller The program doesn't have to worry about how to create and implement it It is only responsible for providing one interface This idea essentially solves the problem. Our programmers no longer manage the creation of objects, but pay more attention to the implementation of business The coupling is greatly reduced This is the prototype of IOC!
🥇 2.2 IOC essence
Inversion of control (IoC) is a design idea. DI (dependency injection) is a method to realize IoC. Some people think that DI is just another way of saying IoC. In programs without IoC, we use object-oriented programming. The creation of objects and the dependencies between objects are completely hard coded. In programs, the creation of objects is controlled by the program itself. After the control is reversed, the creation of objects is transferred to a third party. Personally, I think the so-called control reversal is the reversal of the way to obtain dependent objects.
IoC is the core content of the Spring framework. IoC is perfectly implemented in a variety of ways. You can use XML configuration or annotations. The new version of Spring can also implement IoC with zero configuration.
During initialization, the Spring container reads the configuration file first, creates and organizes objects according to the configuration file or metadata, and stores them in the container. When the program is used, it takes out the required objects from the Ioc container.
When configuring a Bean in XML, the definition information of the Bean is separated from the implementation, and the annotation method can integrate the two. The definition information of the Bean is directly defined in the implementation class in the form of annotation, so as to achieve the purpose of zero configuration.
Inversion of control is a way to produce or obtain specific objects through description (XML or annotation) and through a third party. In Spring, the IoC container implements control inversion, and its implementation method is dependency injection (DI).
❤️ 3, Hello spring
🥇 3.1. Import Jar package
Note: spring needs to import commons logging for logging We use maven, which will automatically download the corresponding dependencies
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.10.RELEASE</version> </dependency>
🥇 3.2. Code writing
Write a Hello entity class
public class Hello { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public void show(){ System.out.println("Hello,"+ name ); } }
Write our spring file, here we name it 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 namely java object , from Spring Create and manage--> <bean id="hello" class="com.kuang.pojo.Hello"> <property name="name" value="Spring"/> </bean> </beans>
We can go and test
@Test public void test(){ //Parse beans XML file to generate and manage the corresponding Bean objects ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //getBean: the parameter is the id of the bean in the spring configuration file Hello hello = (Hello) context.getBean("hello"); hello.show(); }
🥇 3.3 thinking
- Who created the hello object? [the hello object is created by Spring]
- How are the properties of the Hello object set? [the properties of the Hello object are set by the Spring container]
This process is called control reversal:
Control: who controls the creation of objects? Traditional application objects are created by the program itself. After using Spring, objects are created by Spring
Inversion: the program itself does not create an object, but becomes a passive receiving object
Dependency injection: it uses the set method to inject
IOC is a programming idea, from active programming to passive reception
You can browse the underlying source code through newClassPathXmlApplicationContext
🥇 3.4. Modify case 1
In case 1, we add a Spring 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="MysqlImpl" class="com.kuang.dao.impl.UserDaoMySqlImpl"/> <bean id="OracleImpl" class="com.kuang.dao.impl.UserDaoOracleImpl"/> <bean id="ServiceImpl" class="com.kuang.service.impl.UserServiceImpl"> <!--be careful: there name Is not an attribute , But set The part behind the method , Initial lowercase--> <!--Reference another bean , Not with value But with ref--> <property name="userDao" ref="OracleImpl"/> </bean> </beans>
Test!
@Test public void test2(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserServiceImpl serviceImpl = (UserServiceImpl) context.getBean("ServiceImpl"); serviceImpl.getUser(); }
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!
❤️ 4, Spring configuration file
🥇 4.1 Bean tag range configuration
Scope: refers to the scope of the object. The values are as follows:
Value range | explain |
---|---|
singletion | Default, singleton |
prptotype | Multiple cases |
request | In the WEB project, Spring creates a JavaBean object and stores the object in the request field |
session | In the WEB project, Spring creates a JavaBean object and stores the object in the session domain |
global session | In the WEB project, it is applied in the Portlet environment. If there is no Portlet environment, the global session is equivalent to the session |
🏅 4.1.1 when the value of scope is singleton
Number of instantiations of Bean: 1
Bean instantiation timing: instantiate the configured bean instance when the Spring core file is loaded
Bean lifecycle:
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 unloads and destroys the container, the object is destroyed
🏅 4.1.2 when the value of scope is prototype
Number of Bean instantiations: multiple
Instantiation time of Bean: instantiate Bean when calling getBean0 method
Object creation: creates a new object instance when using an object
Object running: as long as the object is in use, it will always be alive
Object destruction: when an object is not used for a long time, it is recycled by the Java garbage collector
🏅 4.1.3 when the value of scope is Request
When the scope of a bean is Request, it means that in an HTTP Request, a bean definition corresponds to an instance; That is, each HTTP Request will have its own bean instance, which is created according to a bean definition. This scope is only valid in the case of web-based Spring ApplicationContext. Consider the following bean definitions:
<bean id="loginAction" class=cn.csdn.LoginAction" scope="request"/>
For each HTTP request, the Spring container will create a new loginaction bean instance according to the loginaction bean definition, and the loginaction bean instance is only valid in the current HTTP request. Therefore, you can safely change the internal state of the created instance according to the needs, while the instances created according to the loginaction bean definition in other requests, You will not see these state changes specific to a request. When the processing of the request ends, the bean instance of the request scope will be destroyed.
🏅 4.1.3 when the value of scope is Session
When the scope of a bean is Session, it means that in an HTTP Session, a bean definition corresponds to an instance. This scope is only valid in the case of web-based Spring ApplicationContext. Consider the following bean definitions:
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>
For an HTTP Session, the Spring container will create a new userPreferences bean instance according to the userPreferences bean definition, and the userPreferences bean is only valid in the current HTTP Session. Like the request scope, you can safely change the internal state of the created instance as needed. For instances created according to userPreferences in other HTTP sessions, you will not see these state changes specific to an HTTP Session. When the HTTP Session is finally discarded, the beans within the scope of the HTTP Session will also be discarded.
🥇 4.2 three methods of bean instantiation
- Parameterless construction method instantiation
bean namely java object , from Spring Create and manage Type variable name = new Type (); Hello hello = new Hello(); id = Variable name class = new Object of: property Equivalent to setting a value for a property in an object First: <bean id="user" class="com.vector.pojo.User"> <constructor-arg index="0" value="Chen Siyu"/> </bean> Second: <bean id="UserDao" class="com.vector.dao.Impl.UserDaoImpl"> </bean>
- Factory static method instantiation
<bean id="UserDao" class="com.vector.factory.StaticFactory" factory-method="getUserDao"/>
- Factory instance method instantiation
<bean id="factory" class="com.vector.factory.DynamicFactory"/> <bean id="UserDao" factory-method="getUserDao" factory-bean="factory"/>
🥇 Dependency injection analysis of 4.3 bean
At present, both UserService instances and UserDao instances exist in the Spring container. The current practice is to obtain UserService instances and UserDao instances outside the container, and then combine them in the program.
🥇 4.4 dependency injection concept of bean
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 their dependencies, but it will not eliminate them. For example, the business layer will still call the methods of the persistence layer.
After using Spring, Spring can maintain the dependency between the business layer and the persistence layer.
Simply put, it means waiting for the framework to transfer the persistence layer object to the business layer without getting it ourselves.
🥇 4.5 how to inject UserDao into UserService?
- Construction method:
public class UserDaoImpl implements UserDao { public UserDaoImpl() { System.out.println("UserDaoImpl Created..."); } @Override public void save() { System.out.println("save running..."); } }
<bean id="UserDao" class="com.vector.dao.Impl.UserDaoImpl"> </bean>
@Test public void test(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("TestBeans.xml"); UserService userService = (UserService)context.getBean("UserService"); userService.save(); context.close(); }
- set method:
General injection:
public class UserServiceImpl implements UserService { private UserDao userDao; public void setUserDao(UserDao userDao){ this.userDao = userDao; } @Override public void save() { userDao.save(); } }
<bean id="userDao" class="com.vector.dao.Impl.UserDaoImpl" /> <bean id="UserService" class="com.vector.service.Impl.UserServiceImpl"> <property name="userDao" ref="userDao"/> </bean>
@Test public void test(){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("TestBeans.xml"); UserService userService = (UserService)context.getBean("UserService"); userService.save(); context.close(); }
P namespace injection:
The essence is also set injection, but it is more convenient than the above set injection. The main experience is in the configuration file, as follows: first, introduce the namespace:
xmlns:p="http : / / waww . springframework.orgl schema/p"
Secondly, the injection method needs to be modified
<bean id="userService" class=" com.itheima.service .impl .UserserviceImpl" p:userDao-ref-"userDao" />
🥇 4.6 data types of bean dependency injection
The above operations are all 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.
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 running..."); }
<bean id="userDao" class="com.vector.dao.Impl.UserDaoImpl"> <property name="username" value="Xiao Qi"/> (Common data type.) <property name="age" value="18"/> </bean> <bean id="UserService" class="com.vector.service.Impl.UserServiceImpl"> <property name="userDao" ref="userDao"/> </bean>
Reference data type.
Collection data type.
public class User { private String name; private String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
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; } @Override public void save() { System.out.println(strList); System.out.println(userMap); System.out.println(properties); System.out.println("save running..."); } }
<bean id="userDao" class="com.vector.dao.Impl.UserDaoImpl"> <property name="strList"> <list> <value>Demo1</value> <value>Demo2</value> <value>Demo3</value> </list> </property> <property name="userMap"> <map> <entry key="user1" value-ref="user1"></entry> <entry key="user1" value-ref="user2"></entry> </map> </property> </bean> <bean id="user1" class="com.vector.domain.User"> <property name="name" value="tom"/> <property name="address" value="Xiguan Village"/> </bean> <bean id="user2" class="com.vector.domain.User"> <property name="name" value="tony"/> <property name="address" value="Dongguan Village"/> </bean> <bean id="UserService" class="com.vector.service.Impl.UserServiceImpl"> <property name="userDao" ref="userDao"/> </bean>
🥇 4.7 introduction of 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="applicationcontext one xxx. xml"" / >
🥇 4.8 key configuration of spring
<bean>label id attribute:In container Bean Unique ID of the instance. Duplicate is not allowed class attribute:To instantiate Bean Fully qualified name of scope attribute:Bean The scope of action is singleton (default)and prototype <property>label:Attribute injection name attribute:Attribute name value attribute:Injected common attribute values ref attribute:Injected object reference value <list>label <map>label <properties>label <constructor-arg>label <import>label:Import other spring Sub document of
❤️ 5, Spring related API s
ApplicationContext Inheritance System 1.5
applicationContext: interface type, which represents the application context. You can obtain the Bean object in the Spring container through its instance
5.2 implementation class of ApplicationContext
1)ClassPathXmlApplicationContext
It loads the configuration file from the root path of the class. This is recommended
2) FileSystemXmlApplicationContext
It loads the configuration file from the disk path. The configuration file can be anywhere on the disk.
3) AnnotationConfigApplicationContext
When configuring container objects with annotations, you need to use this class to create spring containers. It is used to read annotations.
5.3 use of getBean () method
public object getBean (string name) throws BeansException { assertBeanFactoryActive (); return getBeanFactory().getBean (name) ; } public <T> T getBean(Class<T> requiredType) throws BeansException { assertBeanFactoryActive () ; return getBeanFactory().getBean(requiredType) ; }
5.4 key points of knowledge
Key API s of Spring
ApplicationContext app = new classpathXmlApplicationcontext ( "xm1 file") app.getBean ( "id") app.getBean(class)
❤️ 6, Spring configuration data source
🥇 6.1 role of data source (connection pool)
- Data source (connection pool) is the key to improve program performance, such as
- Instantiate the data source in advance and initialize some connection resources
- Get from data source when using connection resources
- Return the connected resources to the data source after use
Common data sources (connection pool): DBCP, C3P0, BoneCP, Druid, etc.
🥇 6.2 development steps of data source
- Import the coordinates of the data source and database driven coordinates
- Create data source object
- Set the basic connection data of the data source
- Use the data source to obtain connection resources and return connection resources
🥇 6.3 spring configuration data source
First, in POM XML import dependency
<dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.11</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.9</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.12</version> </dependency> </dependencies
According to the parameters after set
applicantionContext. Configuration in XML
<bean id="DataSourceTest" class="com.alibaba.druid.pool.DruidDataSource"> <property name="DriverClassName" value="com.mysql.cj.jdbc.Driver"></property> <property name="Url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&charac terEncoding=UTF-8&serverTimezone=Asia/Shanghai& rewriteBatchedStatements=true"></property> <property name="Username" value="root"></property> <property name="Password" value="123456"></property> </bean>
Test code:
//Test spring container to create druid data source public void test1() throws Exception { ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); DataSource bean = app.getBean(DataSource.class); Connection connection = bean.getConnection(); System.out.println(connection); }
🥇 6.4 extracting jdbc files
applicationContext. Loading jdbc.xml Get the connection information from the properties configuration file.
First, you need to introduce the context namespace and constraint path:
- Namespace: xmIns:context=“ http://www.springframework.org/schema/context ”
- Constraint path: http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
configuration file driverClassName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/mybatis?useSSL=false &useUnicode=true &characterEncoding=UTF-8 &serverTimezone=Asia/Shanghai &rewriteBatchedStatements=true &allowPublicKeyRetrieval=true name=root password=123456
<?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"> <!-- Load external propere configuration file--> <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="DataSourceTest" class="com.alibaba.druid.pool.DruidDataSource"> <property name="DriverClassName" value="${driverClassName}"></property> <property name="Url" value="${url}"></property> <property name="Username" value="${name}"></property> <property name="Password" value="${password}"></property> </bean> </beans>
6.4.1 key points of knowledge
The Spring container loads the properties file
<context:property-placeholder location="xx.properties" /> <property name=" " value="$ ikey} " />
❤️ 7, Spring annotation development
7.1 spring original annotation
Spring is a light code and heavy configuration framework. The configuration is heavy and affects the development efficiency. Therefore, annotation development is a trend. Annotation instead of xml configuration file can simplify the configuration and improve the development efficiency.
Spring's original annotations are mainly used to replace the configuration of < bean >
annotation | explain |
---|---|
@Component | Used on classes to instantiate beans |
@Controller | Use to instantiate beans on web tier classes |
@Service | Used on the service layer class to instantiate beans |
@Repository | Used on dao layer classes to instantiate beans |
@Autowired | Use on field for type dependent injection |
@Qualifier | Used in conjunction with @ Autowired for dependency injection by name |
@Resource | Equivalent to @ Autowired +@Qualifier, injected by name |
@Value | Inject common attributes |
@Scope | Label the scope of the Bean |
@ PostConstruct | Use to label the method, which is the initialization method of the Bean |
@PreDestroy | Use to mark the method as the Bean's destruction method |
Original method
<?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"> <!--take userDao and UserService Inject into container--> <bean id="userDao" class="com.vector.dao.impl.UserDaoimpl"></bean> <bean id="UserService" class="com.vector.service.impl.UserServiceimpl"> <property name="userDao" ref="userDao"></property> </bean> </beans>
Test:
When developing with annotations, you need to use the application context Component scanning is configured in XML to specify which package and beans under its sub packages need to be scanned in order to identify classes, fields and methods configured with annotations. Vernacular is to tell what the annotation is and help you create objects
<!--Component scanning of master solution-> <context : component-scan base-package=" com.itheima"></context : component-scan>
Then add the following modifications to the code block
7.2Spring new notes
The above annotations cannot completely replace the xml configuration file. The configurations that need to be replaced by annotations are as follows:
- Configuration of non custom beans:
- Load the configuration of the properties file:
- Configuration of component scanning:
- Introduce other files: insert code snippets here
annotation | explain |
---|---|
@Configuration | Used to specify that the current class is a Spring configuration class from which annotations will be loaded when creating a container |
@ComponentScan | Used to specify the packages that Spring will scan when initializing the container. The function is the same as < contextcomponent scan base package = "com. Itheima" / > in the xml configuration file of Spring |
@Bean | On a method, annotations store the return value of the method in the Spring container |
@PropertySource | For loading Configuration in the properties file |
@lmport | Used to import other configuration classes |
@Import({DataSourceSpringConfiguration.class,XXX.class})//Introduce other annotation classes
Because the annotation has replaced the XML configuration file of Spring, the following modifications need to be made in the main function
public class UserController { public static void main(String[] args) { // ApplicationContext ap = new ClassPathXmlApplicationContext("applicationContext.xml"); AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class); UserService bean = app.getBean(UserService.class); bean.save(); } }
❤️ 8, AOP Foundation
8.1AOP introduction
AOP (Aspect Oriented Programming) means: Aspect Oriented Programming, which realizes the unified maintenance of program functions through precompiled mode and runtime dynamic agent. AOP is the continuation of OOP, a hot spot in software development, an important content in Spring framework, and a derivative paradigm of functional programming. AOP can isolate each part of business logic, reduce the coupling between each part of business logic, improve the reusability of program, and improve the efficiency of development.
Popular Description: add new functions to the main functions without changing the source code.
8.1AOP bottom layer principle
The underlying mechanism of AOP is dynamic agent!
Proxy mode:
- Static proxy
- Dynamic agent
Before learning aop, we should first understand the agent mode!
1.1 static agent
Static agent role analysis
-
Abstract role: generally implemented using interfaces or abstract classes
-
Real role: the role represented
-
Agent role: agent real role; After representing a real role, you usually do some ancillary operations
-
Customer: use the agent role to perform some operations
code implementation
Rent: java Abstract role
//Abstract role: rent a house public interface Rent { public void rent(); }
Host . java is the real role
//Real role: landlord, the landlord wants to rent the house public class Host implements Rent{ public void rent() { System.out.println("House rental"); } }
Proxy . java is the proxy role
//Agent role: Intermediary public class Proxy implements Rent { private Host host; public Proxy() { } public Proxy(Host host) { this.host = host; } //Rent a house public void rent(){ seeHouse(); host.rent(); fare(); } //House viewing public void seeHouse(){ System.out.println("Show the tenant"); } //Intermediary fee public void fare(){ System.out.println("Intermediary fee"); } }
Client . java is the customer
//Customers, general customers will find agents! public class Client { public static void main(String[] args) { //The landlord wants to rent a house Host host = new Host(); //The intermediary helps the landlord Proxy proxy = new Proxy(host); //You go to the agency! proxy.rent(); } }
Analysis: in this process, you are in direct contact with an intermediary, just like in real life. You can't see the landlord, but you still rent the landlord's house through an agent. This is the so-called agent model. The program comes from life, so people who learn programming can generally look at what happens in life more abstractly.
Benefits of static agents:
-
It can make our real role more pure Stop paying attention to some public things
-
Public business is done by agents The division of business is realized,
-
When the public business expands, it becomes more centralized and convenient
Disadvantages:
-
With more classes and more proxy classes, the workload becomes larger Reduced development efficiency
-
We want the benefits of static agent, but we don't want the disadvantages of static agent, so we have dynamic agent!
1.2 dynamic agent
The role of dynamic agent is the same as that of static agent; The proxy class of dynamic proxy is generated dynamically The proxy class of static proxy is written in advance; Dynamic agents are divided into two types: one is interface based dynamic agents, and the other is class based dynamic agents:
- Dynamic agent based on interface -- JDK dynamic agent
- Class based dynamic proxy – cglib
- Now Java sist is used to generate dynamic proxy Baidu javasist
- We use the native code of JDK to implement it here. The rest are the same
The dynamic proxy of JDK needs to know two classes
Core: InvocationHandler and Proxy. Open the JDK help document and have a look
[InvocationHandler: call handler]
Object invoke(Object proxy, method method, Object[] args); //parameter //Proxy - the proxy instance that calls the method //Method - the method corresponds to the instance that invokes the interface method on the proxy instance. The declared class of the method object will be the interface declared by the method, which can be the super interface of the proxy interface of the proxy class inheriting the method. //args - array of objects containing method calls that pass the parameter values of the proxy instance, or null if the interface method has no parameters. The parameters of the primitive type are contained in an instance of the appropriate primitive wrapper class, such as Java Lang. integer or Java lang.Boolean .
[Proxy: Proxy]
//Generate proxy class public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this); }
code implementation
The role is the same as the real one!
Rent . java is an abstract role
//Abstract role: rent a house public interface Rent { public void rent(); }
Host . java is the real role
//Real role: landlord, the landlord wants to rent the house public class Host implements Rent{ public void rent() { System.out.println("House rental"); } }
ProxyInvocationHandler. java Agent role public class ProxyInvocationHandler implements InvocationHandler { private Rent rent; public void setRent(Rent rent) { this.rent = rent; } //Generate an agent class, focusing on the second parameter to obtain the abstract role to be represented! It used to be a role, but now it can represent a kind of role public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this); } // Proxy: proxy class method: the method object of the calling handler of the proxy class // Process method calls on proxy instances and return results @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { seeHouse(); //Core: essence is realized by reflection! Object result = method.invoke(rent, args); fare(); return result; } //House viewing public void seeHouse(){ System.out.println("Show the tenant"); } //Intermediary fee public void fare(){ System.out.println("Intermediary fee"); } }
Client . java
//Tenant
public class Client {
public static void main(String[] args) {
//Real role
Host host = new Host();
//Call handler for proxy instance
ProxyInvocationHandler pih = new ProxyInvocationHandler();
pih.setRent(host); // Put the real character in!
Rent proxy = (Rent)pih.getProxy(); // Dynamically generate the corresponding proxy class!
proxy.rent();
}
}
Core: a dynamic agent generally represents a certain type of business. A dynamic agent can represent multiple classes, and the agent is the interface
Deepen understanding
Let's use dynamic proxy to implement UserService written later!
We can also write a general dynamic proxy implementation class! All proxy objects can be set to Object!
public class ProxyInvocationHandler implements InvocationHandler { private Object target; public void setTarget(Object target) { this.target = target; } //Generate proxy class public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this); } // Proxy: proxy class // Method: the method object of the calling handler of the proxy class public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { log(method.getName()); Object result = method.invoke(target, args); return result; } public void log(String methodName){ System.out.println("Yes"+methodName+"method"); } }
Test!
public class Test { public static void main(String[] args) { //Real object UserServiceImpl userService = new UserServiceImpl(); //Call handler for proxy object ProxyInvocationHandler pih = new ProxyInvocationHandler(); pih.setTarget(userService); //Sets the object to proxy UserService proxy = (UserService)pih.getProxy(); //Dynamically generate proxy class! proxy.delete(); } }
Test, add, delete, modify and check the results!
Benefits of dynamic agents
- It has all the static agents. It also has all the static agents that don't have!
- It can make our real role more pure Stop paying attention to some public things
- Public business is done by agents The division of business is realized,
- When the public business expands, it becomes more centralized and convenient
- A dynamic agent, generally acting for a certain kind of business
- A dynamic proxy can proxy multiple classes, and the proxy is the interface!
8.2 the role of AOP in Spring
Provide declarative transactions; Allows you to customize the cut plane
The following nouns need to be understood:
-
Crosscutting concerns: methods or functions that span multiple modules of an application. That is, the part that has nothing to do with our business logic, but we need to focus on is crosscutting concerns. Such as log, security, cache, transaction and so on
-
ASPECT: a special object whose crosscutting concerns are modularized. That is, it is a class.
-
Advice: work that must be completed in all aspects. That is, it is a method in a class.
-
Target: the notified object.
-
Proxy: an object created after notification is applied to the target object.
-
PointCut: the definition of the "place" where the aspect notification is executed.
-
Join point: the execution point that matches the pointcut.
In spring AOP, crosscutting logic is defined through Advice. Spring supports five types of Advice:
Notification type | Connection point | Implementation interface |
---|---|---|
Before advice | Method before method | org.springframework.aop.MethodBeforeAdvice |
Post notification | After method | org.springframework.aop.AfterReturningAdvice |
Around Advice | Before and after method | org.aopalliance.intercept.MethodInterceptor |
Exception throw notification | Method throws an exception | org.springframework.aop.ThrowsAdvice |
Introduction notice | Add a new method library to the class | org.springframework.aop.IntroductionInterceptor |
8.3 using Spring to implement Aop
[key] to use AOP weaving, you need to import a dependency package!
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>
The first way
Implemented through Spring API
First, write our business interface and implementation class
public interface UserService { public void add(); public void delete(); public void update(); public void search(); } public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("Add user"); } @Override public void delete() { System.out.println("delete user"); } @Override public void update() { System.out.println("Update user"); } @Override public void search() { System.out.println("Query user"); } }
Then write our enhancement class. We write two, one pre enhancement and one post enhancement
public class Log implements MethodBeforeAdvice { //Method: the method of the target object to execute //objects: parameters of the called method //Object: target object @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println( o.getClass().getName() + "of" + method.getName() + "Method was executed"); } } public class AfterLog implements AfterReturningAdvice { //returnValue return value //Method called method //args parameter of the object of the called method //Target the called target object @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("Yes" + target.getClass().getName() +"of"+method.getName()+"method," +"Return value:"+returnValue); } }
Finally, register in the spring file and implement aop cut in implementation. Pay attention to 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: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.kuang.service.UserServiceImpl"/> <bean id="log" class="com.kuang.log.Log"/> <bean id="afterLog" class="com.kuang.log.AfterLog"/> <!--aop Configuration of--> <aop:config> <!--breakthrough point expression:The expression matches the method to execute--> <aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/> <!--Perform wrap; advice-ref Execution method . pointcut-ref breakthrough point--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config> </beans>
test
public class MyTest { @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserService userService = (UserService) context.getBean("userService"); userService.search(); } }
The importance of Aop: very important We must understand the ideas, mainly the understanding of ideas
When the business domain is combined with the public domain, the business domain will be. Aop, etc Realize the reuse of public business The domain business is more pure. The program ape focuses on the domain business, and its essence is dynamic agent
The second way
Custom classes to implement Aop
The target business class remains the same as userServiceImpl
Step 1: write our own cut in class
public class DiyPointcut { public void before(){ System.out.println("---------Before method execution---------"); } public void after(){ System.out.println("---------After method execution---------"); } }
To configure in spring
<!--The second way is to customize the implementation--> <!--register bean--> <bean id="diy" class="com.kuang.config.DiyPointcut"/> <!--aop Configuration of--> <aop:config> <!--The second way: use AOP Label Implementation of--> <aop:aspect ref="diy"> <aop:pointcut id="diyPonitcut" expression="execution(* com.vector.service.UserServiceImpl.*(..))"/> <aop:before pointcut-ref="diyPonitcut" method="before"/> <aop:after pointcut-ref="diyPonitcut" method="after"/> </aop:aspect> </aop:config>
Test:
public class MyTest { @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserService userService = (UserService) context.getBean("userService"); userService.add(); } }
The third way
Implementation using annotations
Step 1: write an enhanced class for annotation implementation
@Aspect public class AnnotationPointcut { @Before("execution(* com.vector.service.UserServiceImpl.*(..))") public void before(){ System.out.println("---------Before method execution---------"); } @After("execution(* com.vector.service.UserServiceImpl.*(..))") public void after(){ System.out.println("---------After method execution---------"); } @Around("execution(* com.kuang.service.UserServiceImpl.*(..))") public void around(ProceedingJoinPoint jp) throws Throwable { System.out.println("Surround front"); System.out.println("autograph:"+jp.getSignature()); //Execute target method Object proceed = jp.proceed(); System.out.println("After surround"); System.out.println(proceed); } }
Step 2: register the bean in the Spring configuration file and add the configuration supporting annotation
<!--The third way:Annotation implementation--> <bean id="annotationPointcut" class="com.kuang.config.AnnotationPointcut"/> <aop:aspectj-autoproxy/> aop:aspectj-autoproxy: explain adopt aop Namespace<aop:aspectj-autoproxy />Declaration is automatically spring Which configurations are in the container@aspectJ Tangential bean Create a proxy and weave in the cut. of course, spring It is still used internally AnnotationAwareAspectJAutoProxyCreator The creation of automatic agent has been carried out, but the details of the specific implementation have been<aop:aspectj-autoproxy />It's hidden <aop:aspectj-autoproxy />There is one proxy-target-class Property, default to false,Indicates use jdk Dynamic proxy weaving enhancement when configured as<aop:aspectj-autoproxy poxy-target-class="true"/>When, it means to use CGLib Dynamic agent technology weaving enhancement. But even if proxy-target-class Set to false,If the target class does not declare an interface, then spring Will be used automatically CGLib Dynamic proxy.
summary
. . . . .