Learn Spring IOC injection again and have a new understanding -- Le byte microservice

Spring IOC injection

Manual instantiation and external import

Figure 1:

Figure 2:

The Through comparison, it is found that the creation of UserDao object in Figure 2 is not actively instantiated as in Figure 1, but the UserDao is passed in through the method with parameters, so as to realize the dependence of UserService on the UserDao class.

The The object behind the actual creation of the object is handed over to the outside to create.

Spring IOC manual assembly (injection)

The Spring supports four injection methods: set injection, constructor injection, static factory injection, and instance factory injection.

set method injection

Note:

  • Attribute field needs to provide set method
  • Four methods, set method injection is recommended
Business object JavaBean
  1. Property field provides set method

    public class UserService {
    
        // Business object UserDao set injection (provide set method)
        private UserDao userDao;
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    }
    
  2. Set the property tag for the bean tag of the configuration file

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd">
        
       <!--
            IOC adopt property Label manual assembly (injection):
                Set Method injection
                    name: bean Name of the attribute field in the object
                    ref: specify bean Tagged id Attribute value
        --> 
        <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>
    
Common objects and basic types
  1. Property field provides set method

    public class UserService {
    
        // Common object string set injection (provide set method)
        private String host;
        public void setHost(String host) {
            this.host = host;
        }
    
        // Basic type integer set injection (provide set method)
        private Integer port;
        public void setPort(Integer port) {
            this.port = port;
        }
    }
    
    
  2. Set the property tag for the bean tag of the configuration file

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd">
        
       <!--
            IOC adopt property Label manual assembly (injection):
                Set Method injection
                    name: bean Name of the attribute field in the object
                    value:Specific value (basic type common object|Date set)
        --> 
    	<bean id="userService" class="com.xxxx.service.UserService">
            <!--Common objects String injection-->
            <property name="host" value="127.0.0.1"/>
            <!--Basic type injection-->
            <property name="port" value="8080"/>
        </bean>
    
    </beans>
    
Collection types and property objects
  1. Property field provides 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;
        }
       
    }
    
  2. Set the property tag for the bean tag of the configuration file

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd">
        
       <!--
            IOC adopt property Label manual assembly (injection):
                Set Method injection
                    name: bean Name of the attribute field in the object
                    value:Specific value (basic type common object|Date set)
        --> 
    	<!--List Collection injection-->
        <property name="list">
            <list>
                <value>Shanghai</value>
                <value>Beijing</value>
                <value>Hangzhou</value>
            </list>
        </property>
    
        <!--Set Collection injection-->
        <property name="set">
            <set>
                <value>Shanghai SH</value>
                <value>Beijing BJ</value>
                <value>Hangzhou HZ</value>
            </set>
        </property>
    
        <!--Map injection-->
        <property name="map">
            <map>
                <entry>
                    <key><value>Jay Chou</value></key>
                    <value>I believe so</value>
                </entry>
                <entry>
                    <key><value>Linjunjie</value></key>
                    <value>Unfortunately, no if</value>
                </entry>
                <entry>
                    <key><value>Eason Chan</value></key>
                    <value>Ten years</value>
                </entry>
            </map>
        </property>
    
        <!--Properties injection-->
        <property name="properties">
            <props>
                <prop key="Shanghai">Oriental Pearl TV Tower</prop>
                <prop key="Beijing">Tiananmen Square</prop>
                <prop key="Hangzhou">West Lake</prop>
            </props>
        </property>
    
    </beans>
    
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;
    }

    // Common object string set injection (provide set method)
    private String host;
    public void setHost(String host) {
        this.host = host;
    }

    // Basic type integer set injection (provide set method)
    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 set output
    public void printList() {
        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() {
        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;
    }
    // Map output
    public void printMap() {
        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(){
        properties.forEach((k,v) -> System.out.println(k + ","+ v ));
    }



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

        userDao.test();

        studentDao.test();

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

        // List collection
        printList();

        // Set set
        printSet();

        // Map
        printMap();

        // Properties
        printProperties();

    }
}

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <!--
        IOC adopt property Label manual assembly (injection):
            Set Method injection
                name: bean Name of the attribute field in the object
                ref: specify bean Tagged id Attribute value
                value:Specific value (basic type common object|Date set)

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

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

        <!--List Collection injection-->
        <property name="list">
            <list>
                <value>Shanghai</value>
                <value>Beijing</value>
                <value>Hangzhou</value>
            </list>
        </property>

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

        <!--Map injection-->
        <property name="map">
            <map>
                <entry>
                    <key><value>Jay Chou</value></key>
                    <value>I believe so</value>
                </entry>
                <entry>
                    <key><value>Linjunjie</value></key>
                    <value>Unfortunately, no if</value>
                </entry>
                <entry>
                    <key><value>Eason Chan</value></key>
                    <value>Ten years</value>
                </entry>
            </map>
        </property>

        <!--Properties injection-->
        <property name="properties">
            <props>
                <prop key="Shanghai">Oriental Pearl TV Tower</prop>
                <prop key="Beijing">Tiananmen Square</prop>
                <prop key="Hangzhou">West Lake</prop>
            </props>
        </property>

    </bean>
    
</beans>

Constructor Injection

Note:

  • Provide a constructor with parameters
Single Bean object as parameter

Java code

public class UserService {

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

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

        userDao.test();
    }

}

XML configuration

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
	<!--
        IOC Inject via constructor:
            adopt constructor-arg Label for injection
                name: Attribute name
                ref: specify bean Tagged id Attribute value
    -->
    <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>
Multiple Bean objects as parameters

Java code

public class UserService {

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

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

        userDao.test();
        accountDao.test();
    }

}

XML configuration

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
	 <!--
        IOC Inject via constructor:
            adopt constructor-arg Label for injection
                name: Attribute name
                ref: specify bean Tagged id Attribute value
    -->
    <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>
Bean object and common object as parameters

Java code

public class UserService {

    private UserDao userDao;  // JavaBean object
    private AccountDao accountDao;  // JavaBean object
    private String uname;  // String type
        
    public UserService(UserDao userDao, AccountDao accountDao, String uname) {
        this.userDao = userDao;
        this.accountDao = accountDao;
        this.uname = uname;
    }

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

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

}

XML configuration

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
	<!--
        IOC Inject via constructor:
            adopt constructor-arg Label for injection
                name: Attribute name
                ref: specify bean Tagged id Attribute value
 				value: Values for common objects of basic types
                index: Subscript of parameter in constructor, 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>
Circular dependency problem

Causes of circulation problems:

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

Problem presentation:

  1. Java code

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

    <!--
         If multiple bean If objects are injected into each other, the problem of circular dependency will occur
         Can pass set Method injection solution
    -->
    <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>
    

If you have any questions, you can join the group: 10803-55292, enter the code 13, and you can have a boss teach you ten years of experience

How to solve this problem: change constructor injection to 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() {
            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() {
            System.out.println("RoleService Test...");
        }
    }
    
  2. 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>
    -->
    <!--Change to 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>
    

Static factory injection

  1. Define static factory classes

    public class StaticFactory {
    
        // Define static methods
        public static TypeDao createTypeDao() {
            return new TypeDao();
        }
    }
    
  2. Java code

    public class TypeService {
    
        private TypeDao typeDao;
    	
        public void setTypeDao(TypeDao typeDao) {
            this.typeDao = typeDao;
        }
    
        public void  test() {
            System.out.println("TypeService Test...");
        }
    }
    
  3. 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 plant injection:
    		Static factory injection also uses set Method injection, only injected bean Object instantiation is through static factory instantiation
    -->
    <bean id="typeDao" class="com.xxxx.factory.StaticFactory" factory-method="createTypeDao"></bean>
    

Example chemical plant injection

  1. Define factory classes

    public class InstanceFactory {
         public TypeDao createTypeDao() {
            return new TypeDao();
        }
    }
    
  2. Java code

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

    Declare the factory bean tag, declare the bean object, and specify the factory object and factory method

    <bean id="typeService" class="com.xxxx.service.TypeService">
    	<property name="typeDao" ref="typeDao"/>
    </bean>
    <!--
    	Example chemical plant injection:
    		Example chemical plant injection also relies on set Method injection, only injected bean Objects are instantiated through the instance factory
    -->
    <bean id="instanceFactory" class="com.xxxx.factory.InstanceFactory"></bean>
    <bean id="typeDao" factory-bean="instanceFactory" factory-method="createTypeDao"></bean>
    

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

Selection of injection mode

The set mode injection preferred in development projects

The Using construction injection can complete the establishment of dependencies while building objects. Once an object is established, everything will be ready. However, if there are many object relationships to be established, using constructor injection will leave a long series of parameters on the building function, which is difficult to remember. At this time, using Set injection will be a good choice.
Using Set injection, you can have a clear name and know what the injected object will be. Names like setXXX() are better than remembering that the position of a parameter on the Constructor represents an object.

p use of namespaces

The After spring2.5, in order to simplify the attribute injection of setter methods, the concept of p namespace is referenced, and the child elements can be simplified as element attribute configuration.

  1. Property field provides set method

    public class UserService {
    
        // Business object UserDao set injection (provide set method)
        private UserDao userDao;
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
        
        // Common object string set injection (provide set method)
        private String host;
        public void setHost(String host) {
            this.host = host;
        }
    }
    
  2. In the configuration file spring XML introduces p namespace

    xmlns:p="http://www.springframework.org/schema/p"
    
    <?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"
           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>
        <!--
    		p:Attribute name:="xxx"		Introducing constant values
    		p:Attribute name-ref:="xxx"	Introduce other Bean Object's id Attribute value
    	-->
        <bean id="userService" class="com.xxxx.service.UserService" 
            p:userDao-ref="userDao" 
            p:host="127.0.0.1" />
    
    </beans>
    

Spring IOC auto assembly (injection)

Annotation mode injection Bean

The For bean injection, in addition to xml configuration, annotation configuration can be used. Annotation configuration can simplify the configuration file, improve the development speed, and make the program look more concise. For annotation interpretation, Spring has a special interpreter for annotations, which parses the defined annotations and implements the injection of corresponding bean objects. Through reflection technology.

Prepare the environment

  1. Modify profile

    <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">
    
  2. Turn on 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> 
    
  3. Annotate the injected bean object

@Resource annotation

@Resource annotation implements automatic injection (reflection)

  • By default, the corresponding bean object is found according to the name of the attribute field (the name of the attribute field is equal to the id attribute value of the bean tag)
  • If the attribute field name is not found, it will be found by type (Class type)
  • Property can provide or not provide a set method
  • Annotations can be declared at the attribute level or set method level
  • You can set the name attribute. The name attribute value must be consistent with the id attribute value of the bean tag; If the name attribute value is set, the bean object will only be searched according to the name attribute value
  • When injecting an interface, if the interface has only one implementation, it will be instantiated normally; If there are multiple implementations of the interface, you need to use the name attribute to specify the bean object to be instantiated

Code example

  1. By default, the corresponding bean object is found according to the name of the attribute field (the name of the attribute field is equal to the id attribute value of the bean tag)

    /**
     * @Resource Annotation implements automatic injection (reflection)
     *  By default, the corresponding bean object is found according to the name of the attribute field (the name of the attribute field is equal to the id attribute value of the bean tag)
     */
    public class UserService {
    
        @Resource
        private UserDao userDao; // The name of the attribute field is equal to the id attribute value of the bean tag
    
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public void test() {
            // Method calling UserDao
            userDao.test();
        }
    }
    
  2. If the attribute field name is not found, it will be found by type (Class type)

    /**
     * @Resource Annotation implements automatic injection (reflection)
     *   If the attribute field name is not found, it will be found by type (Class type)
     */
    public class UserService {
    
        @Resource
        private UserDao ud; // When the attribute field name (ud) is not found in the configuration file, the corresponding class (UserDao type) will be found
    
        public void setUd(UserDao ud) {
            this.ud = ud;
        }
    
        public void test() {
            // Method calling UserDao
            ud.test();
        }
    }
    
  3. Property can provide or not provide a set method

    /**
     * @Resource Annotation implements automatic injection (reflection)
     *   Property can provide or not provide a set method
     */
    public class UserService {
    
        @Resource
        private UserDao userDao; // No set method provided
    
    
        public void test() {
            // Method calling UserDao
            userDao.test();
        }
    }
    
  4. Annotations can be declared at the attribute level or set method level

    /**
     * @Resource Annotation implements 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() {
            // Method calling UserDao
            userDao.test();
        }
    }
    
  5. You can set the name attribute. The name attribute value must be consistent with the id attribute value of the bean tag; If the name attribute value is set, the bean object will only be searched according to the name attribute value

    /**
     * @Resource Annotation implements automatic injection (reflection)
     *   You can set the name attribute. The name attribute value must be consistent with the id attribute value of the bean;
     *   If the name attribute value is set, the bean object will only be searched according to the name attribute value
     */
    public class UserService {
    
        @Resource(name = "userDao") // The name attribute value is consistent with the id attribute value of the bean tag in the configuration file
        private UserDao ud;
    
    
        public void test() {
            // Method calling UserDao
            ud.test();
        }
    }
    
  6. When injecting an interface, if the interface has only one implementation, it will be instantiated normally; If there are multiple implementations of the interface, you need to use the name attribute to specify the bean object to be instantiated

    Define interface class iuserdao Java

    package com.xxxx.dao;
    
    /**
     * Define interface classes
     */
    public interface IUserDao {
        public void test();
    }
    

    Define the interface implementation class userdao01 Java

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

    Define interface implementation class userdao02 Java

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

    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>
    

    Using the annotation userservice Java

    /**
     * @Resource Annotation implements automatic injection (reflection)
     *   When injecting an interface, if the interface has only one implementation, it will be instantiated normally; If there are multiple implementations of the interface, you need to use the name attribute to specify the bean object to be instantiated
     */
    public class UserService {
    
        @Resource(name = "userDao01") // The name attribute value is consistent with the id attribute value of the bean tag of one of the implementation classes
        private IUserDao iUserDao; // Injection interface (there are multiple implementations of the interface)
    
        public void test() {
            iUserDao.test();
        }
    }
    

@Autowired annotation

@Autowired annotation implements automatic injection:

  • Finding bean objects by type (Class type) by default is independent of the name of the attribute field
  • Property can provide or not provide a set method
  • Annotations can be declared at the attribute level or set method level
  • You can add @Qualifier in combination to find the bean object through the value attribute value (the value attribute value must be set and the value must correspond to the id attribute value of the bean tag)
  1. Finding bean objects by type (Class type) by default is independent of the name of the attribute field

    /**
     * @Autowired Automatic injection of annotations
     *  Finding bean objects by type (Class type) by default is independent of the name of the attribute field
     */
    public class UserService {
    
        @Autowired
        private UserDao userDao; // Finding bean objects by type (Class type) by default is independent of the name of the attribute field
    
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public void test() {
            // Method calling UserDao
            userDao.test();
        }
    }
    
  2. Property can provide or not provide a set method

    /**
     * @Autowired Automatic injection of annotations
     *  Property can provide or not provide a set method
     */
    public class UserService {
    
        @Autowired
        private UserDao userDao; // No set method provided
    
        public void test() {
            // Method calling UserDao
            userDao.test();
        }
    }
    
  3. Annotations can be declared at the attribute level or set method level

    /**
     * @Autowired Automatic injection of annotations
     *  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() {
            // Method calling UserDao
            userDao.test();
        }
    }
    
  4. You can add @Qualifier in combination to find the bean object through the value attribute value (the value attribute value must be set and the value must correspond to the id attribute value of the bean tag)

    /**
     * @Autowired Automatic injection of annotations
     *  You can add @Qualifier in combination to find the bean object through the value attribute value
     		value The attribute value must be set, and the value must correspond to the id attribute value of the bean tag
     */
    public class UserService {
    
        @Autowired
        @Qualifier(value="userDao") // The value attribute value must be set, and the value must correspond to the id attribute value of the bean tag
        private UserDao userDao;
    
        public void test() {
            userDao.test();
        }
    }
    

    The recommended * * @Resource** annotation belongs to J2EE, which reduces the coupling with Spring.

Spring IOC scanner

The In the actual development, the number of beans is very large, and the method of manually configuring beans can no longer meet the production needs. Spring also provides a scanning method to uniformly manage the scanned bean objects, simplify the development configuration, and improve the development efficiency.

Configuration of Spring IOC scanner

Spring IOC scanner
	Function: bean Objects are managed uniformly to simplify development configuration and improve development efficiency

    1,Set the scope of automatic scanning
             If bean The object is not in the specified package scope. Even if the annotation is declared, it cannot be instantiated
    2,Use the specified annotation (declared at the class level)    bean Object's id Property defaults to the first lowercase of the class
          Dao Layer:
             @Repository
          Service Layer:
             @Service
          Controller Layer:
             @Controller
          Any class:
             @Component
     Note: it is recommended to declare annotations according to the specified rules during development
  1. Set automatic scanning range

    <?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
           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 scope of automatic scanning -->
        <context:component-scan base-package="com.xxxx"/>
    
    </beans>
    
  2. Use specific annotations

    @Repository (Dao layer)

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

    @Service (service layer)

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

    @Controller (controller layer)

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

    @Component (any layer)

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

Spring simulates the user login process

Dao layer (query user records)

  1. Define JavaBean 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() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getUserPwd() {
            return userPwd;
        }
    
        public void setUserPwd(String userPwd) {
            this.userPwd = userPwd;
        }
    }
    
  2. Write 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;
            // Judge whether the user name is correct
            if(!USERNAME.equals(userName)){
                // null if incorrect
                return null;
            }
            // If correct, set the user name and password to the user object
            user = new User();
            user.setUserName(USERNAME);
            user.setUserPwd(USERPWD);
    
            return user;
        }
    }
    

Service layer (business logic processing)

  1. Define the business processing return message model messagemodel Java

    package com.xxxx.po.vo;
    
    /**
     * Define business processing return message model
     *     Encapsulate return results
     */
    public class MessageModel {
    
        private Integer resultCode = 1; // Result status code 1= success, 0= failure
        private String resultMsg = "Operation succeeded!"; // Result prompt
    
        public Integer getResultCode() {
            return resultCode;
        }
    
        public void setResultCode(Integer resultCode) {
            this.resultCode = resultCode;
        }
    
        public String getResultMsg() {
            return resultMsg;
        }
    
        public void setResultMsg(String resultMsg) {
            this.resultMsg = resultMsg;
        }
    }
    
  2. Write 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 business processing return message model
            MessageModel messageModel = new MessageModel();
            // Judge 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;
            }
            // Judge whether the user password is empty
            if(null == userPwd || "".equals(userPwd.trim())){
                messageModel.setResultCode(0);
                messageModel.setResultMsg("Password cannot be empty!");
                return messageModel;
            }
            // Query user object by user name
            User user = userDao.queryUserByUserName(userName);
            // Judge whether the user object is empty
            if(null == user){
                messageModel.setResultCode(0);
                messageModel.setResultMsg("The user does not exist!");
                return messageModel;
            }
            // If the user object is not empty, judge whether the password is correct
            if(!user.getUserPwd().equals(userPwd)){
                messageModel.setResultCode(0);
                messageModel.setResultMsg("The user password is incorrect!");
                return messageModel;
            }
            // Login successful
            messageModel.setResultMsg("Login succeeded!");
            
            return messageModel;
        }
    }
    

Controller layer (receive request)

  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 judge the user login operation and return the result
            MessageModel messageModel = userService.userLoginCheck(userName, userPwd);
            return messageModel;
        }
    }
    

Testing through 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 TestLogin {

    @Test
    public void test() {
        // Get the Spring container context
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        // Get UserController instantiation object
        UserController userController = (UserController) ac.getBean("userController");
        // Pass in the parameter to call the method of UserController and return the encapsulated class
        MessageModel messageModel= userController.login("admin", "admin");

        System.out.println("Status code:" + messageModel.getResultCode() + ",Prompt:" + messageModel.getResultMsg());
    }
}

Tags: Java Spring

Posted by lxndr on Tue, 31 May 2022 12:08:04 +0530