Spring IOC configuration and use

Posted by inkdrop on Wed, 08 Dec 2021 05:07:53 +0100

preface

The previous article briefly introduced IOC. This article focuses on how to use IOC in spring 5 for Bean management. There are two ways, based on xml files and annotations, which we will talk about one by one.

BeanFactory interface

The bottom layer of the IOC container is the object factory

Spring provides two implementations of IOC containers (two interfaces):

  • Beanfactory: the basic implementation of IOC container is the internal interface of Spring. It is not provided to developers. The ship object will not be created when loading the file. The object will be created only when obtaining the object.

  • ApplicationContext: the sub interface of beanfactory interface, which provides more and more powerful functions. When loading the configuration file, the objects configured in the configuration file will be created.

    Four common implementation classes of ApplicationContext:

    • **FileSystemXmlApplicationContext: * * the project path, that is, the absolute path, is used when loading the configuration file.
    • **ClassPathXmlApplicationContext: * * the configuration file is loaded according to the ClassPath location, that is, the relative path of the project.
    • **XmlWebApplicationContext: * * this class will be loaded when initializing the listener in the Web environment.
    • **AnnotationConfigApplicationContext: * * start the Spring container by annotation.

How spring Di works

Spring provides three methods for dependency injection, including constructor injection, Setter method injection and interface injection. Spring used to recommend using Setter, but now it recommends constructing method injection. One thing to note when using constructor injection is to avoid circular dependencies. The so-called circular dependency means that spring injects B into the construction method of A object, and spring injects A into B object. At this time, A closed loop will be formed, because spring does not know which one to inject first, and then an exception will be thrown. Spring suggests that if this happens, you should use Setter injection instead.

Bean Management (XML based)

Create objects based on xml:

  • In the Spring configuration file, create objects using bean tags
  • There are multiple attributes in the bean tag, commonly used are:
    • id: unique id, used to get the object
    • Class: full path of class
  • When creating an object, the default is to execute the parameterless construction method to complete the object creation
<!--to configure User Object creation-->
<bean id="user" class="com.ayu.User"></bean>

Inject attributes based on xml:

  • Injection using set method

    Use the property tag within the bean tag to complete property injection:

    Name: attribute name in class

    Value: the injected value in the attribute

    <!--use set Method for parameter injection-->
    <bean id="user1" class="com.ayu.User">
    	<property name="name" value="Tom"></property>
    	<property name="age" value="11"></property>
    </bean>
    
  • Injection using a parametric constructor

    Use the constructor Arg tag within the bean tag to complete attribute injection:

    Name: attribute name in class

    Value: the injected value in the attribute

    <!--Parametric construction method is used for parameter injection-->
    <bean id="user2" class="com.ayu.User">
    	<constructor-arg name="name" value="Jerry"></constructor-arg>
    	<constructor-arg name="age" value="11"></constructor-arg>
    </bean>
    

xml injection other attributes:

  • Literal

    • null value

      Use label

      <!--null value-->
      <property name="name">
          <null/>
      </property>
      
    • Attribute values contain special symbols

      Using CDATA

      <!--Special characters-->
      <property name="name">
          <value>
          	<![CDATA[<<Shi Sheng>>]]>
          </value>
      </property>
      
  • Inject external bean s

    Use the ref attribute to inject the externally created bean object

    <!--external bean-->
    <bean id="userService" class="com.ayu.service.UserService">
            <property name="userDao" ref="userDao"></property>
    </bean>
    
    <bean id="userDao" class="com.ayu.dao.UserDao"></bean>
    
  • Inject internal bean s

    Create the bean tag directly in the property tag

    <!--inside bean-->
    <bean id="emp" class="com.ayu.bean.Emp">
        <property name="name" value="Zhang San"></property>
        <property name="dept">
            <bean id="dept" class="com.ayu.bean.Dept">
                <property name="deptNo" value="101"></property>
            </bean>
        </property>
    </bean>
    
  • Cascade assignment

    Assign a value to the attribute of the bean object in the attribute

    <!--Cascade assignment-->
    <bean id="emp1" class="com.ayu.bean.Emp">
        <property name="name" value="Zhang San"></property>
        <property name="dept" ref="dept1"></property>
        <property name="dept.deptNo" value="102"></property>
    </bean>
    <bean id="dept1" class="com.ayu.bean.Dept"></bean>
    

xml injection collection properties:

  • The array tag assigns a value to the array
  • The list tag assigns a value to the list set
  • The set tag assigns a value to the set
  • The map tag assigns a value to the map collection
<bean id="stu" class="com.ayu.collection.Student">
<property name="courses">
    <array>
        <value>language</value>
        <value>mathematics</value>
        <value>English</value>
    </array>
</property>
<property name="list">
    <list>
        <value>java</value>
        <value>go</value>
        <value>c++</value>
    </list>
</property>
<property name="map">
    <map>
        <entry key="java" value="88"></entry>
        <entry key="c++" value="78"></entry>
    </map>
</property>
<property name="set">
    <set>
        <value>MySQL</value>
        <value>SQLServer</value>
    </set>
</property>
<property name="courseList">
    <list>
        <ref bean="course1"></ref>
        <ref bean="course2"></ref>
    </list>
</property>
</bean>

<bean id="course1" class="com.ayu.collection.Course">
	<property name="name" value="Spring5"></property>
</bean>
<bean id="course2" class="com.ayu.collection.Course">
	<property name="name" value="SpringMVC"></property>
</bean>

Using util tag to share bean s:

<!-- Configure namespace -->
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
                    http://www.springframework.org/schema/beans/spring-beans.xsd
                    http://www.springframework.org/schema/util
                    http://www.springframework.org/schema/util/spring-util-2.0.xsd">

<!-- use util Tag to configure shared bean-->
<util:list id="bookList">
    <value>Big talk data structure</value>
    <value>How does the program run</value>
    <value>Introduction to operating system</value>
</util:list>

<bean id="book" class="com.ayu.collection.Book">
    <property name="list" ref="bookList"></property>
</bean>

Configure bean s using the p namespace:

<!-- Configure namespace -->
xmlns:p="http://www.springframework.org/schema/p"

<!--use p Namespace bean-->
<bean id="user" class="com.ayu.User" p:name="Tom" p:age="11"></bean>

Bean scope:

In Spring, you can use the scope attribute to configure the scope of the bean:

  • Singleton: singleton, which generates a singleton bean object * * (default) when initializing the configuration file**
  • Prototype: prototype. Bean objects are not generated when initializing the configuration file. Different bean objects are returned when using
  • Request: in the web environment, each request will return a different bean, which is only valid in this request
  • Session: in the web environment, each request will return a different bean, which is valid in the session
<!--set up scope attribute-->
<bean id="user" class="com.ayu.User" scope="singleton"></bean>

Bean lifecycle:

  1. Generate an instance of a bean through a construction method
  2. Inject properties into bean s
  3. Call initialization method * * (configured through init method attribute)**
  4. Use of bean s
  5. When the IOC container is closed, the destroy method * * (configured through the destroy method property) is called**

Create an Order class for testing:

public class Order {
    private String name;
    
    public Order() {
        System.out.println("1.Nonparametric structure");
    }
    
    public void setName(String name) {
        this.name = name;
        System.out.println("2.set method");
    }
    
    public void initMethod() {
        System.out.println("3.Initialization method");
    }

    public void destroyMethod() {
        System.out.println("5.Destruction method");
    }
    
    @Test
    public void testOrder() {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        Order order = context.getBean("order", Order.class);
        System.out.println("4.Get bean object");
        System.out.println(order);
        ((ClassPathXmlApplicationContext) context).close();
    }
}

Profile:

<bean id="order" class="com.ayu.bean.Order" init-method="initMethod" destroy-method="destroyMethod">
    <property name="name" value="mobile phone"></property>
</bean>

Test results:

1. Nonparametric structure
2.set method
3. Initialization method
4. Get bean object
com.ayu.bean.Order@69b0fd6f
5. Destruction method

Post processor of Bean:

Life cycle after using post processor:

  1. Generate an instance of a bean through a construction method
  2. Inject properties into bean s
  3. Pass the bean to the postProcessBeforeInitialization method of the post processor
  4. Call initialization method * * (configured through init method attribute)**
  5. Pass the bean to the postProcessAfterInitialization method of the post processor
  6. Use of bean s
  7. When the IOC container is closed, the destroy method * * (configured through the destroy method property) is called**

Create a post processor class to implement the BeanPostProcessor interface:

public class MyBeanPost implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Before initialization");
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("After initialization");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

Configure BeanPostProcessor in the configuration file:

<bean id="myBeanPost" class="com.ayu.bean.MyBeanPost"></bean>

Test results:

1. Nonparametric structure
2.set method
Before initialization
3. Initialization method
After initialization
4. Get bean object
com.ayu.bean.Order@66d1af89
5. Destruction method

Automatic assembly of Bean

The autowire attribute of the bean tag implements automatic assembly. Autowire has two common values:

  • byName: inject according to the attribute name. The id value of the injected value bean must be the same as the class attribute value name

    <bean id="emp" class="com.ayu.autowrite.Emp" autowire="byName">
        <!--<property name="dept" ref="dept"></property>-->
    </bean>
    <bean id="dept" class="com.ayu.autowrite.Dept"></bean>
    
  • byType: injected according to attribute type

    <bean id="emp" class="com.ayu.autowrite.Emp" autowire="byType">
        <!--<property name="dept" ref="dept"></property>-->
    </bean>
    <bean id="dept" class="com.ayu.autowrite.Dept"></bean>
    

    Note: through byType automatic assembly, an error will be reported when there are multiple beans of this type in the configured beans

Bean Management (annotation based)

Annotations provided by Spring for bean management

The following four annotation functions are the same and can be used to create bean instances

  • @Controller: controller. It is recommended to add this annotation to the controller layer.
  • @Service: business logic. It is recommended to add this annotation to the business logic layer.
  • @Repository: warehouse management. It is recommended to add this annotation to the data access layer.
  • @Component: add this annotation to components that do not belong to the above base level.

Object creation based on annotation

  1. Turn on component scanning:

    If you scan multiple packages, you can separate them with commas, or scan the upper directory of the package

    <context:component-scan base-package="com.ayu"></context:component-scan>
    
  2. Create a class and add an object annotation on the class

    //The value attribute can not be written, and the default class name is the value with the first letter in lowercase
    @Repository(value="userDao")
    public class UserDaoImpl implements UserDao{
        @Override
        public void hello() {
            System.out.println("hello dao");
        }
    }
    

Enable component scanning details configuration

<!--Example 1: use-default-filters Indicates that the default is not used now filter,Self configuration filter
	content:include-filter Set what to scan-->
<content:component-scan base-package="com.ayu" use-default-filters="false">
    <content:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</content:component-scan>
<!--Example 2: configure all the contents below
	content:exclude-filter Set what is not scanned-->
<content:component-scan base-package="com.ayu" use-default-filters="false">
    <content:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</content:component-scan>

Attribute injection based on annotation

  • @Autowired: auto assemble according to attribute type

    @Service
    public class UserService {
    
        //The set method is not required
        @Autowired
        private UserDao userDaO;
    
        public void hello() {
            System.out.println("hello service");
            userDaO.hello();
        }
    }
    
  • @Qualifier: inject according to the attribute name, which is usually used with @ Autowired

    @Service
    public class UserService {
    
        //The set method is not required
        //Distinguish multiple implementation classes under the same interface
        @Autowired
        @Qualifier(value="userDaoImpl")
        private UserDao userDaO;
    
        public void hello() {
            System.out.println("hello service");
            userDaO.hello();
        }
    }
    
  • @Resource: it can be injected according to type or name (this annotation is provided by JDK)

    @Resource(value="userDaoImpl")
    private UserDao userDaO;
    
  • @Value: inject common type attribute

    @Value(value = "service")
    private String name;
    

Fully annotated development

Create a configuration class instead of an xml configuration file

@Configuration
@ComponentScan(basePackages = {"com.ayu"})
public class SpringConfig {}

In this case, the implementation class AnnotationConfigApplicationContext should be used:

//AnnotationConfigApplicationContext needs to pass the configuration class to it
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userService = context.getBean("userService", UserService.class);
userService.hello();

last

My home page: www.ayu.link
This article is connected to: ┏ (゜ω゜)=☞

Topics: Java Spring ioc