Spring IOC

The main content

The Spring framework

Spring Framework Concepts

Spring is one of many open source Java projects. It is a one-stop lightweight open source framework based on layered javaEE applications. The main core technologies are IOC (Inversion of Control/Dependency Injection) and AOP (aspect oriented), which achieve easy decoupling of projects in the development process and improve the development efficiency of projects.

Introducing Spring into your project immediately brings the following benefits: reducing coupling between components and decoupling between layers of software. You can use many of the services provided by the container, such as transaction management services, messaging services, and so on. When we use container-managed transactions, developers no longer need to manually control transactions. There is no need to deal with complex transaction propagation. The container provides singleton support, eliminating the need for developers to write their own implementation code. The container provides AOP technology that makes it easy to implement functions such as permission interception and runtime monitoring.

Spring Source Architecture

In total, Spring has about 20 modules, made up of more than 1,300 different files. These components are integrated in Core Container, Aop (Aspect Oriented Programming), and Device support, and Data access and integration, respectively Access/Integeration), Web, message sending (Messaging), test 6 modules set.

  1. Core container: Spring-beans and spring-core modules are the core modules of the Spring framework, Containing Inversion of Control (IoC) and Dependency Injection (DI), the core container provides the basic functionality of the Spring framework. The main component of the core container is the BeanFactory, the implementation of the factory pattern. BeanFactory uses inversion of control (IOC) ideas to separate application configuration and dependency specifications from the actual application code.

    Spring Context: The Spring Context is a configuration file that provides Context information to the Spring framework. The Spring context includes enterprise services, such as JNDI, EJB, E-mail, internationalization, validation, and scheduling capabilities.

    Spring-expression module is an extension module of Unified EL. It can query and manage running objects, call object methods, operate arrays, and collections conveniently. Its syntax is similar to traditional EL, but it provides additional functionality, most notably function calls and simple string template functions.

  2. Spring-aop: Spring-AOP is another core module of Spring. In Spring, it is based on the DYNAMIC proxy technology of the JVM, and then designs a series of CROSScutting implementations of AOP, such as pre-notification, return notification, exception notification, etc. With its configuration management features, the Spring AOP module integrates section-oriented programming capabilities directly into the Spring framework. So, you can easily make any object managed by the Spring framework AOP enabled.

  3. Spring Data Access: Spring-jdbc module consists of spring-JDBC, Spring-TX, spring-ORM, spring-JMS and spring-OXM. Spring-jdbc module is the main implementation module of JDBC abstract framework provided by Spring. For simplifying Spring JDBC.

    The Spring-TX module is the SpringJDBC transaction control implementation module. Using the Spring framework, transactions are well encapsulated and can be configured flexibly at any layer through its Aop configuration.

    Spring-orm module is an Orm framework support module, mainly integrating Hibernate, Java Persistence API (JPA) and Java Data Objects (JDO) for resource management, Data access object (DAO) implementation and transaction strategy.

    The Spring-JMS module (Java Messaging Service) can send and receive messages.

    The Spring-OXM module mainly provides an abstraction layer to support Oxm (Oxm stands for object-to-XML-Mapping, which is an O/M-mapper that maps Java objects to XML data or XML data to Java objects), for example: JAXB, Castor, XMLBeans, JiBX, XStream, and more.

  4. The Web module: It is composed of spring-Web, Spring-WebMVC, Spring-WebSocket and spring-WebMVC-portlet. The Web context module is built on the application context module and provides the context for web-based applications. The Web module also simplifies handling multi-part requests and binding request parameters to domain objects.

  5. Message sending: namely, the Spring-Messaging module.

    Spring-messaging is a new module added in Spring4. Its main responsibility is to integrate some basic message delivery applications for the Spring framework.

  6. Unit tests: that is, the Spring-test module. The Spring-test module mainly provides support for testing

Spring framework environment construction

Environmental requirements

JDK version:

JDK 1.7 or later

The Spring version:

Spring 5. X version

Creating a New Maven Project

  1. Create Maven’s normal Java project
  2. Set the coordinates of the project
  3. Set up the Maven environment for your project
  4. Set the name of the project and the workspace to store it in

Adjust the project environment

  1. Modifying the JDK version

    <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <maven.compiler.source>1.8</maven.compiler.source>
      <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    Copy the code
  2. Modify the unit test JUnit version

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    Copy the code
  3. The pluginManagement tag in the Build tag

    <! Remove the pluginManagement tag from the build tag -->
    <build>
    </build>
    Copy the code

Add Spring framework dependency coordinates

Maven repository: mvnrepository.com/

<! Add Spring framework core dependencies -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.4. RELEASE</version>
</dependency>
Copy the code

Writing Bean objects

package com.xxxx.service;

public class UserService {

    public void test(a){
        System.out.println("Hello Spring!"); }}Copy the code

Add the Spring configuration file

  1. Create folder Resources (Alt+insert) under project SRC

  2. Mark Resources as a resource directory

  3. Create a new spring. XML file under SRC \main\ Resources and copy the template content provided by the official documentation into the XML.

    Configure beans into XML and incorporate the corresponding beans into the Spring container for management

    spring.xml

    
            
    <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 https://www.springframework.org/schema/beans/spring-beans.xsd">
    
       <! XML namespace XML namespace XMLNS: XSI XML schema instance XML compliance specification xSI :schemaLocation XML compliance specification in this document
       <bean id="userService" class="com.xxxx.service.UserService"></bean>
    
    </beans>
    Copy the code
  4. Configure the Bean object in spring.xml

    <! -- id: the unique id of the bean object. Class: The class path of the Bean object -->
    <bean id="userService" class="com.xxxx.service.UserService"></bean>
    Copy the code

Load the configuration file to get the instantiated object

package com.xxxx;

import com.xxxx.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        // Get the Spring context (load the configuration file)
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        // Use the getBean method to get the instantiated Bean object in the Spring container (instantiated Bean object)
        // userService represents the id attribute value of the bean label in the configuration file
        UserService userService = (UserService) ac.getBean("userService");
        // Call methods (using instantiated objects)userService.test(); }}Copy the code

Spring IOC container Bean object instantiation emulation

Ideas:

  1. Defines a Bean factory interface that provides methods to get beans

  2. Define the Bean factory interface implementation class, parse the configuration file, and instantiate the Bean object

  3. Implement the get Bean method

Define Bean property objects

package com.xxxx.spring;

/** * the bean object is used to receive the bean tag id and class attribute value in the configuration file */
public class MyBean {

    private String id; // The id attribute value of the bean object
    private String clazz; // The class path of the bean object

    public MyBean(a) {}public MyBean(String id, String clazz) {
        this.id = id;
        this.clazz = clazz;
    }

    public String getId(a) {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getClazz(a) {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz; }}Copy the code

Add dom4J coordinate dependencies

<! -- dom4j -->
<dependency>
    <groupId>dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>1.6.1</version>
</dependency>
<! -- XPath -->
<dependency>
    <groupId>jaxen</groupId>
    <artifactId>jaxen</artifactId>
    <version>1.1.6</version>
</dependency>
Copy the code

Prepare a custom configuration file

spring.xml


      
<beans>
    <bean id="userService" class="com.xxxx.service.UserService"></bean>
    <bean id="accountService" class="com.xxxx.service.AccountService"></bean>
</beans>
Copy the code

Define the Bean factory interface

package com.xxxx.spring;

/** * Bean factory interface definition */
public interface MyFactory {
    // Get the object by id value
    public Object getBean(String id);
}
Copy the code

Defines the implementation class for the Bean interface

package com.xxxx.spring;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** * : /** * : /** * : /** * : /** * Instantiate class.forname (full path of class).newinstance (); Map
      
        store * 4, get the specified instantiation object */
      ,class>
public class MyClassPathXmlApplicationContext implements BeanFactory {

    private Map beans = new HashMap(); // Put the instantiated object into the map
    private List<MyBean> myBeans; // Store the read bean configuration information

    /* get the configuration file */ from the constructor
    public MyClassPathXmlApplicationContext(String fileName) {

        / * 2, by dom4j to parse the XML file, get the List (deposit id and class) * /
        this.parseXml(fileName);

        /* instantiate Class.forname (Class path).newinstance (); Store */ through Map
        this.instanceBean();

    }

    /** * select * from dom4j; /** * from dom4j; /** * from dom4j; Parse the document object with the specified syntax and return collection * 6. Check if the collection is empty and iterate over the collection * 7. Get the attributes in the label element * 8@param fileName
     */
    private void parseXml(String fileName) {
        // get the parser
        SAXReader reader = new SAXReader();
        // get the configuration file URL
        URL url = this.getClass().getClassLoader().getResource(fileName);
        try {
            // 3. Parse the XML file with a parser (spring.xml)
            Document document = reader.read(url);
            // Get all bean tags from beans by using xpath syntax
            XPath xPath = document.createXPath("beans/bean");
            // Parse the document object by specifying the syntax to return the collection
            List<Element> list = xPath.selectNodes(document);
            // Check whether the set is empty
            if(list ! =null && list.size() > 0) {
                myBeans = new ArrayList<>();
                for(Element el : list) {
                    // Get the attributes in the tag element
                    String id = el.attributeValue("id"); // id attribute value
                    String clazz = el.attributeValue("class"); // The class attribute value
                    System.out.println(el.attributeValue("id"));
                    System.out.println(el.attributeValue("class"));
                    // Get the Bean object
                    MyBean bean = new MyBean(id, clazz);
                    // Set the Bean object to the collectionmyBeans.add(bean); }}}catch(DocumentException e) { e.printStackTrace(); }}/** * Instantiate the object class.forname (Class full path).newinstance (); * Store */ by Map
      ,class>
    private void instanceBean(a) {
        // Check whether the bean collection is empty. If it is not empty, the corresponding bean object is traversed
        if(myBeans ! =null && myBeans.size() > 0) {
            for (MyBean bean : myBeans){                                      
                try {
                    // Instantiate the object through the class's full path
                    Object object = Class.forName(bean.getClazz()).newInstance();
                    // Set the ID and instantiation object to the map object
                    beans.put(bean.getId(), object);
                } catch(Exception e) { e.printStackTrace(); }}}}/** * Get the specified value * in the map by key@param id
     * @return* /
    @Override
    public Object getBean(String id) {
        Object object = beans.get(id);
        returnobject; }}Copy the code

Test custom IOC containers

  1. Create the Bean object that corresponds to the configuration file

    UserService.java

    package com.xxxx.service;
     
    public class UserService {
     
        public void test(a){
            System.out.println("UserService Test..."); }}Copy the code

    AccountService.java

    package com.xxxx.service;
    
    public class AccountService {
    
        public void test(a){
            System.out.println("AccountService Test..."); }}Copy the code
  2. Tests whether the instantiated Bean object can be retrieved

    package com.xxxx;
    
    import com.xxxx.spring.MyFactory;
    import com.xxxx.spring.MyClassPathXmlApplicationContext;
    import com.xxxx.service.AccountService;
    import com.xxxx.service.UserService;
    
    public class App {
        
        public static void main(String[] args) {
            MyFactory factory = new MyClassPathXmlApplicationContext("spring.xml");
            // Get the instantiated object
            UserService userService = (UserService) factory.getBean("userService");
            userService.test();
    
            UserService userService2 = (UserService) factory.getBean("userService");
            System.out.println(userService+"= = = = =" + userService2);
    
    
            AccountService accountService = 
            (AccountService)factory.getBean("accountService"); accountService.test(); }}Copy the code

    The Spring container reads the XML configuration information at startup, instantiates the configured bean, and retrieves our configured bean object via the getBean() method provided by the context object. This enables the external container to automatically maintain and create beans.

The Spring IOC configuration file is loaded

Spring configuration file loaded

spring.xml


      
<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 https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="userService" class="com.xxxx.service.UserService"></bean>
</beans>
Copy the code

Load resources based on relative paths

ApplicationContext ac  = new ClassPathXmlApplicationContext("spring.xml");
Copy the code

Load resources by absolute path (Understanding)

ApplicationContext ac = new FileSystemXmlApplicationContext("C:/IdeaWorkspace/spring01/src/main/resources/spring.xml");       
Copy the code

Spring multiple configuration file loading

The Spring framework can load multiple configuration files into the environment when it starts. For complex projects, there may be multiple profiles that are loaded simultaneously when the project starts deployment.

service.xml


      
<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 https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="userService" class="com.xxxx.service.UserService"></bean>
</beans>
Copy the code

dao.xml


      
<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 https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="userDao" class="com.xxxx.dao.UserDao"></bean>
</beans>
Copy the code

Variable argument, passing in multiple file names

// Load multiple resource files simultaneously
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml"."dao.xml");
Copy the code

Import other configuration files from the general configuration file

spring.xml


      
<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 https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <! Import the resource file to include -->
    <import resource="service.xml"/>
    <import resource="dao.xml"/>
</beans>
Copy the code

You only need to load the total configuration file

// Load the total resource file
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
Copy the code

Spring IOC container Bean object instantiation

Constructor instantiation

Note: Creating an empty constructor with the default constructor must exist or the creation fails

  1. Set up the configuration file spring.xml

    
            
    <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 https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="userService" class="com.xxxx.service.UserService"></bean>
    
    </beans>
    Copy the code
  2. Gets the instantiated object

    ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
    UserService userService = (UserService) ac.getBean("userService");  
    userService.test();
    Copy the code

Static Factory instantiation (Awareness)

Note:

  • Have the factory class and factory method
  • The factory method is static
  1. Define a static factory class

    package com.xxxx.factory;
    
    import com.xxxx.service.UserService;
    
    /** * define static factory class */
    public class StaticFactory {
        /** * defines the corresponding static method that returns the instantiated object *@return* /
        public static UserService createUserService(a) {
            return newUserService(); }}Copy the code
  2. Set up the configuration file spring.xml

    
            
    <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 https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <! -- Static factory -->
        <bean id="userService" class="com.xxxx.factory.StaticFactory" factory-method="createUserService"></bean>
    
    </beans>
    Copy the code
  3. Gets the instantiated object

    ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
    UserService userService = (UserService) ac.getBean("userService");  
    userService.test();
    Copy the code

    When we specify that Spring uses static factory methods to create Bean instances, Spring first parses the configuration file and, based on the information specified in the configuration file, invokes the static factory method of the static factory class through reflection, taking the return value of the static factory method as the Bean instance. In this process, Spring is no longer responsible for creating Bean instances, which are provided by static factory methods provided by the user.

Instance Chemical plant instantiation (Understanding)

Note:

  • The factory method is a non-static method
  • You need to configure the factory bean and configure the factory-bean, factory-method properties in the business bean
  1. Defining a factory class

    package com.xxxx.factory;
    
    import com.xxxx.service.UserService;
    
    /** * defines the factory class */
    public class InstanceFactory {
        /** * defines a method that returns the instantiated object *@return* /
        public UserService createUserService(a) {
            return newUserService(); }}Copy the code
  2. Set up the configuration file spring.xml

    
            
    <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 https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <! 2. Reference the factory bean to specify the factory creation method (method non-static) -->
        <bean id="instanceFactory" class="com.xxxx.factory.InstanceFactory"></bean>
        <bean id="userService" factory-bean="instanceFactory" factory-method="createUserService"></bean>
    
    </beans>
    Copy the code
  3. Gets the instantiated object

    ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
    UserService userService = (UserService) ac.getBean("userService");  
    userService.test();
    Copy the code

Compare the three ways Spring instantiates beans

  • Method 1: Create from the bean’s default constructor, which can be used when the business logic of each bean is relatively independent of each other or less associated with the outside world.

  • Method 2: using static factory method to create, you can unified management of the creation of each bean, such as each bean before the creation of the same initialization process, you can use the factory method for unified processing and so on.

  • Method 3: instantiate factory method creation, that is, factory method also as a business bean to control, 1 can be used to integrate other framework bean creation management method, 2 can make bean and factory role swap.

    In development projects, there is usually one way to instantiate beans. Project development basically adopts the first way, which is hosted by Spring and used directly. Two other understandings

Spring IOC injection

Manual instantiation versus external import

Graph one:

Figure 2:

By comparison, it is found that the creation of the UserDao object in Figure 2 does not actively de-instantiate as in Figure 1. Instead, the UserDao is passed in in the form of parameterized methods, so as to realize the dependence of UserService on the UserDao class.

The actual objects behind the scenes are created externally.

Spring IOC Manual Assembly (injection)

Spring supports four types of injection: Set injection, constructor injection, static factory injection, and instance-chemical injection.

Set method injection

Note:

  • Property fields need to provide set methods
  • The set method is recommended
Business object Javabeans
  1. The property field provides the set method

    public class UserService {
    
        // Business object UserDao set injection (provide set method)
        private UserDao userDao;
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao; }}Copy the code
  2. The bean label of the configuration file sets the property label

    
            
    <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 https://www.springframework.org/schema/beans/spring-beans.xsd">
        
       <! = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 
        <bean id="userDao" class="com.xxxx.dao.UserDao"></bean>
    	<bean id="userService" class="com.xxxx.service.UserService">
            <! -- Business object injection -->
            <property name="userDao" ref="userDao"/>
        </bean>
    </beans>
    Copy the code
Common objects and primitive types
  1. The property field provides the set method

    public class UserService {
    
        // Insert a set into a String.
        private String host;
        public void setHost(String host) {
            this.host = host;
        }
    
        // Primitive type Integer set injection (provides set methods)
        private Integer port;
        public void setPort(Integer port) {
            this.port = port; }}Copy the code
  2. The bean label of the configuration file sets the property label

    
            
    <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 https://www.springframework.org/schema/beans/spring-beans.xsd">
        
       <! - the IOC through property label manual assembly (injection) : Set method injection name: bean object property field value: the name of the specific value (basic types Common object | date collection) -- -- > 
    	<bean id="userService" class="com.xxxx.service.UserService">
            <! -- String injection -->
            <property name="host" value="127.0.0.1"/>
            <! -- Basic type injection -->
            <property name="port" value="8080"/>
        </bean>
    
    </beans>
    Copy the code
Collection type and property object
  1. The property field provides the set method

    public class UserService {
    
        // List set injection (provide set method)
        public List<String> list;
        public void setList(List<String> list) {
            this.list = list;
        }
       
    
        // Set Set injection (provide Set method)
        private Set<String> set;
        public void setSet(Set<String> set) {
            this.set = set;
        }
    
    
        // Map set injection (provide set method)
        private Map<String,Object> map;
        public void setMap(Map<String, Object> map) {
            this.map = map;
        }
        
    
        // Properties set injection (provide set method)
        private Properties properties;
        public void setProperties(Properties properties) {
            this.properties = properties; }}Copy the code
  2. The bean label of the configuration file sets the property label

    
            
    <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 https://www.springframework.org/schema/beans/spring-beans.xsd">
        
       <! - the IOC through property label manual assembly (injection) : Set method injection name: bean object property field value: the name of the specific value (basic types Common object | date collection) -- -- > 
    	<! --List set injection -->
        <property name="list">
            <list>
                <value>Shanghai</value>
                <value>Beijing</value>
                <value>hangzhou</value>
            </list>
        </property>
    
        <! --Set Set injection -->
        <property name="set">
            <set>
                <value>Shanghai SH</value>
                <value>Beijing BJ</value>
                <value>Hangzhou HZ</value>
            </set>
        </property>
    
        <! - the Map into -- -- >
        <property name="map">
            <map>
                <entry>
                    <key><value>Jay Chou</value></key>
                    <value>I was so convinced</value>
                </entry>
                <entry>
                    <key><value>Jj Lin</value></key>
                    <value>Unfortunately not if</value>
                </entry>
                <entry>
                    <key><value>Eason chan</value></key>
                    <value>In ten years</value>
                </entry>
            </map>
        </property>
    
        <! - the Properties into -- -- >
        <property name="properties">
            <props>
                <prop key="Shanghai">The Oriental pearl tower</prop>
                <prop key="Beijing">The tiananmen square</prop>
                <prop key="Hangzhou">The west lake</prop>
            </props>
        </property>
    
    </beans>
    Copy the code
The test code

UserService.java

public class UserService {

    // Business object UserDao set injection (provide set method)
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    // Insert a set into a String.
    private String host;
    public void setHost(String host) {
        this.host = host;
    }

    // Primitive type Integer set injection (provides set methods)
    private Integer port;
    public void setPort(Integer port) {
        this.port = port;
    }

    // List set injection (provide set method)
    public List<String> list;
    public void setList(List<String> list) {
        this.list = list;
    }
    // List sets output
    public void printList(a) {
        list.forEach(s -> System.out.println(s));
    }

    // Set Set injection (provide Set method)
    private Set<String> set;
    public void setSet(Set<String> set) {
        this.set = set;
    }
    // Set Set output
    public void printSet(a) {
        set.forEach(s -> System.out.println(s));
    }


    // Map set injection (provide set method)
    private Map<String,Object> map;
    public void setMap(Map<String, Object> map) {
        this.map = map;
    }
    / / the Map output
    public void printMap(a) {
        map.forEach((k,v) -> System.out.println(k + "," + v));
    }


    // Properties set injection (provide set method)
    private Properties properties;
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
    / / Properties output
    public  void printProperties(a){
        properties.forEach((k,v) -> System.out.println(k + ","+ v ));
    }



    public  void  test(a){
        System.out.println("UserService Test...");

        userDao.test();

        studentDao.test();

        System.out.println(Host: "" + host  + ", port:" + port);

        / / the List collection
        printList();

        / / Set collection
        printSet();

        // Map
        printMap();

        // PropertiesprintProperties(); }}Copy the code

spring.xml


      
<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 https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <! - the IOC through property label manual assembly (injection) : Set method into the name: the name of the bean object property field in ref: bean label id attribute value specified value: specific values (basic types Common object | date collection) -- -- >
	<bean id="userDao" class="com.xxxx.dao.UserDao"></bean>
    <bean id="userService" class="com.xxxx.service.UserService">
        <! -- Business object injection -->
        <property name="userDao" ref="userDao"/>
        <property name="studentDao" ref="studentDao"/>

        <! -- String injection -->
        <property name="host" value="192.168.1.109"/>
        <! -- Basic type injection -->
        <property name="port" value="8080"/>

        <! --List set injection -->
        <property name="list">
            <list>
                <value>Shanghai</value>
                <value>Beijing</value>
                <value>hangzhou</value>
            </list>
        </property>

        <! --Set Set injection -->
        <property name="set">
            <set>
                <value>Shanghai SH</value>
                <value>Beijing BJ</value>
                <value>Hangzhou HZ</value>
            </set>
        </property>

        <! - the Map into -- -- >
        <property name="map">
            <map>
                <entry>
                    <key><value>Jay Chou</value></key>
                    <value>I was so convinced</value>
                </entry>
                <entry>
                    <key><value>Jj Lin</value></key>
                    <value>Unfortunately not if</value>
                </entry>
                <entry>
                    <key><value>Eason chan</value></key>
                    <value>In ten years</value>
                </entry>
            </map>
        </property>

        <! - the Properties into -- -- >
        <property name="properties">
            <props>
                <prop key="Shanghai">The Oriental pearl tower</prop>
                <prop key="Beijing">The tiananmen square</prop>
                <prop key="Hangzhou">The west lake</prop>
            </props>
        </property>

    </bean>
    
</beans>
Copy the code

Constructor injection

Note:

  • Provides a parameterized constructor
A single Bean object as a parameter

Java code

public class UserService {

    private UserDao userDao; / / JavaBean objects
    
    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }

    public  void  test(a){
        System.out.println("UserService Test..."); userDao.test(); }}Copy the code

The XML configuration


      
<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 https://www.springframework.org/schema/beans/spring-beans.xsd">
	<! Ref: select bean id value from bean tag
    <bean id="userDao" class="com.xxxx.dao.UserDao" ></bean>
    
    <bean id="userService" class="com.xxxx.service.UserService">
        <constructor-arg name="userDao" ref="userDao"></constructor-arg> 
    </bean>

</beans>
Copy the code
Multiple Bean objects as parameters

Java code

public class UserService {

    private UserDao userDao;  / / JavaBean objects
    private AccountDao accountDao  / / JavaBean objects
        
    public UserService(UserDao userDao, AccountDao accountDao) {
        this.userDao = userDao;
        this.accountDao = accountDao;
    }

    public  void  test(a){
        System.out.println("UserService Test..."); userDao.test(); accountDao.test(); }}Copy the code

The XML configuration


      
<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 https://www.springframework.org/schema/beans/spring-beans.xsd">
	 <! Ref: select bean id value from bean tag
    <bean id="userDao" class="com.xxxx.dao.UserDao" ></bean>
    <bean id="accountDao" class="com.xxxx.dao.AccountDao" ></bean>
    
    <bean id="userService" class="com.xxxx.service.UserService">
        <constructor-arg name="userDao" ref="userDao"></constructor-arg> 
        <constructor-arg name="accountDao" ref="accountDao"></constructor-arg>
    </bean>

</beans>
Copy the code
Bean objects and common objects as parameters

Java code

public class UserService {

    private UserDao userDao;  / / JavaBean objects
    private AccountDao accountDao;  / / JavaBean objects
    private String uname;  // A string of characters
        
    public UserService(UserDao userDao, AccountDao accountDao, String uname) {
        this.userDao = userDao;
        this.accountDao = accountDao;
        this.uname = uname;
    }

    public  void  test(a){
        System.out.println("UserService Test...");

        userDao.test();
        accountDao.test();
        System.out.println("uname:"+ uname); }}Copy the code

The XML configuration


      
<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 https://www.springframework.org/schema/beans/spring-beans.xsd">
	<! -- IOC inject via constructor: inject via constructor-arg tag name: attribute name ref: id attribute value of bean tag value: basic type common object value index: subscript of constructor parameter starting from 0 -->
    <bean id="userDao" class="com.xxxx.dao.UserDao" ></bean>
    <bean id="accountDao" class="com.xxxx.dao.AccountDao" ></bean>
    <bean id="userService" class="com.xxxx.service.UserService">
        <constructor-arg name="userDao" ref="userDao"></constructor-arg> 
        <constructor-arg name="accountDao" ref="accountDao"></constructor-arg>
        <constructor-arg name="uname" value="admin"></constructor-arg>
    </bean>

</beans>
Copy the code
Cyclic dependency problem

Causes of circulation problems:

Beans are injected through constructors, so they depend on each other and cannot be instantiated.

Problem presentation:

  1. Java code

    public class AccountService {
    
        private RoleService roleService;
    
       public AccountService(RoleService roleService) {
            this.roleService = roleService;
        }
    
        public void  test(a) {
            System.out.println("AccountService Test..."); }}public class RoleService {
    
        private AccountService accountService;
    
       public RoleService(AccountService accountService) {
            this.accountService = accountService;
        }
    
        public void  test(a) {
            System.out.println("RoleService Test..."); }}Copy the code
  2. The XML configuration

    <! If multiple bean objects are injected into each other, the problem of circular dependency can be solved by using the set method injection.
    <bean id="accountService" class="com.xxxx.service.AccountService">
        <constructor-arg name="roleService" ref="roleService"/>
    </bean>
    
    <bean id="roleService" class="com.xxxx.service.RoleService">
        <constructor-arg name="accountService" ref="accountService"/>
    </bean>
    Copy the code

How to solve: Replace constructor injection with SET method injection

  1. Java code

    public class AccountService {
    
        private RoleService roleService;
    
       /* public AccountService(RoleService roleService) { this.roleService = roleService; } * /
    
        public void setRoleService(RoleService roleService) {
            this.roleService = roleService;
        }
    
        public void  test(a) {
            System.out.println("AccountService Test..."); }}public class RoleService {
    
        private AccountService accountService;
    
       /* public RoleService(AccountService accountService) { this.accountService = accountService; } * /
    
        public void setAccountService(AccountService accountService) {
            this.accountService = accountService;
        }
    
        public void  test(a) {
            System.out.println("RoleService Test..."); }}Copy the code
  2. The XML configuration

    <! -- <bean id="accountService" class="com.xxxx.service.AccountService"> <constructor-arg name="roleService" ref="roleService"/> </bean> <bean id="roleService" class="com.xxxx.service.RoleService"> <constructor-arg name="accountService" ref="accountService"/> </bean> -->
    <! Set method injection -->
    <bean id="accountService" class="com.xxxx.service.AccountService">
        <property name="roleService" ref="roleService"/>
    </bean>
    
    <bean id="roleService" class="com.xxxx.service.RoleService">
        <property name="accountService" ref="accountService"/>
    </bean>
    Copy the code

Static factory injection

  1. Define a static factory class

    public class StaticFactory {
    
        // Define static methods
        public static TypeDao createTypeDao(a) {
            return newTypeDao(); }}Copy the code
  2. Java code

    public class TypeService {
    
        private TypeDao typeDao;
    	
        public void setTypeDao(TypeDao typeDao) {
            this.typeDao = typeDao;
        }
    
        public void  test(a) {
            System.out.println("TypeService Test..."); }}Copy the code
  3. The XML configuration

    Set the bean label in the configuration file, specify the factory object, and set the corresponding method

    <bean id="typeService" class="com.xxxx.service.TypeService">
    	<property name="typeDao" ref="typeDao"/>
    </bean>
    <! Static factory injection: Static factory injection is also injected with the set method, but the instantiation of the injected bean object is instantiated through the static factory.
    <bean id="typeDao" class="com.xxxx.factory.StaticFactory" factory-method="createTypeDao"></bean>
    Copy the code

Example plant injection

  1. Defining a factory class

    public class InstanceFactory {
         public TypeDao createTypeDao(a) {
            return newTypeDao(); }}Copy the code
  2. Java code

    public class TypeService {
    
        private TypeDao typeDao;
    	
        public void setTypeDao(TypeDao typeDao) {
            this.typeDao = typeDao;
        }
    
        public void  test(a) {
            System.out.println("TypeService Test..."); }}Copy the code
  3. The XML configuration

    Declare the factory Bean label, declare the bean object, and specify the factory object and factory methods

    <bean id="typeService" class="com.xxxx.service.TypeService">
    	<property name="typeDao" ref="typeDao"/>
    </bean>
    <! Instance-chemical injection: Instance-chemical injection is also injected through the set method, but the instantiation of the injected bean object is instantiated through the instance-chemical injection.
    <bean id="instanceFactory" class="com.xxxx.factory.InstanceFactory"></bean>
    <bean id="typeDao" factory-bean="instanceFactory" factory-method="createTypeDao"></bean>
    Copy the code

    Focus on the set injection and constructor injection, factory mode to understand. In the actual development, the set mode is basically used to inject beans.

Selection of injection mode

The set mode is injected as a preference in development projects

Injection can use structure in building of objects at the same time as the establishment of complete dependency on the object the establishment of everything is ready, but if you want to build a lot of object relations, will use constructor injection in a long series of building function parameters, and not easy to memory, then using the Set injection will be a good choice. With Set injection, you can have a clear name and know what the injected object will be. A name like setXXX() is better than remembering that the position of a parameter on Constructor represents an object.

The use of the p namespace

In order to simplify setter method property injection after spring2.5, it is possible to simplify child elements into element property configurations by referring to the concept of p namespaces.

  1. The property field provides the set method

    public class UserService {
    
        // Business object UserDao set injection (provide set method)
        private UserDao userDao;
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
        
        // Insert a set into a String.
        private String host;
        public void setHost(String host) {
            this.host = host; }}Copy the code
  2. Introduce the p namespace in the configuration file spring.xml

    xmlns:p="http://www.springframework.org/schema/p"
    Copy the code
    
            
    <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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
        
    	<bean id="userDao" class="com.xxxx.dao.UserDao"></bean>
        <! -ref:=" XXX "-ref:=" XXX" -ref:=" XXX"
        <bean id="userService" class="com.xxxx.service.UserService" 
            p:userDao-ref="userDao" 
            p:host="127.0.0.1" />
    
    </beans>
    Copy the code

Spring IOC auto-assembly (injection)

Annotate injected beans

For bean injection, annotations can be configured in addition to XML configuration. Annotated configurations can simplify configuration files, speed up development, and make programs look more concise. For annotation interpretation, Spring has a special interpreter for annotations that parse the defined annotations and inject the corresponding bean object. By reflection technology.

Prepare the environment

  1. Modifying a Configuration File

    <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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    Copy the code
  2. Enabling Automatic injection

    <! -- Start automatic assembly (injection) -->
    <context:annotation-config/>
    
    <bean id="userDao" class="com.xxxx.dao.UserDao"></bean>
    <bean id="userService" class="com.xxxx.service.UserService"></bean> 
    Copy the code
  3. Annotate the injected bean object

@ Resource annotation

The @Resource annotation implements automatic injection (reflection)

  • By default, the corresponding bean object is found based on the property field name (the name of the property field is equal to the id attribute value of the bean label)
  • If the property field name is not found, it is looked up by type (Class type)
  • Property may or may not provide a set method
  • Annotations can be declared at the attribute level or set method level
  • You can set the name attribute, whose value must be the same as the ID attribute of the bean label. If the name attribute value is set, only the bean object is looked up by the name attribute value
  • When an interface is injected, it is instantiated normally if the interface has only one implementation; If there are multiple implementations of the interface, you need to specify the bean object to be instantiated using the Name attribute

Code sample

  1. By default, the corresponding bean object is found based on the property field name (the name of the property field is equal to the id attribute value of the bean label)

    / * * *@ResourceAnnotations implement automatic injection (reflection) * By default, the corresponding bean object is found based on the name of the property field (the name of the property field is equal to the id property value of the bean label) */
    public class UserService {
    
        @Resource
        private UserDao userDao; // The name of the property field is equal to the id property value of the bean label
    
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public void test(a) {
            // Call the UserDao methoduserDao.test(); }}Copy the code
  2. If the property field name is not found, it is looked up by type (Class type)

    / * * *@ResourceAnnotations implement automatic injection (reflection) * If the property field name is not found, it is looked up by type (Class type) */
    public class UserService {
    
        @Resource
        private UserDao ud; // If the attribute field name (ud) is not found in the configuration file, the corresponding class (type UserDao) will be searched.
    
        public void setUd(UserDao ud) {
            this.ud = ud;
        }
    
        public void test(a) {
            // Call the UserDao methodud.test(); }}Copy the code
  3. Property may or may not provide a set method

    / * * *@ResourceAnnotations implement automatic injection (reflection) * properties that may or may not provide set methods */
    public class UserService {
    
        @Resource
        private UserDao userDao; // The set method is not provided
    
    
        public void test(a) {
            // Call the UserDao methoduserDao.test(); }}Copy the code
  4. Annotations can be declared at the attribute level or set method level

    / * * *@ResourceAnnotations implement automatic injection (reflection) * Annotations can be declared at the attribute level or set method level */
    public class UserService {
    
        private UserDao userDao;
    
        @Resource // Annotations can also be set on the set method
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public void test(a) {
            // Call the UserDao methoduserDao.test(); }}Copy the code
  5. You can set the name attribute, whose value must be the same as the ID attribute of the bean label. If the name attribute value is set, only the bean object is looked up by the name attribute value

    / * * *@ResourceAnnotation implementation automatic injection (reflection) * You can set the name attribute, the name attribute value must be the same as the bean ID attribute value; * If the name attribute value is set, only the bean object */ will be looked up by the name attribute value
    public class UserService {
    
        @Resource(name = "userDao") // The name attribute value is the same as the id attribute value of the bean label in the configuration file
        private UserDao ud;
    
    
        public void test(a) {
            // Call the UserDao methodud.test(); }}Copy the code
  6. When an interface is injected, it is instantiated normally if the interface has only one implementation; If there are multiple implementations of the interface, you need to specify the bean object to be instantiated using the Name attribute

    Define the interface class iUserdao.java

    package com.xxxx.dao;
    
    /** * Defines the interface class */
    public interface IUserDao {
        public void test(a);
    }
    Copy the code

    Define the interface implementation class UserDao01.java

    package com.xxxx.dao;
    
    /** * interface implementation class */
    public class UserDao01 implements IUserDao {
    
        @Override
        public void test(a){
            System.out.println("UserDao01..."); }}Copy the code

    Define the interface implementation class UserDao02.java

    package com.xxxx.dao;
    
    /** * interface implementation class */
    public class UserDao02 implements IUserDao {
    
        @Override
        public void test(a){
            System.out.println("UserDao02..."); }}Copy the code

    XML configuration file

    <! -- Start automatic assembly (injection) -->
    <context:annotation-config/>
    
    <bean id="userService" class="com.xxxx.service.UserService"></bean>
    
    <bean id="userDao01" class="com.xxxx.dao.UserDao01"></bean>
    <bean id="userDao02" class="com.xxxx.dao.UserDao01"></bean>
    Copy the code

    Use the annotation userService.java

    / * * *@ResourceAnnotation implements automatic injection (reflection) * When injecting an interface, instantiate normally if the interface has only one implementation; If there are multiple implementations of the interface, you need to specify the bean object */ to be instantiated using the name attribute
    public class UserService {
    
        @Resource(name = "userDao01") // The name attribute value is the same as the id attribute value of the bean tag of one of the implementation classes
        private IUserDao iUserDao; // Inject interface (there are multiple implementations of the interface)
    
        public void test(a) { iUserDao.test(); }}Copy the code

The @autowired annotation

The @autowired annotation enables automatic injection:

  • The default is to find bean objects by type (Class type) regardless of the name of the property field
  • Property may or may not provide a set method
  • Annotations can be declared at the attribute level or set method level
  • You can use it in combination with @Qualifier to find bean objects using the value attribute value (value must be set and match the id attribute value of the bean tag).
  1. The default is to find bean objects by type (Class type) regardless of the name of the property field

    / * * *@AutowiredThe default is to find bean objects by type (Class type) regardless of the name of the property field */
    public class UserService {
    
        @Autowired
        private UserDao userDao; // By default, bean objects are found by type (Class type) regardless of the name of the property field
    
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public void test(a) {
            // Call the UserDao methoduserDao.test(); }}Copy the code
  2. Property may or may not provide a set method

    / * * *@AutowiredAnnotations implement automatic injection * properties that may or may not provide a set method */
    public class UserService {
    
        @Autowired
        private UserDao userDao; // The set method is not provided
    
        public void test(a) {
            // Call the UserDao methoduserDao.test(); }}Copy the code
  3. Annotations can be declared at the attribute level or set method level

    / * * *@AutowiredAnnotations implement automatic injection * Annotations can be declared at the attribute level or set method level */
    public class UserService {
    
        private UserDao userDao; 
    
        @Autowired// Annotations can be declared at the set method level
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public void test(a) {
            // Call the UserDao methoduserDao.test(); }}Copy the code
  4. You can use it in combination with @Qualifier to find bean objects using the value attribute value (value must be set and match the id attribute value of the bean tag).

    / * * *@AutowiredAnnotation implementation automated injection * can be added@QualifierIn combination, finding the bean object by value property value must be set, and the value must correspond to the bean label ID property value */
    public class UserService {
    
        @Autowired
        @Qualifier(value="userDao") // value the value of the attribute must be set, and the value must correspond to the id attribute value of the bean label
        private UserDao userDao;
    
        public void test(a) { userDao.test(); }}Copy the code

    The ** @resource ** annotation is recommended for J2EE and reduces coupling to Spring.

Spring IOC scanner

In the actual development, the number of beans is very large, and manual configuration of beans can no longer meet the production needs. Spring also provides scanning mode at this time, which can uniformly manage the scanned bean objects, simplify development configuration and improve development efficiency.

Configuration of the Spring IOC scanner

The Spring IOC scanner does: If the bean object is not in the specified package scope, even if the annotation is declared, it cannot be instantiated. If the annotation is specified (declared at the class level), the id attribute of the bean object defaults to the Dao layer of the class. @Repository Service layer: @service Controller layer: @Controller Arbitrary class: @Component Note: It is recommended to declare annotations according to specified rules during developmentCopy the code
  1. Set the automatic scan range

    
            
    <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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
        <! -- Set the range of automatic scan -->
        <context:component-scan base-package="com.xxxx"/>
    
    </beans>
    Copy the code
  2. Use specific annotations

    @repository (Dao layer)

    @Repository
    public class ResourceDao {
    
        public void  test(a) {
            System.out.println("ResourceDao..."); }}Copy the code

    @service (Service layer)

    @Service
    public class ResourceService {
    
        @Resource
        private ResourceDao resourceDao; // The Service layer injects dao layer bean objects
    
        public  void  test(a) {
            System.out.println("ResourceService..."); resourceDao.test(); }}Copy the code

    @controller (Controller layer)

    @Controller
    public class ResourceController {
    
        @Autowired
        private ResourceService resourceService; // The Controller layer injects the service layer bean object
    
        public  void  test(a) {
            System.out.println("ResourceController..."); resourceService.test(); }}Copy the code

    @Component (arbitrary layer)

    @Component
    public class PropertyUtils {
        public void test(a){
            System.out.println("PropertyUtils..."); }}Copy the code

Spring simulates the user login process

Dao Layer (Query user records)

  1. Define javabeans User. Java

    package com.xxxx.po;
    
    /** * User User entity class */
    public class User {
    
        private String userName; // User name
        private String userPwd; // User password
    
        public String getUserName(a) {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getUserPwd(a) {
            return userPwd;
        }
    
        public void setUserPwd(String userPwd) {
            this.userPwd = userPwd; }}Copy the code
  2. Write the Dao layer, userdao.java

    package com.xxxx.dao;
    
    import com.xxxx.po.User;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public class UserDao {
        
        private final String USERNAME = "admin";
        private final String USERPWD = "admin";
        
        /** * Query user object * by user name@param userName
         * @return* /
        public User queryUserByUserName(String userName){
            User user = null;
            // Check whether the user name is correct
            if(! USERNAME.equals(userName)){// If not, return null
                return null;
            }
            // If correct, set the user name and password to the user object
            user = new User();
            user.setUserName(USERNAME);
            user.setUserPwd(USERPWD);
    
            returnuser; }}Copy the code

Service layer (Business logic processing)

  1. Define the business process return MessageModel messagemodel.java

    package com.xxxx.po.vo;
    
    /** * Defines the business process return message model * encapsulates the return result */
    public class MessageModel {
    
        private Integer resultCode = 1; // Result Status code 1= success, 0= failure
        private String resultMsg = "Operation successful!"; // Result message
    
        public Integer getResultCode(a) {
            return resultCode;
        }
    
        public void setResultCode(Integer resultCode) {
            this.resultCode = resultCode;
        }
    
        public String getResultMsg(a) {
            return resultMsg;
        }
    
        public void setResultMsg(String resultMsg) {
            this.resultMsg = resultMsg; }}Copy the code
  2. Write the Service layer, userService.java

    package com.xxxx.service;
    
    import com.xxxx.dao.UserDao1;
    import com.xxxx.po.User;
    import com.xxxx.po.vo.MessageModel;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    
    @Service
    public class UserService {
        @Resource
        private UserDao userDao;
    
        /** * Verify user login *@param userName
         * @param userPwd
         * @return* /
        public MessageModel userLoginCheck(String userName, String userPwd){
            // Define the business process return message model
            MessageModel messageModel = new MessageModel();
            // Check whether the user name is not empty
            if(null == userName || "".equals(userName.trim())){
                messageModel.setResultCode(0);
                messageModel.setResultMsg("User name cannot be empty!");
                return messageModel;
            }
            // Check whether the user password is empty
            if(null == userPwd || "".equals(userPwd.trim())){
                messageModel.setResultCode(0);
                messageModel.setResultMsg("The password cannot be empty!");
                return messageModel;
            }
            // Query user objects by user name
            User user = userDao.queryUserByUserName(userName);
            // Determine whether the user object is empty
            if(null == user){
                messageModel.setResultCode(0);
                messageModel.setResultMsg("This user does not exist!");
                return messageModel;
            }
            // If the user object is not empty, check whether the password is correct
            if(! user.getUserPwd().equals(userPwd)){ messageModel.setResultCode(0);
                messageModel.setResultMsg("User password is incorrect!");
                return messageModel;
            }
            // Login succeeded
            messageModel.setResultMsg("Login successful!");
            
            returnmessageModel; }}Copy the code

Controller Layer (receiving requests)

  1. Write the Controller layer userController.java

    package com.xxxx.controller;
    
    import com.xxxx.po.vo.MessageModel;
    import com.xxxx.service.UserService1;
    import org.springframework.stereotype.Controller;
    
    import javax.annotation.Resource;
    
    @Controller
    public class UserController {
        @Resource
        private UserService userService;
    
        /** * User login *@param userName
         * @param userPwd
         * @return* /
        public MessageModel login(String userName, String userPwd){
            // Call the Dao layer to determine the user login operation and return the result
            MessageModel messageModel = userService.userLoginCheck(userName, userPwd);
            returnmessageModel; }}Copy the code

Test with JUnit

package com.xxxx;

import com.xxxx.controller.UserController;
import com.xxxx.po.vo.MessageModel;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class  {

    @Test
    public void test(a) {
        // Get the Spring container context
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        // Get the UserController instantiation object
        UserController userController = (UserController) ac.getBean("userController");
        // The passed argument calls the UserController method, returning the wrapper class
        MessageModel messageModel= userController.login("admin"."admin");

        System.out.println("Status code: + messageModel.getResultCode() + ", prompt message:"+ messageModel.getResultMsg()); }}Copy the code

The scope and life cycle of the Bean

The scope of the Bean

By default, objects we get from the Spring container are singletons, with the following scoped types for beans:

The singleton scope

Note: Lazy-init is lazy loading. If true, lazy-init means that the bean is not instantiated when the Spring container is started, but is instantiated when the program is called. The default is false when the Spring container is instantiated at startup.

By default, only one instance of a managed bean exists in the IOC container, and the Spring container returns only the same bean for all operations that fetch that bean.

The container instantiates all singleton bean objects on startup and caches dd>

The lazy-init attribute, if false, instantiates the bean object when the IOC container starts. The default false, if true, does not instantiate the bean object when the IOC container starts, but only when the bean object is used

What good is lazy-init set to false? 1) Potential configuration problems can be discovered in advance. 2) Bean objects are stored in the cache, so there is no need to instantiate beans when using them, which speeds up the running efficiency of the program

What objects are suitable as singletons? In general, the singleton pattern is suitable for stateless or immutable objects. (There are no member variables that change the state of the object.) For example: Controller layer, Service layer, DAO layer

What is an object that is stateless or whose state cannot be changed?

In fact, the change of object state is often caused by the change of attribute value. For example, the name attribute of user class will change, and the change of attribute name will generally cause the change of user object state. For our program, stateless objects do not have instance variables to ensure the safety of threads, service layer business objects are stateless objects. Thread-safe.

The prototype scope

Scope =”prototype” sets the type of the bean. Each request to the Spring container for the bean returns a new bean, as opposed to “Singleton”, which does not cache the bean and creates a new bean based on the bean definition.

Scope in Web applications

  1. The request scope

    Indicates that each request requires the container to create a new Bean. For example, the data submitted to the form must be a new Bean for each request to hold the form data and be released at the end of the request.

  2. Session scope

    Indicates that each session requires the container to create a new Bean. For example, there is usually one session for each user, and the user information of the user needs to be stored in the session. In this case, you can set the scope of the Bean to the session level.

  3. GlobalSession scope

    Similar to the Session scope, it is used for Web applications in a portlet environment (portlets are Java-based Web components managed by a portlet container that handles requests and produces dynamic content). This is considered session scoped in a non-portlet environment.

The configuration is the same as the basic scopes, but the web environment must support it, and the corresponding container listener or interceptor must be configured to apply these scopes.

The life cycle of the Bean

Compare what you’ve learned about the servlet lifecycle (the container starts loading and instantiating the servlet class, initializes the servlet, calls the service method, and destroys the servlet).

There is also the concept of a lifecycle for Spring container-managed beans

In Spring, the Bean life cycle consists of four phases: Bean definition, initialization, use, and destruction

The definition of a Bean

In Spring, beans are typically defined through configuration documents.

Multiple beans can be defined in a configuration document.

Initialization of the Bean

By default, objects are instantiated when the IOC container is loaded.

There are two ways to initialize a Spring bean:

** Method 1: ** This is done by specifying the init-method property in the configuration document.

public class RoleService {
    // Define the methods that need to be called during initialization
    public void init(a) {
        System.out.println("RoleService init..."); }}Copy the code
<! -- Specify method with init-method property -->
<bean id="roleService" class="com.xxxx.service.RoleService" init-method="init"></bean>
Copy the code

Method 2: org. Springframework. Beans. Factory. InitializingBean interface.

public class RoleService implements InitializingBean {

    @Override
    public void afterPropertiesSet(a) throws Exception {
        System.out.println("RoleService init..."); }}Copy the code
<bean id="roleService" class="com.xxxx.service.RoleService" ></bean>
Copy the code

Bean object instantiation is instantiated at the time of Spring container initialization, but is not immutable. You can delay the Bean object initialization through the lazy-init=”true” attribute until the Bean is initialized when the getBean method is called

Using the beans

** Mode 1: ** Use BeanFactory

// Get the Spring context
BeanFactory factory = new ClassPathXmlApplicationContext("spring.xml");
RoleService roleService = (RoleService) factory.getBean("roleService");
Copy the code

Method 2: ** Use ApplicationContext

// Get the Spring context
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
RoleService roleService = (RoleService) ac.getBean("roleService");
Copy the code

The destruction of the Bean

Implement destruction (The Spring container maintains management of bean objects and can specify the method to be executed for bean object destruction).

** Step 1: ** Implement the destruction method (The Spring container maintains the management of the bean object and can specify the method to be executed for the destruction of the bean object)

<bean id="roleService" class="com.xxxx.service.RoleService" destroy-method="destroy"></bean>
Copy the code
Step 2: * * * * through AbstractApplicationContext object, call the close method to realize the destruction process of beanCopy the code
AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("spring.xml");
ctx.close();
Copy the code
IOC/ DI-Inversion of control and dependency injection transfer the creation of object instantiations to external containers (IOC containers act as factories); Attribute assignment operations;Copy the code