Spring's Dependency Injection

Source: Internet
Author: User
Tags set set

The so-called dependency injection is the creation of an object, the object or the data that the object depends on is created, for example, there is a student class, its constructor requires passing a dog object, that is, it depends on the dog object, or it has a string type of property, Then it relies on data of type string as well. With spring's configuration file, we can configure the dependency of an object, and when the object is instantiated, it is created with its dependencies, and this process is dependency injection.

In spring's configuration file, we configure the class that needs to be managed through the bean tag, and when it is configured, spring can help us instantiate the object of this class, and we just need to get this object from the spring container without having to manually go to new. Let's take a look at how to get spring to help us create the object, the student class code is as follows:

package org.zero01.test;public class Student {    private String name;    private int sid;    private String address;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getSid() {        return sid;    }    public void setSid(int sid) {        this.sid = sid;    }    public String getAddress() {        return address;    }    public void setAddress(String address) {        this.address = address;    }}

The spring configuration file configuration includes the following:

<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">    <bean id="stu" class="org.zero01.test.Student"></bean></beans>

Test code:

package org.zero01.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {    public static void main(String[] args) {        // 传入配置文件的路径        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");        // 通过配置的id创建对象        Student student = (Student) app.getBean("stu");        student.setSid(1);        student.setName("小明");        student.setAddress("M78星云");        System.out.println(student.getSid());        System.out.println(student.getName());        System.out.println(student.getAddress());        // 默认是单例模式的,所以得到的是同一个对象        Student student2 = (Student) app.getBean("stu");        System.out.println(student == student2);    }}

Operation Result:

1小明M78星云true

By default, spring instantiates objects are singleton, and if you don't want to be a singleton, set the scope property in the Bean label to prototype:

<bean id="stu" class="org.zero01.test.Student" scope="prototype"></bean>

Test code:

package org.zero01.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {    public static void main(String[] args) {        // 传入配置文件的路径        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");        // 通过配置的id创建对象        Student student = (Student) app.getBean("stu");        // 设置成prototype后,每次创建的都是新对象了        Student student2 = (Student) app.getBean("stu");        System.out.println(student == student2);    }}

Operation Result:

false
Next you'll look at some of the common attributes in the bean tag and the inline tags

The Init-method property in the bean tag that specifies a method that is called when the container instantiates the object, such as when I add an Init method to the Student class:

public void init() {        this.name = "小明";        this.sid = 1;        this.address = "M78星云";}

Specify this method in the Init-method property:

<bean id="stu" class="org.zero01.test.Student" init-method="init"></bean>

Test code:

package org.zero01.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {    public static void main(String[] args) {        // 传入配置文件的路径        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");        // 通过配置的id创建对象        Student student = (Student) app.getBean("stu");        System.out.println(student.getSid());        System.out.println(student.getName());        System.out.println(student.getAddress());    }}

Operation Result:

1小明M78星云

There is a property sub-tag in the bean tag, which allows us to configure the value of the object's properties, for example

    <bean id="stu" class="org.zero01.test.Student">        <property name="sid" value="1"/>        <property name="name" value="Jon"/>        <property name="address" value="北京"/>    </bean>

The test code is the same as before, slightly. The results of the operation are as follows:

1Jon北京

It is important to note that to configure the value of an attribute in an object through the property tag, this attribute must have a setter method, otherwise it cannot be configured.

The property tag has a ref attribute that has the value of the id attribute of the bean label, so that when an object is dependent on an object, it can be referenced using the ref attribute, such as a student property that relies on a dog object:

    private Dog dog;    public Dog getDog() {        return dog;    }    public void setDog(Dog dog) {        this.dog = dog;    }

You can refer to this object by using the ref attribute:

    <bean id="dog" class="org.zero01.test.Dog"/>    <bean id="stu" class="org.zero01.test.Student">        <!-- 基本数据类的值都可以自动进行转换 -->        <property name="sid" value="1"/>        <property name="name" value="Jon"/>        <property name="address" value="北京"/>        <property name="dog" ref="dog"/>    </bean>

The property tag's properties have been described above, because the property tag has only this three attribute, but it has a lot of sub-tags, for example, the three properties can be used as sub-tags:

    <bean id="dog" class="org.zero01.test.Dog"/>    <bean id="stu" class="org.zero01.test.Student">        <property name="sid">            <value type="int">1</value>        </property>        <property name="name">            <value type="java.lang.String">Jon</value>        </property>        <property name="address" value="北京"/>        <property name="dog">            <ref bean="dog"/>        </property>    </bean>

Commonly used sub-tags in property tags:

    • value specifies the values of the property
    • Ref Reference Bean Object
    • Bean creates a Bean object
    • List specifies the property value of the list type
    • Map specify attribute values for map type
    • Set specifies the property value of the set type
    • Array specifies the property value of the array type
    • Null to specify an empty property value
    • Props property values for the specified properties type

The value and ref tags have already been used, and the rest of the tags are used in the following ways:

The student class adds the following:

    private List list;    private Set set;    private Map map;    private Properties properties;    private int[] numbers;    public Properties getProperties() {        return properties;    }    public void setProperties(Properties properties) {        this.properties = properties;    }    public int[] getNumbers() {        return numbers;    }    public void setNumbers(int[] numbers) {        this.numbers = numbers;    }    public List getList() {        return list;    }    public void setList(List list) {        this.list = list;    }    public Set getSet() {        return set;    }    public void setSet(Set set) {        this.set = set;    }    public Map getMap() {        return map;    }    public void setMap(Map map) {        this.map = map;    }

Configuration file Contents:

    <bean id= "Dog" class= "Org.zero01.test.Dog"/> <bean id= "Stu" class= "org.zero01.test.Student" > &lt ;p roperty name= "list" > <list> <value>list01</value> <valu e>list02</value> <value>list03</value> <bean class= "org.zero01.test. Dog "id=" dog2 "/> <ref bean=" dog "></ref> <null/> </list&gt        ; </property> <property name= "map" > <map key-type= "java.lang.String" value-type= "Java.lang".                Object "> <entry key=" value= "01"/> <entry key= "02" value=        <entry key= "value=" 03 "/> <entry key=" dog "value-ref=" dog "/> </map> </property> <property name= "Set" > <set> <value>set01</va        Lue>        <value>set02</value> <value>set03</value> <null/>                </set> </property> <property name= "Numbers" > <array>            <value>1</value> <value>2</value> <value>3</value>                </array> </property> <property name= "Properties" > <props>            <prop key= "stature" >1.75</prop> <prop key= "Avoirdupois" >100</prop> </props> </property> </bean>

Test code:

package org.zero01.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {    public static void main(String[] args) {        // 传入配置文件的路径        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");        // 通过配置的id创建对象        Student student = (Student) app.getBean("stu");        System.out.println(student.getList());        System.out.println(student.getMap());        System.out.println(student.getSet());        for (int i : student.getNumbers()) {            System.out.print(i);        }        System.out.println("\n" + student.getProperties());    }}

Operation Result:

[list01, list02, list03, [email protected], [email protected], null]{01=零一, 02=零二, 03=零三, [email protected]}[set01, set02, set03, null]123{avoirdupois=100, stature=1.75}

As you can see, the Spring Profile label is still rich, which is just the basic common label, and some additional tag support needs to be introduced yourself.

In addition to the property tag used to configure the attribute value, there is also a constructor-arg tag, which can be configured with the constructor's parameter values, in the same way as the properties tag, such as the student class has such a constructor:

    public Student(String name, int sid, String address, Dog dog) {        this.name = name;        this.sid = sid;        this.address = address;        this.dog = dog;    }

The configuration reads as follows:

    <bean id="stu" class="org.zero01.test.Student">        <constructor-arg name="dog" ref="dog"/>        <constructor-arg name="sid" value="1"/>        <constructor-arg name="name" value="Mick"/>        <constructor-arg name="address" value="上海"/>    </bean>

Test code:

package org.zero01.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {    public static void main(String[] args) {        // 传入配置文件的路径        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");        // 通过配置的id创建对象        Student student = (Student) app.getBean("stu");        System.out.println(student.getSid());        System.out.println(student.getName());        System.out.println(student.getAddress());        System.out.println(student.getDog());    }}

Operation Result:

1Mick上海[email protected]

Constructor-arg tags In addition to the two properties used above, there is an index property and the Type property, which is used to assign a parameter assignment to, and the type attribute is used to specify the value, which is generally not available. Constructor-arg Tag also has a sub-label, its sub-label and the property tag's sub-label, here will not repeat it.

When we use property tags, we may feel a bit of egg ache, to write so many attributes or tags, so spring provides a property tag, let us use this property tag to simplify some of the configuration of the property's operation, using this attribute tag first need to Beans Introducing attribute Tag addresses:

xmlns:p="http://www.springframework.org/schema/p"

You can then use this property to mark the following:

    <bean id="dog" class="org.zero01.test.Dog"/>    <bean id="list" class="java.util.ArrayList"/>    <bean id="stu" class="org.zero01.test.Student" p:sid="1" p:name="Alisa" p:address="湖南" p:dog-ref="dog" p:list-ref="list"/>

From the configuration content can be seen, on the bean label can directly complete the configuration of properties, can let us write a lot less tags. However, one of the small drawbacks is that you cannot populate an object with a collection of objects, and you can see only an instance object that does not contain any elements from the above configuration. Therefore, this attribute tag is generally used to configure the base data type of the property value is more, encountered when the collection object needs to fill the elements of the case can only use the properties tag.

The test code is similar to the previous, slightly. The results of the operation are as follows:

1Alisa湖南[email protected][]

In the actual development, the general use of XML configuration dependent objects is relatively small, most of the situation is to use annotations to configure, because the annotations are more convenient and simple than XML. However, there are some objects that must be configured in XML, such as the data source object that is used to connect to the database, because the configuration information for this object is so varied that it is inappropriate to use annotations to configure it, so this type of object is well suited for configuration using XML, such as configuring a C3P0 connection pool:

    <bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource"          p:driverClass="com.mysql.jdbc.Driver"          p:jdbcUrl="jdbc:mysql///mysql"          p:user="root"          p:password="your_password"          p:maxPoolSize="10"          p:minPoolSize="3"          p:loginTimeout="2000"    />

Test code:

package org.zero01.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import javax.sql.DataSource;public class Test {    public static void main(String[] args) {        // 传入配置文件的路径        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");        // 通过配置的id创建对象        DataSource dataSource = (DataSource) app.getBean("c3p0");        System.out.println(dataSource);    }}

Operation Result:

com.mchange.v2.c3p0.ComboPooledDataSource[ identityToken -> 1hge0yy9t1mjbsw5vgbf8b|30b8a058, dataSourceName -> 1hge0yy9t1mjbsw5vgbf8b|30b8a058 ]

There is an abstract attribute in the bean tag that declares a node as an abstract node, which can be inherited by a quilt node, and is identical to the inheritance concept in Java, where the child node can have all the configuration information of the parent node after inheriting the parent node. For example, we can demonstrate this inheritance relationship by configuring the data source object:

    <!-- 通过 abstract 属性声明为抽象节点后才可以被继承 -->    <bean id="c3p0" class="com.mchange.v2.c3p0.ComboPooledDataSource" abstract="true"          p:driverClass="com.mysql.jdbc.Driver"          p:jdbcUrl="jdbc:mysql///mysql"          p:user="root"          p:password="your_password"    />    <!-- 通过 parent 属性来继承一个父节点,该节点会拥有父节点的所有配置信息 -->    <bean id="dataSource" parent="c3p0"          p:maxPoolSize="20"          p:minPoolSize="5"          p:loginTimeout="1500"    />    <bean id="dataSource2" parent="c3p0"          p:maxPoolSize="15"          p:minPoolSize="3"          p:loginTimeout="1000"    />

As above, the child node can have all the configuration information of the parent node after inheriting the parent node, so we can write some more stable and non-changing configuration information on the parent node. Then, on the basis of the configuration information of the parent node, the child nodes can add some configuration information, so that we can have multiple configuration options when we get the data source object.

The test code changes the previous c3p0 to DataSource or DataSource2, and the result is as follows:

com.mchange.v2.c3p0.ComboPooledDataSource[ identityToken -> 1hge0yy9t1mjprn91mvr8fv|30b8a058, dataSourceName -> 1hge0yy9t1mjprn91mvr8fv|30b8a058 ]

Note: Once a node is declared as an abstract node, it cannot be instantiated, only the child nodes that inherit it can be instantiated.

Configuring Spring's annotation Support

The above also mentions that using annotations to configure dependent objects is easier and easier, so here's a quick introduction to how to configure spring annotations so that spring can pass through annotations to manage classes.

The spring configuration file contents are modified as follows:

<?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       http://www.springframework.org/schema/beans/spring-beans.xsd       http://www.springframework.org/schema/context       http://www.springframework.org/schema/context/spring-context.xsd">    <!-- 让Spring支持注解 -->    <context:annotation-config/>    <!-- 指定哪些包下的类支持使用注解的方式管理 -->    <context:component-scan base-package="org.zero01.test"/></beans>

Add @Component annotations on the student class to let the class be managed by spring:

package org.zero01.test;import org.springframework.stereotype.Component;// 这里注解配置的值相当于xml中bean标签的id属性的值@Component("stu")public class Student {        ...

Test code:

package org.zero01.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {    public static void main(String[] args) {        // 传入配置文件的路径        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");        // 通过配置的id创建对象        Student student = (Student) app.getBean("stu");        Student student2 = (Student) app.getBean("stu");        // 同样默认是单例的        System.out.println(student == student2);    }}

Operation Result:

true

On the setter method of the property, we can configure the value of the property by @Value annotations, which is equivalent to the properties tag in the XML:

package org.zero01.test;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;@Component("stu")public class Student {    private String name;    private int sid;    private String address;    public String getName() {        return name;    }    @Value("小明")    public void setName(String name) {        this.name = name;    }    public int getSid() {        return sid;    }    @Value("1")    public void setSid(int sid) {        this.sid = sid;    }    public String getAddress() {        return address;    }    @Value("湖南")    public void setAddress(String address) {        this.address = address;    }}

Test code:

package org.zero01.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {    public static void main(String[] args) {        // 传入配置文件的路径        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");        // 通过配置的id创建对象        Student student = (Student) app.getBean("stu");        System.out.println(student.getSid());        System.out.println(student.getName());        System.out.println(student.getAddress());    }}

Operation Result:

1小明湖南

This @Value annotation, in addition to the setter method of the property, can also be written directly on the property, the function is the same:

package org.zero01.test;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;@Component("stu")public class Student {    @Value("小明")    private String name;    @Value("1")    private int sid;    @Value("湖南")    private String address;    ...

The test code, as before, runs the same result, slightly.

Spring's Dependency Injection

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.