Spring
1. Introduction to spring framework
Spring, born in 2002, was created by Rod Johnson. Spring framework is an open source, lightweight project management framework that integrates many design patterns. Committed to JAVAEE lightweight solutions. Compared with the original framework, the spring framework is essentially different from the previous struts 2 and mybatis frameworks. It is not to replace the original framework, but to integrate and manage it.
Lightweight solution: provide a simple, unified and efficient way to construct the whole application, and can knead the single-layer framework together with the best combination to establish a coherent system.
2. The core role of spring framework
The spring framework is used to manage [create | use | destroy] components in the project. Because the spring framework can help us produce component objects in the project, it is also used to call spring a factory container.
Component: the service, Dao and action in the project are all components in the project
Note: the spring framework usually does not manage the creation of entity class objects
3. Build the first spring environment
1. Introduce dependency
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.2.RELEASE</version> </dependency>
2. Import configuration file
# Profile name: any name # Configuration file location: anywhere under the root in the project # Contents of the 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-3.2.xsd "> </beans>
3. Create components
userDAO
package com.libin.dao; public interface UserDAO { void save(String name); }
userDAOImpl
package com.libin.dao; public class UserDAOImpl implements UserDAO { @Override public void save(String name) { System.out.println("full name:"+name); } }
4. Configure factory management components
spring.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"> <!--adopt bean Label management component object--> <bean id="userDAO" name="Can repeat" class="com.libin.dao.UserDAOImpl"></bean> </beans>
5. Start factory test
public static void main(String[] args) { //Start plant ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); //Get object UserDAO userDAO = (UserDAO) context.getBean("userDAO");//If name is repeated, the last one is valid userDAO.save("shouting and arguing noisily"); }
4. The core idea of spring framework
4.1 IOC [control reversal]
-
IOC (inversion of control)
# 1. Definitions Change the creation of the object from the original(new)To the configuration file,hand spring Factory to create objects
-
Di (dependent injection)
# 1. Definitions Spring Not only to create objects,Also establish the relationship between classes,Therefore, the concept of dependency injection is proposed on the basis of control inversion.
4.2 AOP [aspect oriented programming]
AOP (aspect oriented programming) aspect oriented programming
5.Spring dependency injection
5.1 SET mode injection
IoC Service Provider injects the dependent object into the dependent class by calling the setter function provided by the member variable.
Advantages: flexible. You can selectively inject the desired objects.
Disadvantages: after the initialization of the dependent object, it cannot be used because the dependent object has not been injected.
1. Object injection
CityDAO
package com.libin.dao; public interface CityDAO { void query(String name); }
CityDAOImpl
package com.libin.dao; public class CityDAOImpl implements CityDAO{ @Override public void query(String name) { System.out.println("cityDAO: "+name); } }
CityServiceImpl
package com.libin.service; public class CityServiceImpl implements CityService{ //Dependency injection private CityDAO cityDAO; public void setCityDAO(CityDAO cityDAO) { this.cityDAO = cityDAO; } @Override public void queryAll(String name) { //CityDAO cityDAO = new CityDAOImpl(); System.out.println("cityServer: "+name); cityDAO.query(name); } }
spring.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"> <!--DAO Component object--> <bean class="com.libin.dao.CityDAOImpl" id="cityDAOs"></bean> <!--Service Component object--> <bean class="com.libin.service.CityServiceImpl" id="cityService"> <!-- Injection: assigning values to member variables in a class property: Inject values into member variables in the class name: Which member variable is injected with a value member variable name ref: Used to configure the unique identification of the injection object in the factory --> <property name="cityDAO" ref="cityDAOs"></property> </bean> </beans>
Test ---- TestSpring
public class TestSpring { public static void main(String[] args) { //Start factory create component object ApplicationContext context = new ClassPathXmlApplicationContext("di/spring.xml"); //Get the object parameters created in the factory: obtained through the unique ID of the factory CityService cityService = (CityService) context.getBean("cityService"); cityService.queryAll("xiaohuang"); } }
2. Injection of eight basic types + String type + date type
<property name="name" value="zhagnsan"/> <property name="age" value="21"/> <property name="id" value="100063"/> <property name="bir" value="2012/12/12"/> <property name="price" value="23.23"/>
3. Array type injection
<!--Inject array type data--> <property name="qqs"> <array> <value>xxx</value> <value>qqq</value> <value>vvvv</value> </array> </property>
4. Reference type and collection type injection
<!--Inject reference types and objects--> <property name="userDAO" ref="userDAO"/> <property name="lists"> <list> <value>aaa</value> <value>bbb</value> <value>ccc</value> </list> </property> <property name="maps"> <map> <entry key="aa" value="xiaohei"/> <entry key="bb" value="xiaoming"/> <entry key="cc" value="xiaosan"/> </map> </property> <property name="props"> <props> <prop key="url">jdbc:mysql://localhost:3306/test</prop> <prop key="driver">com.mysql.jdbc.Driver</prop> <prop key="username">hr</prop> <prop key="password">hr</prop> </props> </property>
**Note * *: ref attribute injection is used for reference types and value attribute injection is used for basic types
5.2. Structural injection
Definition: the process of injecting values into member variables using construction methods in a class is called construction injection
Syntax:
A. dependency: who needs to declare who as a member variable and provide an open construction method
b. injection: use in the configuration file for injection
Inject the dependent object into the dependent object through the parameters of the constructor, and inject it when initializing the object.
Advantages: after object initialization, you can obtain usable objects.
Disadvantages: when there are many objects to be injected, the constructor parameter list will be very long;
Not flexible enough. If there are multiple injection methods, and each method only needs to specify a few dependencies, multiple overloaded constructors need to be provided
Count, trouble.
StudentDAOmpl.java
package constructor; public class StudentDAOImpl implements StudentDAO { @Override public void querys(String name) { System.out.println("===querys==dao="+name); } }
StudentServiceImpl.java
package constructor; public class StudentServiceImpl implements StudentService { //Dependency injection declares member variables private StudentDAO studentDAO; //Provide construction method public StudentServiceImpl(StudentDAO studentDAO) { this.studentDAO = studentDAO; } @Override public void querys(String name) { System.out.println("===querys=service=="); studentDAO.querys(name); } }
spring.xml
<bean class="autodi.StudentDAOImpl" id="studentDAO"></bean> <bean class="autodi.StudentServiceImpl" id="studentService"> <constructor-arg index="0" name="studentDAO" ref="studentDAO"></constructor-arg> </bean>
test
package constructor; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestSpring { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("constructor/spring.xml"); StudentService studentService = (StudentService) context.getBean("studentService"); studentService.querys("shouting and arguing noisily"); } }
Inject other attributes
<!--Injecting objects using construction methods--> <constructor-arg index="0" name="id" ref="user"/> <!--Inject values using basic data types--> <constructor-arg index="0" name="id" value="1"/> <constructor-arg index="1" name="name" value="xiaohei"/> <constructor-arg index="2" name="age" value="12"/> <constructor-arg index="3" name="qqs"> <array> <value>xxx</value> <value>222</value> <value>333</value> </array> </constructor-arg>
Note: Construction injection is not commonly used, but it must be used in some framework classes. Here, you can understand its injection syntax first.
5.3. Automatic injection
Auto inject object
Syntax:
1. Dependency: who needs to declare who as a member variable and provide an exposed Set method
2. Injection: the bean tag in the configuration file, using the autowired attribute
Principle: the bottom layer uses SET injection
Note: injection between component objects can only be completed automatically, and eight basic types + String + Date + List + array + Map cannot be injected
autowire: automatically inject values for member variables in a class
- autowire="byName"
If the injected property name matches the bean id in the configuration file, it will be injected if it is consistent, and an error will be reported if it is inconsistent
- autowire="byType"
According to the injected attribute type, it matches the type in the configuration file, and the type is consistent with the injection (ambiguity will occur when multiple implementation classes)
Note: no matter which injection method is used above, you need to provide a set method for the attribute
StudentDAOmpl.java
package autodi; public class StudentDAOImpl implements StudentDAO { @Override public void querys(String name) { System.out.println("===querys==dao="+name); } }
StudentServiceImpl.java
package autodi; public class StudentServiceImpl implements StudentService { //Dependency injection declares member variables private StudentDAO studentDAO; //Provides exposed set methods public void setStudentDAO(StudentDAO studentDAO) { this.studentDAO = studentDAO; } @Override public void querys(String name) { System.out.println("===querys=service=="); studentDAO.querys(name); } }
spring.xml
<bean class="autodi.StudentDAOImpl" id="studentDAO"></bean> <bean class="autodi.StudentServiceImpl" id="studentService" autowire="byType"></bean>
test
package constructor; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestSpring { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("autodi/spring.xml"); StudentService studentService = (StudentService) context.getBean("studentService"); studentService.querys("shouting and arguing noisily"); } }
6.Spring Bean factory
6.1.bean creation mode
singleton: singleton default
It is globally unique in the factory and is created only once
prototype: multiple cases
The global is not unique. A new object will be created every time it is used
<bean id="" class="xxxx.userAction" scope="prototype|singleton"> service,dao -----> singleton struts2 action -----> prototype
Note: in project development, the Action of service and Dao components must be multiple instances
6.2. Production principle of bean
Principle: Reflection + construction method
UserDAOImpl userDAO = (UserDAOImpl) Class.forName("com.libin.dao.UserDAOImpl").newInstance(); System.out.println(userDAO);
6.3. The lifecycle of a bean
-
When to create
As the factory starts, all singleton beans create non singleton beans, which are created each time they are used
-
When to destroy
The factory * * closes and all beans are destroyed * * (Note: spring manages multiple beans loosely and will not be responsible for the destruction of multiple beans)
6.4. Benefits of creating objects from bean factories
- Use the configuration file to manage java classes. When changing the implementation of classes in the reproduction environment, there is no need to redeploy and modify the file
- spring creates bean s in singleton mode by default, which reduces memory consumption
- The relationship between classes is established through dependency injection (which makes the relationship between java clearer and convenient for maintenance and management)
Day2
1. Existing business layer development problems
a. Define business interface
public interface UserService { void save(String name); void delete(String id); void update(); String findAll(String name); String findOne(String id); }
b. Implement business interface
public class UserServiceImpl implements UserService { @Override public void save(String name) { try { System.out.println("Open transaction"); System.out.println("Processing business logic,call DAO~~~"); System.out.println("Commit transaction"); }catch (Exception e){ System.out.println("Rollback transaction"); e.printStackTrace(); } } @Override public void delete(String id) { try { System.out.println("Open transaction"); System.out.println("Processing business logic,call DAO~~~"); System.out.println("Commit transaction"); }catch (Exception e){ System.out.println("Rollback transaction"); e.printStackTrace(); } } @Override public void update() { try { System.out.println("Open transaction"); System.out.println("Processing business logic,call DAO~~~"); System.out.println("Commit transaction"); }catch (Exception e){ System.out.println("Rollback transaction"); e.printStackTrace(); } } @Override public String findAll(String name) { try { System.out.println("Open transaction"); System.out.println("Processing business logic,call DAO~~~"); System.out.println("Commit transaction"); }catch (Exception e){ System.out.println("Rollback transaction"); e.printStackTrace(); } return name; } @Override public String findOne(String id) { try { System.out.println("Open transaction"); System.out.println("Processing business logic,call DAO~~~"); System.out.println("Commit transaction"); }catch (Exception e){ System.out.println("Rollback transaction"); e.printStackTrace(); } return id; } }
Problem: as can be seen from the above figure, there is a lot of redundancy in the control transaction code in the existing business layer. How to solve the redundancy problem in the existing business layer?
2. Agency introduction
a. What is an agent
Proxy: refers to a design pattern in java
b. Why do I need an agent
Many times, in addition to the functions that the current class can provide, we need to add some additional functions.
c. Role of agency
The proxy object can act as an intermediary between the customer and the target object, thus adding additional functions to the target object.
d. Proxy legend
3. Development of static agent
Target class | object (target): the proxy class is called the target class | or the proxy object is called the target object
Principle of agent development: the functions of the agent class and the target class are consistent and implement the same interface. At the same time, the agent class depends on the object of the target class
a. Developing static proxy classes
//Static proxy class //Development principle: the proxy class and the target class implement the same interface and depend on the real target class public class UserServiceStaticProxy implements UserService { //Real target class / / target original business logic object private UserService userService; public void setUserService(UserService userService) { this.userService = userService; } @Override public void save(String name) { try { System.out.println("Open transaction"); userService.save(name);//Calling real business logic methods System.out.println("Commit transaction"); }catch (Exception e){ System.out.println("Rollback transaction"); e.printStackTrace(); } } @Override public void delete(String id) { try { System.out.println("Open transaction"); userService.delete(id);//Calling real business logic methods System.out.println("Commit transaction"); }catch (Exception e){ System.out.println("Rollback transaction"); e.printStackTrace(); } } @Override public void update() { try { System.out.println("Open transaction"); userService.update();//Calling real business logic methods System.out.println("Commit transaction"); }catch (Exception e){ System.out.println("Rollback transaction"); e.printStackTrace(); } } @Override public String findAll(String name) { try { System.out.println("Open transaction"); String result = userService.findAll(name);//Calling real business logic methods System.out.println("Commit transaction"); return result; }catch (Exception e){ System.out.println("Rollback transaction"); e.printStackTrace(); } return null; } @Override public String findOne(String id) { try { System.out.println("Open transaction"); //Call the target class method String one = userService.findOne(id);//Calling real business logic methods System.out.println("Commit transaction"); return one; }catch (Exception e){ System.out.println("Rollback transaction"); e.printStackTrace(); } return null; } }
b. Change target implementation class
public class UserServiceImpl implements UserService { @Override public void save(String name) { System.out.println("Processing business logic,call DAO~~~"); } @Override public void delete(String id) { System.out.println("Processing business logic,call DAO~~~"); } @Override public void update() { System.out.println("Processing business logic,call DAO~~~"); } @Override public String findAll(String name) { System.out.println("Processing business logic,call DAO~~~"); return name; } @Override public String findOne(String id) { System.out.println("Processing business logic,call DAO~~~"); return id; } }
c. Configure static proxy classes
<!--Configure target class--> <bean id="userService" class="staticproxy.UserServiceImpl"></bean> <!--Configure proxy class--> <bean id="userServiceStaticProxy" class="staticproxy.UserServiceStaticProxy"> <!--Injection target object--> <property name="userService" ref="userService"/> </bean>
d. Call proxy method
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); UserService userServiceStaticProxy = (UserService) context.getBean("userServiceStaticProxy"); userServiceStaticProxy.save("shouting and arguing noisily");
New problem: we often write more than one business layer and two business layers in development, and there will be many business layers. If we develop a static agent class for each business layer, it will not reduce the workload, and even double our workload. How to solve the above problem?
Solution: dynamically create agent classes for the business layer during operation, and solve the problem of business code redundancy in our existing business layer through dynamic agent classes
4. Principle of dynamic agent
The Proxy class provided by jdk can dynamically generate Proxy classes for existing businesses
Parameter 1: current thread class loader
Parameter 2: interface type for generating proxy class
Parameter 3: when calling a method through a proxy class object, the invoke party proxy in parameter 3 will be entered first newProxyInstance(loader, interfaces, h) ;// The return value is the dynamic proxy object
public class TestDynamicProxy { public static void main(String[] args) { final UserService userService = new UserServiceImpl(); //Parameter 1: current thread class loader ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); //Parameter 2: Class[] classes = new Class[]{UserService.class}; //Parameter 3: UserService userServiceProxy = (UserService) Proxy.newProxyInstance(contextClassLoader, classes, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try{ System.out.println("Open transaction");//Additional operation Object invoke = method.invoke(userService, args); System.out.println("Commit transaction");//Additional operation return invoke; }catch (Exception e){ System.out.println("Rollback transaction");//Additional operation } return null; } }); userServiceProxy.save("Xiao Xiao"); } }
5.AOP (Aspect Oriented Programming)
Advice: operations other than the target method are called notifications
Pointcut: which methods in which classes should be notified
Aspect: notification + pointcut
1. Notification classification
2. Programming steps
# 1. Introduce dependency spring-aop spring-expression spring-aspects # 2. Development notice MethodBeforeAdvice Before advice MethodInterceptor Around Advice AfterReturningAdvice Notify on return ThrowsAdvice Exception notification MyAdvice implements Notification interface{.....} //Custom notification class: used to complete additional functions public class MyAdvice implements MethodBeforeAdvice { @Override//Parameter 1: currently calls the method object / / parameter 2: currently calling the parameter / / parameter 3: object of the method object. public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("Target method name: "+method.getName()); System.out.println("Parameters of the target method: "+objects); System.out.println("Target object: "+o.getClass()); } } # 3. Configuration section a.introduce aop 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: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"> b.Management notice <!--Management notification class--> <bean id="myAdvice" class="before.MyAdvice"/> c.Configure section <aop:config> <aop:pointcut id="pc" expression="execution(* before.UserServiceImpl.*(..))"/> <aop:advisor advice-ref="myAdvice" pointcut-ref="pc"/> </aop:config> # 4. Start factory test ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("before/spring.xml"); UserService userSerivce = (UserService) context.getBean("userService"); System.out.println(userSerivce.getClass()); userSerivce.save("shouting and arguing noisily");
3. Use of advance notice
4. Use of surround notifications
5. Notification upon return
6. Exception notification
6. Entry point expression table
1. Pointcut expression at execution method level
Note: the pointcut expression at the method level should be as accurate as possible, otherwise the program may run abnormally
2. Pointcut expression at within class level
# 1. Grammar within(package.class) # 2. Examples within(com. service.*) package: com. service class: All methods in all classes do not care about return values and parameters within(com. service.UserServiceImpl) package: com.libin.service class: UserServiceImpl All methods in the class do not care about return values and parameters
Note: the efficiency of within is higher than that of execution expression. It is recommended to use within expression
If you think it's good, praise, collect, share, and support me with one key and three links~