A Bean is an object that is instantiated, assembled, and managed through the Spring IoC container. In order for the Spring IoC container to instantiate beans correctly, information about Bean instantiation needs to be configured.

Three ways of assembly

Methods of instantiation and dependency injection.

1.1 Explicit ASSEMBLY based on XML

The basic configuration structure of beans in XML is as follows


      
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="..." class="...">
        <! -- collaborators and configuration for this bean go here -->
    </bean>
    <bean id="..." class="...">
        <! -- collaborators and configuration for this bean go here -->
    </bean>
    <! -- more bean definitions go here -->
</beans>
Copy the code

Id represents the bean’s unique identity, and class represents the bean’s type

1.1.1 Instantiation methods: Constructor method (common), static factory and instance factory

XML configuration for the three instantiation methods:

<! If the default constructor is not used, the create fails. -->
<bean id="userService1" class="com.smday.service.impl.UserServiceImpl"></bean>

<! Create an object using a method in a class and store it in the spring container.
<bean id="instanceFactory" class="com.smday.factory.InstanceFactory"></bean>
<bean id="userService2" factory-bean="instanceFactory" factory-method="getUserService"></bean>

<! Create object with static method in factory
<bean id="userService3" class="com.smday.factory.StaticFactory" factory-method="getUserService"></bean>
Copy the code

The factory method needs the corresponding factory class:

// The factory class corresponding to the instance factory method
public class InstanceFactory {
    public BeanClass getUserService(a) {
        return new BeanClass("Instance Factory Method"); }}// Static factory corresponding class
public class StaticFactory {
    private static BeanClass beanInstance = new BeanClass("Call static factory method to instantiate Bean");
    public static BeanClass createInstance(a) {
        returnbeanInstance; }}Copy the code

To use it, use getBean(“id”), as in

BeanClass b = (BeanClass)appCon.getBean("staticFactoryInstance");
Copy the code

1.1.2 Dependency injection methods: constructor injection, setter injection

Constructor injection:<constructor-arg>The label

The Bean definition to instantiate:

public class ExampleBean {
    private AnotherBean beanOne;
    private YetAnotherBean beanTwo;
    private int i;
    public ExampleBean(
        AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {
        this.beanOne = anotherBean;
        this.beanTwo = yetAnotherBean;
        this.i = i; }}Copy the code

Using constructor injection in XML:

<bean id="exampleBean" class="examples.ExampleBean">
    <! -- constructor injection using the nested ref element -->
    <constructor-arg>
        <ref bean="anotherExampleBean"/>
    </constructor-arg>

    <! -- constructor injection using the neater ref attribute -->
    <constructor-arg ref="yetAnotherBean"/>

    <constructor-arg type="int" value="1"/>
</bean>

<bean id="anotherExampleBean" class="examples.AnotherBean"/>
<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
Copy the code

Value: Used to provide basic and String data.

Ref: Used to provide other bean-type data, bean objects that appear in Spring’s IOC core container

Setter injection:<property>The label

The Bean definition that needs to be instantiated needs to provide a set method

public class ExampleBean {
    private AnotherBean beanOne;
    private YetAnotherBean beanTwo;
    private int i;
    public void setBeanOne(AnotherBean beanOne) {
        this.beanOne = beanOne;
    }
    public void setBeanTwo(YetAnotherBean beanTwo) {
        this.beanTwo = beanTwo;
    }
    public void setIntegerProperty(int i) {
        this.i = i; }}Copy the code

The XML file

<bean id="exampleBean" class="examples.ExampleBean">
    <! -- setter injection using the nested ref element -->
    <property name="beanOne">
        <ref bean="anotherExampleBean"/>
    </property>

    <! -- setter injection using the neater ref attribute -->
    <property name="beanTwo" ref="yetAnotherBean"/>
    <property name="integerProperty" value="1"/>
</bean>

<bean id="anotherExampleBean" class="examples.AnotherBean"/>
<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
Copy the code

Name: Specifies the property name of the set method to be called at injection time.

Value: Provides data of the basic type and String type.

Ref: Provides additional bean-type data, bean objects that appear in Spring’s IOC core container.

Injection of collection types: list and Map

<bean id="userService" class="com.smday.service.impl.UserServiceImpl">
    <property name="myStrs">
        <array>
            <value>AAA</value>
            <value>BBB</value>
            <value>BBB</value>
        </array>
    </property>
    <property name="myList">
        <list>
            <value>AAA</value>
            <value>BBB</value>
            <value>BBB</value>
        </list>
    </property>
    <property name="mySet">
        <set>
            <value>AAA</value>
            <value>BBB</value>
            <value>BBB</value>
        </set>
    </property>
    <property name="myMap">
        <map>
            <entry key="testA" value="AAA"></entry>
            <entry key="testB" >
                <value>BBB</value>
            </entry>
        </map>
    </property>
    <property name="myProp">
        <props>
            <prop key="testC">CCC</prop>
            <prop key="testD">DDD</prop>
        </props>
    </property>
</bean>
Copy the code

List structure: Use list, array, and set tags

Map structure: Use the map and props tags

1.2 Explicit Java-based assembly

Hey hey, the teacher did not speak do not write

1.3 Annotation-based autoassembly

Spring implements autowiring from two perspectives:

  • Component scanning: SpringAutomatically discover beans created in the application contextThat is, beans that need to be managed in the project are scanned and instantiated into the cache pool. Use the annotations in front of the bean class and set them in the XML<context:component-scan base-package="xxx"/>The implementation.
  • Automatic assembly: SpringAutomatically satisfy dependencies between beansIf a bean has other beans as members, the corresponding bean can be automatically found in the Spring cache pool. Add annotations in front of member attributes@AutowiredThe implementation.

1.3.1 Basic Structure

For example, the Controller layer uses the bean of the Service layer:

Define a Service layer interface

public interface UserService {
    void add(a);
}
Copy the code

Define the Service layer interface implementation class

The @Component annotation tells Spring to create this bean. @Component is equivalent to @Component(), or @Component(“userServiceImpl”), @Component(value = “userServiceImpl”), value is the Bean ID. The default lowercase class name is customizable.

@Component
public class UserServiceImpl implements UserService {
    @Override
    public void add(a) {
        System.out.println("Add user"); }}Copy the code

Define the Controller layer

The @value annotation dynamically injects an external Value into the Bean (related blog)

The @AutoWired annotation tells Spring to automatically inject Userservice, which is assembled by Bean type by default

@Component
public class UserController {
	@value (" Inject normal string ")
	private String s;
      
	@Autowired
        private UserService userservice;
        public String getS(a) {
                return s;
	}
	public void setS(String s) {
		this.s = s;
	}
	public void add(a){
		System.out.println("s = "+s); userservice.add(); }}Copy the code

Configure annotations in the XML to specify where the Spring container scans Bean objects


      
<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"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
        
    <context:component-scan base-package="com.service" />
	<context:component-scan base-package="com.controller" />
    
</beans>
Copy the code

The test class

public class Test {
	public static void main(String args[]) {
		@SuppressWarnings("resource")
		ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserController tmp = (UserController) appCon.getBean("userController"); tmp.add(); }}Copy the code

1.3.2 Common annotations

@Component

  • Action: Stores the current class object into the Spring container.

  • Property: value, used to specify the bean ID. If no value is specified, the default value is the first letter of the current class.

  • In the three-tier architecture, the Spring framework provides three distinct layers of annotation that are the same as @Component, but more semantic: @Controller: the control layer, @Service: the business layer, and @respository: the data access layer

@Autowired

  • Function: annotate class member variables, methods and constructors to complete the work of automatic assembly. Automatic injection by type, as long as there is only one bean object type in the container that matches the type of the variable to be injected. The set method is not necessary when using annotation injection.

  • If no bean type in the IoC container matches the type of the variable being injected, an error is reported (you can set the required attribute to false, or the state is unassembled if no bean of the corresponding type is found)

  • The @qualifier and @Resource annotations should be used in the IoC container if there are ambiguities when multiple types match

@Resource

  • Same function as @autowired. The difference is that the annotation defaults to assemble injection by name, and will only assemble injection by type if no Bean matching the name is found;

  • The @Resource annotation has two attributes: name and type. The name attribute specifies the Bean instance name, that is, to assemble injection by name; The type attribute specifies the Bean type, that is, the assembly is based on the Bean type.

@Qualifier

  • When the @AutoWired annotation needs to be assembled by name, it needs to be used in conjunction with the annotation, and the instance name of the Bean is specified by the @Qualifier annotation parameter.

The scope of the Bean

Scope name describe
singleton By default, beans defined using singleton have only one instance of the Bean in the Spring container.
prototype Each time the Spring container retrieves a Prototype-defined Bean, the container creates a new Bean instance.
request The container will return a Bean instance in one HTTP request, and different HTTP requests will return different Bean instances. Used only in the context of a Web Spring application.
session In an HTTP Session, the container will return the same Bean instance. Used only in the context of a Web Spring application.
application Create an instance for each ServletContext object, that is, the same application shares a Bean instance. Used only in the context of a Web Spring application.
websocket Create a Bean instance for each WebSocket object. Used only in the context of a Web Spring application.

For different assembly methods, there are different scope definition methods:

  1. usescope="xxx"Set the scope in the XML file
<bean id="constructorInstance" class="instance.BeanClass" scope="prototype"/>
Copy the code
  1. Used in class definition@Scope(xxx)annotations
@Component
@Scope("prototype")
public class UserController {
	@Autowired
    private UserService userservice;
}
Copy the code

Testing the scope, you can see that under the Prototype scope, the getBean gets a new instance every time

public class TestController {
	@Test
	public void testMethod(a){
        ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserController tmp1 = (UserController) appCon.getBean("userController");
		System.out.println(tmp1);//com.controller.UserController@4d14b6c2
		
		UserController tmp2 = (UserController) appCon.getBean("userController");
		System.out.println(tmp2);//com.controller.UserController@c05fddc}}Copy the code

The life cycle of the Bean

Calling custom initialization methods and calling custom destruction methods can be configured using properties init-method and destroy-method, respectively.

Bean

package life;
public class BeanLife {
    public void initMyself(a) {
        System.out.println(this.getClass().getName() + "Perform custom initialization methods");
    }
    public void destroyMyself(a) {
        System.out.println(this.getClass().getName() + "Perform custom destruction methods"); }}Copy the code

XML configuration file

<bean id="beanLife" class="life.BeanLife" init-method="initMyself" destroy-method ="destroyMyself"/>
Copy the code

test

public static void main(String[] args) {
   // Initialize the Spring container and load the configuration file
   / / in order to illustrate the destroy method, make ClassPathXmlApplicationContext class declaration container here
   ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
   System.out.println("Before obtaining the object");
   BeanLife blife = (BeanLife)ctx.getBean("beanLife");
   System.out.println("After obtaining the object" + blife);
   ctx.close();// Close the container and destroy the Bean object
}
Copy the code

The output