Spring-IOC XML configuration

introduction

In Springboot programming practice, we tend way to use annotations carried Bean registration and dependency injection, but the container information management XML format is still Spring provides the most powerful support of the most comprehensive way, this XML for Spring-IOC's configuration detailed explanation.

<beans>和<bean>

BeanFactory and ApplicationContext XML configuration are uniform format before Spring2.0, this format DTD provided by Spring requirement that the head of the configuration file, the following DOCTYPE declaration form:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
   ...
</beans>

After release from Spring 2.0, Spring under the premise continue to maintain backward compatibility, both can continue to use the DOCTYPE DTD way
to limit the configuration file format, and the introduction of XML Schema-based document declaration:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:util="http://www.springframework.org/schema/util"
        xmlns:jee="http://www.springframework.org/schema/jee"
        xmlns:lang="http://www.springframework.org/schema/lang"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-2.0.xsd
        http://www.springframework.org/schema/jee
        http://www.springframework.org/schema/jee/spring-jee-2.0.xsd
        http://www.springframework.org/schema/lang
        http://www.springframework.org/schema/lang/spring-lang-2.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
    ...
</beans>

<beans>

<Beans> is the top element of the configuration file, which may contain 0 or 1 <description> and more <bean> and <import> or <alias>

<Beans> You can configure all <bean> global behavior, including:

  • default-lazy-init

The value true or false, the default value false, if the flag is used for all <bean> delay initialized.

  • default-autowire

It may be a value of no, byName, byType, constructor and autodetect. The default is no, if you use automatic binding, is used to mark all the bean which one to use default binding way.

  • default-dependency-check

Values ​​can be none, objects, simple, and all, the default value none, i.e. not dependency checking.

  • default-init-method

If the jurisdiction of the <bean> according to certain rules, have the same name of the initialization method, you can specify the uniform initialization method name here, instead of on each <bean> Repeat specified separately.

  • default-destroy-method

And default-init-method corresponds, bean if there is under the jurisdiction of the object using the same name according to certain rules destruction methods, you can be unified by the designated property.

<description>、<import>和<alias>

  • <description>

A description of the configuration file.

  • <import>

Typically, according to the relationship or hierarchy of function modules, the configuration information into a plurality of different categories in the configuration file. When want to load the main profile and main profile depends profile while loading, can rely on its profile references in this main configuration file by <import> element. For example, if the A.xml <bean> definitions may be dependent in some <bean> B.xml defined in, then you can use <import> B.xml in introducing into the A.xml A.xml, similar to in the form of <import resource = "B.xml" /> of.

  • <alias>

Some may act "nickname" (alias) by <alias> for certain <bean>, usually to reduce the input. For example, suppose there is a <bean>, its name is dataSourceForMasterDatabase, you may want to add a <alias>, like <alias name = "dataSourceForMasterDatabase" alias = "masterDataSource" />. After the reference to the <bean> or by dataSourceForMasterDatabase masterDataSource can.

<bean>

  • id attribute

Identification of objects in the container, if not configured, the small hump <bean> id takes the class name.

In addition to using id, can also be used to identify the name, it is the difference between id, id name could use some characters can not be used, such as /. But
you can also specify multiple name divided by commas, spaces or colon. with the use of the role name <alias> specify multiple aliases for substantially the same id:

<bean id="person" name="/china/person,/england/person"/ class="com.ruanshubin.springboot.entity.Person">
等同于:
<alias name="person" alias="/china/person"/>
<alias name="person" alias="/england/person"/>
  • class property

Each registered object to the container by the need to specify which type of class attribute <bean> element.

Dependency Injection

To demonstrate dependency injection, our new entity class 3, respectively, for the host, and computer monitors.

public class MainEngine {
    // 名称
    private String name;
    // 型号
    private String type;
    // 花费
    private Integer cost;
        
        ...
        构造器及get/set方法
        toString方法
    }
    
public class Display {
    // 名称
    private String name;
    // 型号
    private String type;
    // 花费
    private Integer cost;

        ...
        构造器及get/set方法
        toString方法
    }
    
public class Computer {
    // 名称
    private String name;
    // 主机
    private MainEngine mainEngine;
    // 显示器
    private Display display;
                
            ...
        构造器及get/set方法
        toString方法
        }

Constructor injection

New spring-beans.xml file in the resources directory:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:util="http://www.springframework.org/schema/util"
        xmlns:jee="http://www.springframework.org/schema/jee"
        xmlns:lang="http://www.springframework.org/schema/lang"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-2.0.xsd
        http://www.springframework.org/schema/jee
        http://www.springframework.org/schema/jee/spring-jee-2.0.xsd
        http://www.springframework.org/schema/lang
        http://www.springframework.org/schema/lang/spring-lang-2.0.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

    <bean id="display" class="com.ruanshubin.springboot.ioc.entity.Display">
        <constructor-arg>
            <value>惠普</value>
        </constructor-arg>
        <constructor-arg>
            <value>V300</value>
        </constructor-arg>
        <constructor-arg>
            <value>1000</value>
        </constructor-arg>
    </bean>

    <bean id="mainEngine" class="com.ruanshubin.springboot.ioc.entity.MainEngine">
        <constructor-arg>
            <value>戴尔</value>
        </constructor-arg>
        <constructor-arg>
            <value>T600</value>
        </constructor-arg>
        <constructor-arg>
            <value>3600</value>
        </constructor-arg>
    </bean>

    <bean id="computer" class="com.ruanshubin.springboot.ioc.entity.Computer">
        <constructor-arg>
            <value>组装机1</value>
        </constructor-arg>
        <constructor-arg>
            <ref bean="mainEngine"></ref>
        </constructor-arg>
        <constructor-arg>
            <ref bean="display"></ref>
        </constructor-arg>
    </bean>

</beans>

Write the main function:

public class IocXmlTest {
    public static void main(String[] args) {
        XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-beans.xml"));
        Computer computer = (Computer) beanFactory.getBean("computer");
        System.out.println(computer);
    }
}

Operating results as follows:

Computer{name='组装机1', mainEngine=MainEngine{name='戴尔', type='T600', cost=3600}, display=Display{name='惠普', type='V300', cost=1000}}

Can be found if the basic injection attribute data type (and its packaging), String, etc., using <value> for injection, if a Java object, <ref bean = "..."> manner is used for injection .

Meanwhile, the above <constructor-arg> in order to be in strict accordance with the order of the attributes of a Java class, otherwise there will be problems, such as the configuration changes mainEngine is:

<bean id="mainEngine" class="com.ruanshubin.springboot.ioc.entity.MainEngine">
        <constructor-arg>
                <value>T600</value>
        </constructor-arg>
        <constructor-arg>
                <value>戴尔</value>
        </constructor-arg>
        <constructor-arg>
                <value>3600</value>
        </constructor-arg>
</bean>

Re-run the main class, the result is:

Computer{name='组装机1', mainEngine=MainEngine{name='T600', type='戴尔', cost=3600}, display=Display{name='惠普', type='V300', cost=1000}}

Can be found, the host name and model interchange, causing abnormal.

In this case, add index label which characterizes the sequence number attribute, from zero.

<bean id="mainEngine" class="com.ruanshubin.springboot.ioc.entity.MainEngine">
        <constructor-arg index="1">
                <value>T600</value>
        </constructor-arg>
        <constructor-arg index="0">
                <value>戴尔</value>
        </constructor-arg>
        <constructor-arg>
                <value>3600</value>
        </constructor-arg>
</bean>

There type label , the type of each attribute is not configured for simultaneously:

<bean id="mainEngine" class="com.ruanshubin.springboot.ioc.entity.MainEngine">
        <!--不添加type标签会报错-->
        <constructor-arg type="Integer">
                <value>3600</value>
        </constructor-arg>
        <constructor-arg>
                <value>戴尔</value>
        </constructor-arg>
        <constructor-arg>
                <value>T600</value>
        </constructor-arg>
</bean>

It is the most powerful name tag , regardless <constructor-arg> whether the order coincides with the order of each attribute of the entity class, as long as the same name to ensure the safety injection, such as the configuration changes mainEngine:

<bean id="mainEngine" class="com.ruanshubin.springboot.ioc.entity.MainEngine">
        <constructor-arg name="cost">
                <value>3600</value>
        </constructor-arg>
        <constructor-arg name="type">
                <value>T600</value>
        </constructor-arg>
        <constructor-arg name="name">
                <value>戴尔</value>
        </constructor-arg>
</bean>

While the order of the attributes <constructor-arg> sequence with the opposite entity class, but by one name binding, is still operating results:

Computer{name='组装机1', mainEngine=MainEngine{name='戴尔', type='T600', cost=3600}, display=Display{name='惠普', type='V300', cost=1000}}

setter method injection

The method of using setter <property> complete dependency injection, such as:

<bean id="computer" class="com.ruanshubin.springboot.ioc.entity.Computer">
        <property name="name" value="组装机1"/>
        <property name="mainEngine" ref="mainEngine"/>
        <property name="display" ref="display"/>
</bean>

It should be noted that, in addition to value and ref tags, Spring also provides a bean, idref, value, null, list, set, map, props.

Specific usage scenarios, we do not do too much introduction, we are free to Google.

Automatic injection autowire

In addition to specify dependencies between the bean explicitly configured, Spirng also provided in accordance with certain functional characteristics of certain bean bean definition will automatically direct binding interdependent. By <bean> autowire the property to specify the current bean definition employ some type of automatic binding mode. In this way, you do not need to manually specify the bean explicitly define the relevant dependencies, thus eliminating some of the workload can be entered manually.

Spring provides five automatic binding mode, i.e., no, byName, byType, constructor and autodetect.

  • no

The default configuration, which does not take automatic injection, injection only rely on manual configuration.

  • byName

By name instance variables declared in the class, the value of beanName bean definitions declared in the XML configuration file matching, match the bean definition will automatically be bound to the current instance variables.

As we will inject computer of the above configuration amended as follows:

<bean id="computer" class="com.ruanshubin.springboot.ioc.entity.Computer" autowire="byName">
</bean>

Operating results as follows:

Computer{name='null', mainEngine=MainEngine{name='戴尔', type='T600', cost=3600}, display=Display{name='惠普', type='V300', cost=1000}}

The program will automatically find the id mainEngine, display of the bean to complete the injection, because there is no id for the name of the <bean>, it can not be automatically injected, this is null.

Can modify the configuration, add not automatically injected properties:

<bean id="computer" class="com.ruanshubin.springboot.ioc.entity.Computer" autowire="byName">
        <property name="name" value="组装机1"/>
</bean>

At this point, run again:

Computer{name='组装机1', mainEngine=MainEngine{name='戴尔', type='T600', cost=3600}, display=Display{name='惠普', type='V300', cost=1000}}
  • byType

And byName Similarly, byType class instance variable in accordance with the declared Type, bean declared in the XML Type profile matches, bean definitions will be matched automatically bound to the instance variable current.

As we will inject computer of the above configuration amended as follows:

<bean id="computer" class="com.ruanshubin.springboot.ioc.entity.Computer" autowire="byType">
        <property name="name" value="组装机1"/>
</bean>

run:

Computer{name='组装机1', mainEngine=MainEngine{name='戴尔', type='T600', cost=3600}, display=Display{name='惠普', type='V300', cost=1000}}

Here there is a problem, when there is an instance variable Type in the Spring container two <bean>, which one would it be injected?

Suppose the following configuration is added in the above spring-beans.xml file:

<bean id="mainEngine1" class="com.ruanshubin.springboot.ioc.entity.MainEngine">
        <constructor-arg name="cost">
                <value>3000</value>
        </constructor-arg>
        <constructor-arg name="type">
                <value>X900</value>
        </constructor-arg>
        <constructor-arg name="name">
                <value>神州</value>
        </constructor-arg>
</bean>

At this time, Spring container there are two host instance, we still byType by automatic injection.

Run the main function:

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'computer' defined in class path resource [spring-beans.xml]: Unsatisfied dependency expressed through bean property 'mainEngine'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.ruanshubin.springboot.ioc.entity.MainEngine' available: expected single matching bean but found 2: mainEngine,mainEngine1
...

Clearly, Spring will not help you make this decision, when there are multiple instances of the same Type, the error will be thrown out the program directly from you to make decisions.

  • constructor

constructor type is the type of construction method for automatically binding parameters carried out, it is also the type of binding byType mode. However, matching parameter type constructor is a method of construction, rather than the type of the instance attribute. And byType mode similar, if more than one qualifying bean definition is found, then the container returns an error.

  • autodetect

And the combination is byType constructor mode, if the object has no default argument constructor, the container will automatically bind byType priority mode. Otherwise, use the constructor mode. Of course, if injected via the constructor bind other properties is not bound, the container will use the remaining object properties byType automatic binding.

Dependency checking and inheritance

Dependency checking

Check whether the complete binding-dependent as expected, which was bound by the dependency-check tag, following four patterns:

  • none

Not dependency checking

  • simple

Container would simply attribute types and associated collection dependency checking, object reference exception type dependent.

  • object

Only the object reference type dependency checking.

  • all

simple and object combination.

inherit

New Server class inherits from Computer:

public class Server extends Computer{
    // 名称
    private String name;
    // 主机
    private MainEngine mainEngine;
    // 显示器
    private Display display;
    // GPU型号
    private String gpuType;

    public Server() {
    }

    public Server(String name, MainEngine mainEngine, Display display, String gpuType) {
        super(name, mainEngine, display);
        this.gpuType = gpuType;
    }
        
        ...
        get/set方法
        toString方法
    }

Increase in spring-beans.xml following profile:

<bean id="server" parent="computer" class="com.ruanshubin.springboot.ioc.entity.Server">
        <property name="gpuType" value="TC800"/>
</bean>

Modify the startup categories:

public class IocXmlTest {
    public static void main(String[] args) {
        XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-beans.xml"));
        Server server = beanFactory.getBean("server", Server.class);
        System.out.println(server);
    }
}

Operating results as follows:

Server{name='组装机1', mainEngine=MainEngine{name='戴尔', type='T600', cost=3600}, display=Display{name='惠普', type='V300', cost=1000}, gpuType='TC800'}

It can be seen by our parent label completed Bean succession of management.

Bean's scope

Before Spring2.0, Bean scope type container only two kinds, i.e., the prototype, and singleton, 2.0, and the introduction of three kinds of web-related scope types, i.e. request, session, global session.

singleton

  • Object instance

There is only a vessel sharing instance.

  • Objects survival time

Examples of the first request is to be destroyed or to exit the container.

prototype

  • Object instance

Examples of multiple containers.

  • Objects survival time

Each request is to create a new instance of the object instance is returned to the requesting party after, the vessel will no longer have to return the current object reference, the requesting party needs its own responsible for the current management of the returned object subsequent life cycle, including the object destroy.

  • request

Spring container, that is, to create a new Request-Processor using the object for the current request XmlWebApplicationContext requests for each HTTP, after the end of the request, the lifetime of the object instance is completed. 10 while the time when the HTTP request comes in, the container 10 will return the new object instance RequestProcessor 10 for this request, and the interference between them.

  • session

Spring container creates a new instance of an object belonging to their own UserPreferences for each individual session. Compared with the request, in addition to examples of the bean has session scope than the request scope bean may be longer survival time, others really no difference.

  • global session

global session only the application in the portlet Web-based application makes sense, it is mapped to the session global scope of the portlet. If you use this type of scope in a normal servlet-based Web applications, the container will treat it as a normal session type of scope.

  • Custom scope

In later versions of 2.0 Spring, the container provides extension points for the scope, so that the scene you can according to their needs or applications to add custom scope type. Incidentally, the default is singleton and prototype hard-coded into the code, the request, session, and global session, including custom scope type, belonging to the scope scalable ranks, they have achieved org.springframework.beans. factory.config.Scope interface.

Specifically how to design and develop a custom scope of the future we specifically written article describes.

Let's look at an interesting thing:

MainEngine removed the toString () method, and the scope is set to mainEngine prototype.

 <bean id="mainEngine" class="com.ruanshubin.springboot.ioc.entity.MainEngine" scope="prototype">
        <constructor-arg name="cost">
                <value>3600</value>
        </constructor-arg>
        <constructor-arg name="type">
                <value>T600</value>
        </constructor-arg>
        <constructor-arg name="name">
                <value>戴尔</value>
        </constructor-arg>
</bean>

Modify the main function:

public class IocXmlTest {
    public static void main(String[] args) {
        XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-beans.xml"));
        Computer computer = (Computer) beanFactory.getBean("computer");
        System.out.println(computer.getMainEngine());
        System.out.println(computer.getMainEngine());
    }
}

run:

com.ruanshubin.springboot.ioc.entity.MainEngine@4dfa3a9d
com.ruanshubin.springboot.ioc.entity.MainEngine@4dfa3a9d

Obviously, MainEngine example 2 obtained is the same.

How, then, each time the acquisition MainEngine, total returns an instance of the newly created it, you can use <lookup-method> tag:

<bean id="computer" class="com.ruanshubin.springboot.ioc.entity.Computer">
        <property name="name" value="组装机1"/>
        <property name="mainEngine" ref="mainEngine"/>
        <property name="display" ref="display"/>
        <lookup-method name="getMainEngine" bean="mainEngine"/>
</bean>

Run the main function again:

com.ruanshubin.springboot.ioc.entity.MainEngine@480bdb19
com.ruanshubin.springboot.ioc.entity.MainEngine@2a556333

Achieve their goals.

At the same time, may be made to the Computer getMainEngine modified to make each of Examples MainEngine taken from BeanFactory, the method of operation is to achieve BeanFactoryAware Computer Interface.

public class Computer implements BeanFactoryAware {
    
    private BeanFactory beanFactory;
    
        @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
    // 名称
    private String name;
    // 主机
    private MainEngine mainEngine;
    // 显示器
    private Display display;

    public Computer() {
    }

    public Computer(String name, MainEngine mainEngine, Display display) {
        this.name = name;
        this.mainEngine = mainEngine;
        this.display = display;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public MainEngine getMainEngine() {
        return beanFactory.getBean("mainEngine", MainEngine.class);
    }

    public void setMainEngine(MainEngine mainEngine) {
        this.mainEngine = mainEngine;
    }

    public Display getDisplay() {
        return display;
    }

    public void setDisplay(Display display) {
        this.display = display;
    }
}

In this case, the following configuration is removed, the above-described main program run:

<lookup-method name="getMainEngine" bean="mainEngine"/>

Operating results as follows:

com.ruanshubin.springboot.ioc.entity.MainEngine@402a079c
com.ruanshubin.springboot.ioc.entity.MainEngine@59ec2012

Still can achieve their goals.

Of course, if you do not realize BeanFactoryAware interface can also be used ObjectFactoryCreatingFactoryBean way.

ObjectFactoryCreatingFactoryBean is provided a Spring FactoryBean implementations, it returns a ObjectFactory instance. Related objects can be returned to our container management from this ObjectFactory instance ObjectFactoryCreatingFactoryBean returned.

Firstly, the spring-beans.xml ObjectFactoryCreatingFactoryBean arranged, the host and injection type.

<bean id="objectFactory" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
        <property name="targetBeanName">
                <idref bean="mainEngine"/>
        </property>
</bean>

<bean id="computer" class="com.ruanshubin.springboot.ioc.entity.Computer">
        <property name="name" value="组装机1"/>     
        <property name="display" ref="display"/>
        <property name="objectFactory">
                <ref bean="objectFactory"/>
        </property>
</bean>

Meanwhile amend Computer class:

public class Computer{
    
    private ObjectFactory objectFactory;

    public void setObjectFactory(ObjectFactory objectFactory) {
        this.objectFactory = objectFactory;
    }

    // 名称
    private String name;
    // 主机
    private MainEngine mainEngine;
    // 显示器
    private Display display;

    public Computer() {
    }

    public Computer(String name, MainEngine mainEngine, Display display) {
        this.name = name;
        this.mainEngine = mainEngine;
        this.display = display;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public MainEngine getMainEngine() {
        return (MainEngine) objectFactory.getObject();
    }

    public void setMainEngine(MainEngine mainEngine) {
        this.mainEngine = mainEngine;
    }

    public Display getDisplay() {
        return display;
    }

    public void setDisplay(Display display) {
        this.display = display;
    }
}

Operating results as follows:

com.ruanshubin.springboot.ioc.entity.MainEngine@5cb9f472
com.ruanshubin.springboot.ioc.entity.MainEngine@56ef9176

Read, read, write more, something more Spring-IOC container XML configuration, we have the opportunity to revisit later.

10431632-a592bb9d7a331a0a.jpg
Thinker walking

Welcome to sweep the two-dimensional code above, I am concerned about the micro-channel public number!

Reproduced in: https: //www.jianshu.com/p/908c91e82a5f

Guess you like

Origin blog.csdn.net/weixin_33749131/article/details/91068107