The secret of Spring framework

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

  1. 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
  2. spring creates bean s in singleton mode by default, which reduces memory consumption
  3. 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~

Keywords: Java MySQL IntelliJ IDEA Spring Back-end

Added by phpretard on Thu, 20 Jan 2022 06:50:44 +0200