Basic use of Spring framework

1, Foreword

The basic part of the Spring framework is too long. It is divided into several articles to consolidate the learning record.

1. What is Spring

The spring framework was created due to the complexity of software development. Spring uses basic JavaBean s to accomplish things that could only be done by EJB s before. However, the use of spring is not limited to server-side development. In terms of simplicity, testability and loose coupling, most Java applications can benefit from spring.
Objective: to solve the complexity of enterprise application development
Function: use basic JavaBean s instead of EJB s
Scope: any Java application
Spring is a lightweight inversion of control (IoC) and aspect oriented (AOP) container framework.

2. Spring advantages

1 convenient decoupling and simplified development
Through the container, Spring separates the creation of objects from the code and gives them to Spring for control, so as to avoid high coupling between modules caused by direct coding. Users do not have to code and deal with the single instance and multiple instance control of objects by themselves. They can mainly focus on the interface function without paying attention to the specific implementation class and implementation details
2 AOP section programming
AOP aspect programming is a concept of programming. Spring implements this concept well. Through aspect programming, we can increase functions without modifying the original code. It is usually used for transaction control, logging, performance detection, permission control and so on
3 declarative transactions
The control of transactions can be entrusted to Spring. We can declare the transaction processing method through annotations or configuration files without coding and processing ourselves
4. Integrate JUNIT to facilitate testing
spring integrates JUNIT unit test, which can easily and quickly test the functions of the project, which is convenient for us to debug the program
5. It is convenient to integrate various excellent frameworks
SSM> Spring+SpringMVC +MyBatis
SSH> Spring+Hibernate +Strust
Various other frameworks
6. Rich functional packaging
spring encapsulates JavaEE (JDBC, JavaMail,) in a series of ways to simplify our use of API s and improve the efficiency of program development
7 standardized source code learning samples
spring has ingenious source code design, clear structure and extensive use of design patterns. It is not only a model of java code specification, but also the source code often asked in the interview of senior programmers

3. Spring architecture


1.Data Access/Integration

  • The data access / integration layer includes JDBC, ORM, OXM, JMS and Transactions modules, which are described below.
    • JDBC module: it provides an abstract layer of JDBC, which greatly reduces the coding of database operations in the development process.
    • ORM module: provides an integration layer for popular object relational mapping API s, including JPA, JDO, Hibernate and iBatis.
    • OXM module: provides an abstract layer implementation that supports object / XML Mapping, such as JAXB, Castor, XMLBeans, JiBX and XStream.
    • JMS module: refers to the Java message service, which contains information for production and consumption.
    • Transactions transaction module: support programming and declarative transaction management, implement special interface classes, and provide all POJO s.

2.Web module

  • The Web layer of Spring includes Web, Servlet, Struts and Portlet components. The details are as follows.
    • Web module: it provides basic web development integration features, such as multi file upload function, IoC container initialization of Servlet listener and web application context.
    • Servlet module: including Spring model view controller (MVC) to implement Web application.
    • Struts module: it contains Spring applications in support classes and integrates the classic Struts Web layer.
    • Portlet module: it provides the function of using MV C in portlet environment, which is similar to that of Web servlet module.

3.Core Container

  • Spring's Core container is the foundation of other modules. It is composed of Beans module, Core module, Context module and Expression Language module. Details are as follows.
    • Beans module: it provides BeanFactory, which is a classic implementation of the factory pattern. Spring calls the management object Bean.
    • Core module: provides the basic components of Spring framework, including IoC and DI functions.
    • Context module: Based on the core and Beans modules, it is the medium to access, define and configure any object. The ApplicationContext interface is the focus of the context module.
    • Expression Language module: it is a powerful Expression Language for querying and manipulating object graphs at runtime.
  1. Other modules
  • Other modules of Spring include AOP, Aspects, Instrumentation and Test modules, which are described below.
    • AOP module: it provides aspect oriented programming implementation, which allows to define method interceptors and entry points, and separate the code according to functions to reduce coupling.
    • Aspects module: provides integration with AspectJ. It is a powerful and mature aspect oriented programming (AOP) framework.
    • Instrumentation module: it provides the support of class tools and the implementation of class loader, which can be used in a specific application server.
    • Test module: supports Spring components and tests using JUnit or TestNG framework.

2, Spring IOC basic usage

1. IOC concept

In short, the right to create an object, or the location of control, is transferred from the JAVA code to the spring container. The spring container controls the creation of an object, that is, the inversion of control. When spring creates an object, it will read the information in the configuration file, and then use the reflection to create the object and store it in the container. When we need an object, we can obtain the object through the id, We don't need to go to new
Bottom line: create objects and give them to the container
Basic test code:
Create a Maven project, and then import the shelf package of spring beans. After importing the shelf package, the four dependencies will also be automatically imported into the project
Spring context, container
Spring beans create objects
Spring core jar
Spring expression expression jar

 <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>5.3.5</version>
 </dependency>

The dependency transfer diagram is as follows

To facilitate testing, we import Junit test dependencies

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope>
        </dependency>

Then create the implementation class

package com.xiaohui.dao;

public interface EmpDao {
    int addEmp();
}

package com.xiaohui.dao.impl;

import com.xiaohui.dao.EmpDao;

public class EmpDaoImpl implements EmpDao {
    @Override
    public int addEmp() {
        System.out.println("addEmp()");
        return 0;
    }
}

Create a new Spring xml file in the resources directory and copy < bean id = "empdao" class = "com. Xiaohui. Dao. Impl. Empdaoimpl" > < / bean >

public class Test01 {
    @Test
    public void testAddEmp(){
        //Get a container object and read spring XML file. After instantiating the configured object in the configuration file, it is automatically put into the container
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        //Get the object of the object by the ID of the container
        EmpDao empDao = applicationContext.getBean("empDao",EmpDao.class);
        //Call method test
        empDao.addEmp();
    }
}

2. Implementation principle of IOC container

  • 1. Reading configuration file with XML parsing technology
<bean id="empDao" class="com.msb.dao.impl.EmpDaoImpl"></bean>

Read the above information into the ID of the program object. One is the full pathname of the object's class

  • 2. Reflection technology instantiates objects and puts them into containers
    Get the bytecode of the class
    Class clazz =Class.forName("com.msb.dao.impl.EmpDaoImpl")
    Instantiate objects by bytecode
    Object obj = clazz.newInstance();
    Put objects into a map collection
    map.put("empDao",obj)
  • 3. Factory mode returns Bean object getBean method
     public Object getBean(String name){
            Object obj =map.get(name);
            return obj;
     }   
  • IOC interface
    • BeanFactory interface: the basic function interface of IOC container, which is used internally by spring. We generally do not use this interface directly when dealing with business
    • ApplicationContext provides more powerful sub interfaces for developers

3, Implementing DI in XML

  • Bean management in spring:
    • Bean (Chinese translation of coffee beans) Also known as JAVABean In fact, it is one object in JAVA program, so bean management is actually spring's management of objects in JAVA program
  • What is the content of management
    • 1. Object creation IOC
      • IOC is called inversion of control, which means that Spring creates objects for us, and then we use them directly instead of NEW
      • IOC deals with how objects are created
    • 2. Attribute assignment DI
      • DI Dependency Injection, i.e. "dependency injection" refers to assigning values to object attributes when creating attributes
        The realization of object function often depends on the value of attribute, so assigning value to object attribute can be regarded as dependency injection
      • Because object attributes are not only basic data types, but also other classes or reference types
        Then dependency injection will put more relationships between objects together, which can create a huge dependency
        DI deals with the attribute assignment and interdependence of objects

1. IOC create object

Construct objects by parameterless construction method

<bean id="user1" class="com.xiaohui.bean.User"></bean>

Common properties of bean Tags

  • id the id of the object
  • Full pathname of class
  • name is similar to id, but generally not used
  • Scope controls the single instance and multiple instances of the object and the scope of use
    • singleton scope (the default value of scope), there will only be one shared bean instance in the Spring IOC container
    • For the beans deployed in the prototype scope, each acquisition will generate a new bean instance, which is equivalent to a new operation
    • Request means that a new bean will be generated for each HTTP request, and the bean is only valid in the current HTTP request
    • The session scope means that a new bean will be generated for each HTTP request, and the bean is only valid in the current HTTP session
    • The global session scope is similar to the standard HTTP Session scope, but it only makes sense in portlet based web applications
  • Lazy init lazy loads and instantiates the object when calling getBean

2. DI assigns values to object properties

a. Assign values to object attributes through the set method

 <!--property Is using set Method to implement dependency injection-->
    <bean id="user1" class="com.xiaohui.bean.User">
        <property name="userid" value="1"></property>
        <property name="username" value="Zhang San"></property>
        <property name="password" value="abcdefg"></property>
    </bean>

b. Assign values to object properties through parameterized construction

<!--
    constructor-arg Is to use the construction method to implement dependency injection
    constructor-arg The number of must correspond to the number of parameters of a construction method
    name Refers to the parameter name
    index Refers to the index of the parameter
    value Refers to the parameter value
    -->
    <bean id="user2" class="com.xiaohui.bean.User">
        <constructor-arg name="userid" value="20"></constructor-arg>
        <constructor-arg name="username" value="A Wu"></constructor-arg>
        <constructor-arg name="password" value="123456789"></constructor-arg>
    </bean>
    <bean id="user3" class="com.xiaohui.bean.User">
        <constructor-arg index="0"  value="30"></constructor-arg>
        <constructor-arg index="1"  value="ASA"></constructor-arg>
        <constructor-arg index="2"  value="987654321"></constructor-arg>
    </bean>

c. Assign values to object attributes through the p namespace and the C namespace

Add constraint

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

Configuration object

<!--p Namespace,That's right property Simplified treatment of-->
    <bean id="user4" class="com.msb.bean.User" p:userid="4" p:username="Xiaodong" p:password="111111" ></bean>
    <!--c Namespace,That's right constructor-arg Simplification of-->
    <bean id="user5" class="com.msb.bean.User" c:userid="5" c:username="Xiaoxi" c:password="222222" ></bean>

d. Inject null values and special symbols

 <bean id="user1" class="com.msb.bean.User">
        <!--null value-->
        <property name="userid">
            <null></null>
        </property>
        <!--Special symbol translation character < &lt;  >&gt;  & &amp;     -->
        <property name="username" value="&amp;xiaoming&lt;&gt;"></property>
        <!-- Special symbols  <![CDATA[content]]>  -->
        <property name="password">
            <value><![CDATA[&<123456>]]></value>
        </property>
    </bean>

e. About bean references

Create two entity classes

package com.msb.bean;
import java.util.Date;

public class Mouse {
    private String name;
    private Date birthdate;
    @Override
    public String toString() {
        return "Mouse{" +
                "name='" + name + '\'' +
                ", birthdate=" + birthdate +
                '}';
    }
    public Mouse() {
    }
    public Mouse(String name, Date birthdate) {
        this.name = name;
        this.birthdate = birthdate;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Date getBirthdate() {
        return birthdate;
    }
    public void setBirthdate(Date birthdate) {
        this.birthdate = birthdate;
    }
}
package com.msb.bean;

public class Cat {
    private String name;
    private Mouse mouse1;
    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", mouse1=" + mouse1 +
                '}';
    }
    public Cat() {
    }
    public Cat(String name, Mouse mouse1) {
        this.name = name;
        this.mouse1 = mouse1;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Mouse getMouse1() {
        return mouse1;
    }
    public void setMouse1(Mouse mouse1) {
        this.mouse1 = mouse1;
    }
}

applicationContext3.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">

    <!--Tell the container to prepare one Date object-->
    <bean id="date1" class="java.util.Date"></bean>

    <bean id="mouse" class="com.xiaohui.bean.Mouse">
        <property name="name" value="Jerry"></property>
        <!--bean Reference external bean-->
        <property name="birthdate" ref="date1"></property>
    </bean>

    <bean id="cat1" class="com.xiaohui.bean.Cat">
        <property name="name" value="Tom"></property>
        <!--bean Reference external bean-->
        <property name="mouse1" ref="mouse"></property>
    </bean>

    <bean id="cat2" class="com.xiaohui.bean.Cat">
        <property name="name" value="Tom2"></property>
        <!--Reference internal bean-->
        <property name="mouse1">
            <bean class="com.xiaohui.bean.Mouse">
                <property name="name" value="Jerry2"></property>
                <property name="birthdate">
                    <bean class="java.util.Date"></bean>
                </property>
            </bean>
        </property>
    </bean>

    <bean id="mouse2" class="com.xiaohui.bean.Mouse"></bean>
    <bean id="cat3" class="com.xiaohui.bean.Cat">
        <property name="name" value="Tom3"></property>
        <!--Cascade introduction bean-->
        <property name="mouse1" ref="mouse2"></property>
        <!--Calling this class with reflection get***()Method to obtain the object and then assign a value-->
        <property name="mouse1.name" value="Jerry3"></property>
        <property name="mouse1.birthdate">
            <bean class="java.util.Date"></bean>
        </property>
    </bean>

</beans>

Test code:

    @Test
    public void testCat(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext3.xml");
        Cat cat = applicationContext.getBean("cat1", Cat.class);
        System.out.println(cat.toString());

        Cat cat2 = applicationContext.getBean("cat2", Cat.class);
        System.out.println(cat2.toString());

        Cat cat3 = applicationContext.getBean("cat3", Cat.class);
        System.out.println(cat3.toString());

    }

result:

Cat{name='Tom', mouse1=Mouse{name='Jerry', birthdate=Tue May 11 16:54:10 CST 2021}}
Cat{name='Tom2', mouse1=Mouse{name='Jerry2', birthdate=Tue May 11 16:54:10 CST 2021}}
Cat{name='Tom3', mouse1=Mouse{name='Jerry3', birthdate=Tue May 11 16:54:10 CST 2021}}

f. About set injection

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util.xsd">

    <!--Define public collections-->
    <util:list id="outerbookList">
        <!--Declare multiple Book object-->
        <bean id="b1" class="com.xiaohui.bean.Book" p:bname="JAVA" p:author="hibernate "></bean>
        <bean id="b2" class="com.xiaohui.bean.Book" p:bname="Go" p:author="hibernate "></bean>
        <bean id="b3" class="com.xiaohui.bean.Book" p:bname="JVM" p:author="hibernate "></bean>
    </util:list>

    <bean id="student1" class="com.xiaohui.bean.Student">
        <!--Array injection first-->
        <!--<property name="books" value="1,2,3"></property>-->
        <!--Array injection second-->
        <property name="books">
            <array>
                <value>java</value>
                <value>Mysql</value>
                <value>Spring</value>
            </array>
        </property>

        <!--set Set injection-->
        <property name="bookSet">
            <set>
                <value>java</value>
                <value>Mysql</value>
                <value>Spring</value>
            </set>
        </property>

        <!--list Set injection-->
        <property name="bookList">
            <list>
                <value>java</value>
                <value>Mysql</value>
                <value>Spring</value>
            </list>
        </property>

        <!--Map Set injection-->
        <property name="bookMap">
            <map>
                <entry key="java" value="aaa"></entry>
                <entry key="mysql" value="bbb"></entry>
                <entry key="spring" value="ccc"></entry>
            </map>
        </property>

        <!--List The first method of object injection-->
        <!--<property name="bookList2" ref="outerbookList"></property>-->
        <!--Second-->
        <property name="bookList2">
            <list>
                <bean class="com.xiaohui.bean.Book">
                    <property name="bname" value="java"></property>
                    <property name="author" value="aaa"></property>
                </bean>
                <bean class="com.xiaohui.bean.Book">
                    <property name="bname" value="mysql"></property>
                    <property name="author" value="bbb"></property>
                </bean>
                <bean class="com.xiaohui.bean.Book">
                    <property name="bname" value="spring"></property>
                    <property name="author" value="ccc"></property>
                </bean>
                <ref bean="book1"></ref>
            </list>
        </property>
    </bean>

    <bean name="book1" class="com.xiaohui.bean.Book">
        <property name="bname" value="Java"></property>
        <property name="author" value="ddd"></property>
    </bean>


</beans>

Test code:

    @Test
    public void testStudent(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext4.xml");
        Student student = applicationContext.getBean("student1", Student.class);
        System.out.println(student.getBooks());
        System.out.println(student.getBookList());
        System.out.println(student.getBookSet());
        System.out.println(student.getBookMap());
        System.out.println(student.getBookList2());

    }

result:

[java, Mysql, Spring]
[java, Mysql, Spring]
[java, Mysql, Spring]
{java=aaa, mysql=bbb, spring=ccc}
[Book{bname='java', author='aaa'}, Book{bname='mysql', author='bbb'}, Book{bname='spring', author='ccc'}, Book{bname='Java', author='ddd'}]

g. Get bean in factory mode

Features: the class class defined in the bean tag is not the class of the returned object, but the factory that produces the object
Factory design mode: GOF
spring defines a factory interface for us, which can produce the interface of objects. We can obtain bean s through the factory
Define the factory object and implement the FactoryBean interface

package com.xiaohui.bean;

import org.springframework.beans.factory.FactoryBean;

public class BookFactroy implements FactoryBean<Book> {
    @Override
    public Book getObject() throws Exception {
        Book book = new Book();
        book.setBname("java");
        book.setAuthor("programmer");
        return book;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }
}

configuration file

<bean id="bookFactroy" class="com.xiaohui.bean.BookFactroy"></bean>

Test code

package com.xiaohui.test;

import com.xiaohui.bean.*;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Arrays;

public class Test02 {

    @Test
    public void testUser(){
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationContext5.xml");
        //The object returned by the factory is the Book object, so here we need to use the Book class to receive
        Book book = applicationContext.getBean("bookFactroy", Book.class);
        System.out.println(book);
    }

}

result:

Book{bname='java', author='programmer'}

4, Bean life cycle

SpringBean's lifecycle reference link: Detailed explanation of Spring Bean life cycle

  • The bean goes through various stages from creation to destruction and the methods called in each stage
    • 1 create bean instance through constructor (execute constructor)
    • 2. Assign value to bean attribute (execute set method)
    • 3. Initialize the bean (call the initialization method of the bean and configure the method to be called)
    • 4. Bean acquisition (container object getBean method)
    • 5. The container closes and destroys the bean (to call the destruction method, you need to configure the method to be called)

Test life cycle
Prepare bean

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

     <bean id="user" class="com.xiaohui.bean.User" init-method="initUser" destroy-method="destoryUser">
          <property name="username" value="Zhang San"></property>
     </bean>

</beans>

Entity class

package com.xiaohui.bean;

 **/
public class User {
    private Integer userid;
    private String username;
    private String password;

    public User() {
        System.out.println("First step:User structure");
    }

    public void setUsername(String username) {
        System.out.println("Step 2: User set method");
        this.username = username;
    }

    public void initUser(){
        System.out.println("Step 3: User initialization");
    }

    public void destoryUser(){
        System.out.println("Step 5: User Destroy");
    }

    public Integer getUserid() {
        return userid;
    }

    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }



    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public User(Integer userid, String username, String password) {
        System.out.println("allArgConstructor");
        this.userid = userid;
        this.username = username;
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "userid=" + userid +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

Test code:
	@Test
    public void testUser(){
        ClassPathXmlApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationContext6.xml");
        User user = applicationContext.getBean("user", User.class);
        System.out.println("Step 4: User Object gets from the container");
        System.out.println(user);
        //Close the container
        applicationContext.close();
    }

result:

First step:User structure
 Step 2: User set method
 Step 3: User initialization
 Step 4: User Object gets from the container
User{userid=null, username='Zhang San', password='null'}
Step 5: User Destroy
  • About post processor
    • 1 create bean instance through constructor (execute constructor)
    • 2. Assign value to bean attribute (execute set method)
    • 3 method of passing bean instance to bean post processor
    • 4. Initialize the bean (call the initialization method of the bean and configure the method to be called)
    • 5 method of passing bean instance to bean post processor
    • 6. Bean acquisition (container object getBean method)
    • 7. The container closes and destroys the bean (to call the destruction method, you need to configure the method to be called)

1. Create a post processor to implement beanpostprocessor and rewrite two methods

package com.xiaohui.beanProcesser;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanProcesser implements BeanPostProcessor {
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        //Object bean instantiated bean
        //id of string beanname bean
        System.out.println("bean:Before initializing the method");
        return bean;// return bean is required here
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("bean:After initializing the method");
        return bean;// return bean is required here
    }
}

2 configure the post processor and add the life cycle of the post processor to all bean s in the container

<bean id="myBeanProcesser" class="com.xiaohui.beanProcesser.MyBeanProcesser"></bean>

result:

First step:User structure
 Step 2: User set method
bean:After initializing the method
 Step 3: User initialization
bean:Before initializing the method
 Step 4: User Object gets from the container
User{userid=null, username='Zhang San', password='null'}
Step 5: User Destroy
  • Functions of BeanPostProcessor interface:
    • If we want to complete bean instantiation, configuration and other initialization methods in the Spring container, we need to add some logic processing before and after. We need to define one or more BeanPostProcessor interface implementation classes, and then register them in the Spring IoC container.

1. Both methods in the interface should return the incoming bean instead of null. If NULL is returned, we will not get the target through the getBean method.
2. ApplicationContext will automatically detect all beans that implement the BeanPostProcessor interface in the configuration file, register them as post processors, and then call it when the container creates beans. Therefore, deploying a post processor is no different from deploying other beans. When using BeanFactory implementation, the bean post processor must be explicitly registered through code, and the registration method is defined in the ConfigurableBeanFactory interface in the IoC container inheritance system

5, Automatic assembly

The property tag allows you to manually assign properties for injection
We can also complete the automatic injection of attributes through automatic transfer, that is, automatic assembly, which can simplify the configuration of DI

package com.xiaohui.bean;

public class Dept {
}

package com.xiaohui.bean;

public class Emp {
    private Dept dept;
    @Override
    public String toString() {
        return "Emp{" +
                "dept=" + dept +
                '}';
    }
    public Dept getDept() {
        return dept;
    }
    public void setDept(Dept dept) {
        this.dept = dept;
    }
    public Emp() {
    }
    public Emp(Dept dept) {
        this.dept = dept;
    }
}

configuration file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="dept" class="com.msb.bean.Dept"></bean>
    <!--
    autowire Property control automatically injects objects in the container onto the properties of the current object
    byName According to the goal id Value and attribute value injection,To ensure that the property value of the current object is consistent with that of the target object id Consistent value
    byType Inject according to type,Ensure that there is only one instance of the same type of target object in the container
    -->
    <bean id="emp" class="com.msb.bean.Emp" autowire="byName"></bean>
</beans>

Test code

@Test
    public void testUser(){
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationContext7.xml");
        Emp emp = applicationContext.getBean("emp", Emp.class);
        System.out.println(emp);
    }

result:

Emp{dept=com.xiaohui.bean.Dept@13c9d689}

6, Use external property profile

1. Import Druid dependency and MySQL connector dependency

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.23</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>

2. Prepare a JDBC in the resources directory Properties property configuration file

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=root

Add the context namespace in applicationContext and read the attribute configuration file. Configure the druid data source and inject the information in the attribute configuration file into the connection pool

<?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">

     <context:property-placeholder location="jdbc.properties"></context:property-placeholder>

     <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
          <property name="username" value="${jdbc.username}"></property>
          <property name="password" value="${jdbc.password}"></property>
          <property name="url" value="${jdbc.url}"></property>
          <property name="driverClassName" value="${jdbc.driver}"></property>
          <property name="initialSize" value="1"></property>
     </bean>

</beans>

3 Debug test code

    @Test
    public void testUser() throws SQLException {
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationContext8.xml");
        DruidDataSource druidDataSource = applicationContext.getBean("druidDataSource", DruidDataSource.class);
        System.out.println(druidDataSource);
    }

7, Annotation management bean

1. Create object IOC in annotation mode

  • @Component is placed on the class and used as a tag to tell spring that the current class needs to be instantiated by the container and put into the container
    • This annotation has three sub annotations
      • @The controller is used to instantiate the controller layer bean
      • @Service is used to instantiate service layer bean s
      • @Repository is used to instantiate persistence layer bean s
    • When you are not sure which layer it is, use Component
    • It's OK to mix these annotations with each other, but it's not recommended
<?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">
    <!--Add annotation scan,Scan the specified package,Instantiate all annotated classes in the package
        base-package Put the package to be scanned behind
        If there are multiple packages to scan,You can separate them with commas  com.xiaohui.bean,com.xiaohui.service
        Or you can write a layer of package path  com.xiaohui
        It can be specified by annotation bean of id@Component("user1")
        If not specified,be id The default is lowercase
        -->
    <context:component-scan base-package="com.xiaohui.bean"></context:component-scan>

</beans>

Entity class and test code

package com.xiaohui.bean;

import org.springframework.stereotype.Component;

@Component
public class User {
}

    @Test
    public void testGetBean(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = applicationContext.getBean("user", User.class);
        System.out.println(user);
    }

result:

com.xiaohui.bean.User@41fecb8b

Component scan configuration annotation identification
use-default-filters="false"
The default value is true, which means the default scanning filter is used
The Default scan filter will recognize and include four annotations @ Component @Controller @Service @Repository
Instead of using the default filter, use our own filter

    <!--Control scan only Controller annotation-->
    <context:component-scan base-package="com.xiaohui.bean" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!--Control not to scan Controller annotation-->
    <context:component-scan base-package="com.xiaohui.bean" use-default-filters="true">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

Test code:

//@Component
@Controller
//@Service
//@Repository
public class User {
}

    @Test
    public void testGetBean(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user1 = applicationContext.getBean("user", User.class);
        System.out.println(user1);
    }

Scan only Controller When commenting, the result is com.xiaohui.bean.User@5ace1ed4
 Do not scan Controller Note, the result is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'user' available

2. Annotation dependent injection DI

@Autowired automatically assembles according to the attribute data type
@Qualifier injects dependencies based on attribute names
@Resources can be injected by type or name
@Value injection normal data type (8+String)
Project structure diagram

Interface and implementation class

public interface UserDao {
    void add();
}

@Repository
public class UserDaoImplA implements UserDao {
    @Override
    public void add() {
        System.out.println("UserDaoImplA  add...");
    }
}

@Repository
public class UserDaoImplB implements UserDao {
    @Override
    public void add() {
        System.out.println("UserDaoImplB  add...");
    }
}

public interface UserService {
    void add();
}

applicationContext2.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"
       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">

    <context:property-placeholder location="classpath:aaa.properties"></context:property-placeholder>
    <context:component-scan base-package="com.xiaohui"></context:component-scan>

</beans>

aaa.properties

sname=Xiao Ming
sage=20
sgender=male

When using external files to read content, Chinese garbled code is used for setting and related configuration

  • @Autowired (common)
    • Find the corresponding object in the container according to the type, and assign a value to the current attribute after finding it
    • There is no need to rely on the set method
    • The attribute type can be an interface, which will automatically match the corresponding implementation class object
    • @Autowired works with @ Qualifier to specify injected objects by name
    • @If the Resource does not configure name, it is injected according to the type
    • @Resource(name = "userDaoImplB") configures name, which is injected according to the name
  • @Resource is the annotation of javax package in JDK
  • @Autowired and @ Qualifier are annotations in spring
  • @Value can be assigned to a common attribute
  • @Value can use the expression ${} to get the variable value of the system
    • Or Values in the properties property configuration file
package com.xiaohui.service.impl;

import com.xiaohui.dao.UserDao;
import com.xiaohui.dao.impl.UserDaoImplA;
import com.xiaohui.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class UserServiceImpl implements UserService {
//    @Autowired
//    @Qualifier("userDaoImplB")
//    private UserDao userDao;

    @Resource(name="userDaoImplA")
    private UserDao userDao;
    
    //Ordinary attribute assignment (external files or direct assignment can be used)
    @Value("${sname}")
    private String sname;
    @Value("${sgender}")
    private String sgender;
    @Value("${sage}")
    private Integer sage;
    
    @Override
    public void add() {
        System.out.println("UserServiceImpl add...");
        System.out.println(sname);
        System.out.println(sgender);
        System.out.println(sage);
        userDao.add();
    }
}

The test results of @ Autowired and @ Qualifier are the same as those of @ Resource

UserServiceImpl add...
Xiao Ming
 male
20
UserDaoImplA  add...

3. Configure classes to implement IOC and DI (understand)

Add @ ComponentScan and @ PropertySource through a configuration class in the config directory to scan packages and external files
Create a configuration class to replace the XML configuration file

package com.xiaohui.config;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackages = "com.xiaohui")
@PropertySource("classpath:aaa.properties")
public class SpringConfig {
}

Test code:

    @Test
    public void testGetBean2(){
        ApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        UserServiceImpl userServiceImpl = applicationContext.getBean("userServiceImpl", UserServiceImpl.class);
        userServiceImpl.add();
    }

result:

UserServiceImpl add...
Xiao Ming
 male
20
UserDaoImplB  add...

8, Agent mode

Proxy mode is to access the target object through the proxy object, which can enhance additional functions based on the target object, such as adding permissions, access control and audit.

1. Static proxy

In the static proxy, both the proxy class and the proxy class need to implement the same interface, which means that our static proxy class can only proxy one class, and we need to know which class we want to proxy in advance to write the proxy class. If we have other classes that want to use the proxy, we must write another proxy class. However, in actual development, we may have many classes that need to be represented, and we may not know which class we want to represent in advance. Therefore, if we continue to use static agents, it will increase a lot of workload, low efficiency and poor code reuse rate.

package com.xiaohui.test;

public class Test1 {
    public static void main(String[] args) {
        Person person =new Person("Zhang San");
        Court court=new Lawyer(person);
        court.doCourt();
    }
}
// Interface
interface Court{
    void doCourt();
}
// proxy class
class Lawyer implements Court{
    private Person person;
    public Lawyer(Person person) {
        this.person = person;
    }
    @Override
    public void doCourt() {
        System.out.println("Lawyer evidence:The video proves that Zhang San was traveling at that time,Not at the crime scene");
        System.out.println("Lawyer summary:Zhang San can't kill");
        person.doCourt();
    }
}
// Proxied class
class Person implements Court{
    private String name;
    public Person(String name) {
        this.name = name;
    }
    @Override
    public void doCourt() {
        System.out.println(name+"say:I didn't kill anyone");
    }
}

Using agent technology to obtain agent object instead of Zhang San to enhance the method of lawsuit

2. Dynamic agent

Dynamic proxy can proxy for some non-specific classes or some non-specific methods. We can dynamically change the rules of the proxy when the program is running. The proxy mode created by the proxy class when the program is running becomes dynamic proxy. In this case, the proxy class is not defined in the Java code, but dynamically generated according to our "instructions" in the Java code when the program runs
Proxy dynamic proxy JDK dynamic proxy oriented interface
cglib dynamic proxy third-party dynamic proxy facing parent class

a. Proxy dynamic proxy JDK dynamic proxy

Obtain a Proxy object through Proxy dynamic Proxy, and enhance a method in the Proxy object

  • The premise of using proxy dynamic proxy
    • Interface oriented
    • 1. There must be interfaces and implementation classes
    • 2. Methods defined in the enhancement interface
    • 3. Only annotations on Methods in the interface can be read
package com.xiaohui.testProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Test02 {
    public static void main(String[] args) {
        Dinner dinner = new Person("Zhang San");

        //Obtain a Proxy object through Proxy dynamic Proxy, and enhance a method in the Proxy object
        // Classloader, the class loader of the proxy object
        ClassLoader classLoader = dinner.getClass().getClassLoader();
        // Class<?> [] interfaces, all interfaces implemented by the proxy object
        Class[] interaces= dinner.getClass().getInterfaces();
        // InvocationHandler h, the execution processor object, is specifically used to define enhanced rules
        InvocationHandler invocationHandler = new InvocationHandler(){
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                Object proxy proxy object
//                Method method the method being represented
//                Object[] args is the runtime argument of the proxy method
                Object res = null;
                if(method.getName().equals("eat")){
                    System.out.println("Wash your hands before meals");
                    //Let the original eat method run
                    res = method.invoke(dinner,args);
                    System.out.println("Wash the dishes after dinner");
                }else{
                    //Let the original drink method run
                    res = method.invoke(dinner,args);
                }
                return res;
            }
        };

        Dinner dinnerProxy =(Dinner) Proxy.newProxyInstance(classLoader,interaces,invocationHandler);
        dinnerProxy.eat("steamed stuffed bun");
//        dinnerProxy.drink();
    }
}

interface Dinner{
    void eat(String foodName);
    void drink();
}

class Person implements Dinner{
    private String name;
    public Person(String name) {
        this.name = name;
    }

    @Override
    public void eat(String foodName) {
        System.out.println(name+"I am eating"+foodName);
    }

    @Override
    public void drink() {
        System.out.println(name+"I'm drinking tea");
    }
}

class Student implements Dinner {
    private String name;

    public Student(String name) {
        this.name = name;
    }

    @Override
    public void eat(String foodName) {
        System.out.println(name + "Eating in the canteen" + foodName);
    }

    @Override
    public void drink() {
        System.out.println(name + "I'm drinking coke");
    }
}

summary

  • 1. Enhance the object function without modifying the original code or there is no way to modify the original code. Use the proxy object to replace the original object to complete the function successfully
    So as to achieve the purpose of expanding functions
  • 2. JDK Proxy dynamic proxy interface oriented dynamic proxy must have the existence of interface and implementation class. The proxy object enhances the method rewritten by the implementation class in the method of implementing the interface
    • The generated proxy object can only be converted into an interface, not a proxy class
    • Proxy objects can only enhance the methods defined in the interface, and other interface independent methods in the implementation class cannot be enhanced
    • The proxy object can only read the annotation on the method in the interface, and cannot read the annotation on the implementation class method

b. CGLIB dynamic proxy

1. It is oriented to the parent class and has no direct relationship with the interface
2. Not only one method in the interface, but also other methods that can be enhanced
3. You can read all annotations on Methods in the parent class

package com.xiaohui.testCglib;

import org.junit.Test;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @ClassName Test01
 **/
public class Test01 {
    @Test
    public void testCglib() {
        //Get a Person object
        Person person = new Person();
        //1. Get an Enhancer object
        Enhancer enhancer = new Enhancer();
        //2. Set parent bytecode
        enhancer.setSuperclass(person.getClass());
        //3. Gets the MethodInterceptor object used to define enhancement rules
        MethodInterceptor methodInterceptor = new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                /*
                Object o, The generated proxy object personProxy
                Method method,  The original method to be executed in the parent class is person > > > eat()
                Object[] objects,  The array of arguments passed in when the method is called
                MethodProxy methodProxy Override the method personproxy > > > eat() of the parent class in the subclass
                */
                Object res = null;
                if (method.getName().equals("eat")) {
                    System.out.println("Please wash your hands before meals");
                    res = methodProxy.invokeSuper(o, objects);
                    System.out.println("Please wash the dishes after dinner");
                } else {
                    res = methodProxy.invokeSuper(o, objects);
                }
                return res;
            }
        };
        //4. Callback setting methodInterceptor
        enhancer.setCallback(methodInterceptor);
        //5. Get proxy object
        Person person1 = (Person) enhancer.create();
        //6. Use proxy objects to complete functions
        person1.eat("steamed stuffed bun");
    }
}

class Person {
    public Person() {
    }

    public void eat(String foodName) {
        System.out.println("Zhang San is eating" + foodName);
    }
}

class Son extends Person{
    public Son() {
        super();
    }

    @Override
    public void eat(String foodName) {
        System.out.println("Please wash your hands before meals");
        super.eat(foodName);
        System.out.println("Please wash the dishes after dinner");
    }
}

Keywords: Java Spring

Added by Dillinger on Thu, 10 Feb 2022 21:03:58 +0200