Home  >  Article  >  Java  >  Detailed explanation of unknown injection methods in Java Spring

Detailed explanation of unknown injection methods in Java Spring

黄舟
黄舟Original
2017-03-24 10:51:251628browse

Preface

Using the XML file for configuration in the Spring configuration file actually allows Spring to execute the corresponding code, for example:

  • Using the 60e23eb984d18edbb092da6b8f295aba element actually lets Spring execute the parameterless or parameterized constructor

  • Using the 3fcb97bb666cd7884d4d3210fb47b5ef element actually allows Spring to execute the parameterless or parameterized constructor. Let Spring execute the setter method once

But Java programs may also have other types of statements: calling getter methods, calling ordinary methods, accessing fields of classes or objects, etc., and Spring also provides this This statement provides the corresponding configuration syntax:

  • Calling the getter method: using PropertyPathFactoryBean

  • Calling the Filed value of the class or object: using FiledRetrievingFactoryBean

  • Call ordinary methods: Use MethodInvokingFactoryBean

Inject the properties of other BeansValue

PropertyPathFactoryBean is used to Obtain the attribute value of the target Bean (actually the value returned by calling the getter method). The obtained value can be injected into other Beans, or a new Bean can be defined directly. Look at the following configuration file:

<bean id="person" class="com.abc.Person">
    <property name="age" value="30" />
    <property name="son">
        <!-- 使用嵌套Bean定义属性值 -->
        <bean class="com.abc.service.Son">
            <property name="age" value="11" />
        </bean>
    </property>
</bean>

<bean id="son2" class="com.abc.service.Son">
    <!-- age属性不是直接注入,而是将person中的son的age属性赋值给son2的age属性 -->
    <property name="age">
        <!-- 注意这里使用的是PropertyPathFactoryBean -->
        <bean id="person.son.age" 
            class="org.springframework.beans.factory.config.PropertyPathFactoryBean" />
    </property>
</bean>

The attributes of the Person class and Son class can be seen from the configuration file, which are no longer given. The main program is as follows:

public class Test {
    public static void main(String args[]) {
        ApplicationContext ac = 
            new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("age=" + ac.getBean("son2", Son.class).getAge());
    }
}

Output result:

age=11

The attribute value of the Bean instance can not only be injected into another Bean, but also the attribute value of the Bean instance can be directly defined as a Bean instance. This is also Completed through PropertyPathFactoryBean. Add this section to the above configuration file:

<bean id="son1" 
    class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
    <!-- 确定目标Bean,表明son1来自哪个Bean的组件 -->
    <property name="targetBeanName" value="person" />
    <!-- 确定属性,表明son1来自目标Bean的哪个属性 -->
    <property name="propertyPath" value="son" />
</bean>

Execute the above Test class, replace son2 with son1, and the result will be the same.

Inject the Field values ​​of other Beans

Through the FieldRetrievingFactoryBean class, you can inject the Field values ​​of other Beans into other Beans, or directly define new Beans. The following is a configuration fragment:

<bean id="son" class="com.abc.service.Son">
    <property name="age">
        <bean id="java.sql.connection.TRANSACTION_SERIALIZABLE"
            class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" />
    </property>
</bean>

The main test program is similar to the one defined above and is no longer provided here. The execution results are as follows:

age=8

In this configuration, the age value of the son object, Equal to the value of java.sql.Connection.TRANSACTION_SERIALIZABLE. In the above definition, when defining the FieldRetrievingFactoryBean factory Bean, the specified id is not the unique identifier of the Bean instance, but the expression of the specified Field (the value to be taken out).

Note: Field can be either static or amorphous. The Field expression specified in the above configuration snippet is a static Field value and therefore can be accessed directly through the class name. If the Field value is non-static, it should be accessed through a Bean that already exists in the container - that is, the first phrase of the Field expression should be a Bean that already exists in the container.

Field values ​​can also be defined as Bean instances. For example, add the following paragraph to the configuration file:

<bean id="age" 
    class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
    <!-- targetClass指定Field所在的目标类 -->
    <property name="targetClass" value="java.sql.Connection" />
    <!-- targetField指定Field名 -->
    <property name="targetField" value="TRANSACTION_SERIALIZABLE" />
</bean>

Add the following output to the main program:

System.out.println("age=" + ac.getBean("age"));

Execution results and Same as above.

When using FieldRetrievingFactoryBean to obtain the Field value, you must specify the following two attributes:

  • targetClass or targetObject: used to specify the location of the Field value respectively The target is tired or the target object. If the Field to be obtained is static, use targetClass to specify the target; if the Field is non-static, use targetObject to specify the target object

  • targetField: Specify the Field of the target class or target object Name

If Field is a static Field, there is a more concise way of writing:

<bean id="age" 
    class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
    <!-- value指定哪个类的哪个静态域值 -->
    <property name="staticField" value="java.sql.Connection.TRANSACTION_SERIALIZABLE" />
</bean>

Inject other Bean method return value

Through MethodInvokingFactoryBean factory Bean, the return value of the target method can be injected as the property value of the Bean. This factory bean is used to obtain the return value of the specified method, which can be either a static method or an instance method; this value can be injected into the specified attribute of the specified Bean instance, or it can be directly defined as a Bean instance. Look at the example:

<bean id="valueGenerator" class="com.abc.util.ValueGenerator" />
<bean id="son1" class="com.abc.service.Son">
    <property name="age">
        <!-- 获取方法返回值:调用valueGenerator的getValue方法 -->
        <bean 
            class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
            <property name="targetObject" ref="valueGenerator" />
            <property name="targetMethod" value="getValue" />
        </bean>
    </property>
</bean>

The following is the ValueGenerator:

public class ValueGenerator {
    public int getValue() { return 2; }
    public static int getStaticValue () { return 3;}
}

The test program still prints the value of age in son1, the code is omitted, the results are as follows:

age=2

If you want to call the static method, Then modify the configuration to:

<bean id="son1" class="com.abc.service.Son">
    <property name="age">
        <!-- 获取方法返回值:调用valueGenerator的getStaticValue方法 -->
        <bean 
            class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
            <property name="targetClass" value="com.abc.util.ValueGenerator" />
            <property name="targetMethod" value="getStaticValue" />
        </bean>
    </property>
</bean>

The test result is:

age=3

Since Java supports overloading, only giving the method name is not enough to determine the call. Which method can be successfully called through the above configuration because both methods in ValueGenerator have no parameters. If there are parameters in the method, how to configure them? Add the following content to the configuration file:

<bean id="sysProps" 
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetClass" value="java.lang.System" />
    <property name="targetMethod" value="getProperties" />
<bean>
<bean id="javaVersion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <!-- 指向上面的sysProps Bean -->
    <property name="targetObject" value="sysProps" />
    <property name="targetMethod" value="getProperty" />
    <!-- 这里配置参数 -->
    <property name="arguments">
        <!-- 使用list元素列出调用方法的多个参数 -->
        <list>
            <value>java.version</value>
        </list>
    </property>
<bean>

The above example is equivalent to calling the getProperty method of java.lang.System with "java.version" as a parameter. The return value will create a Bean named javaVersion. That is equivalent to:

javaVersion = java.lang.System.getProperty("java.version");

Same as Field in the previous article, if the method to be called is a static method, there is a more concise method:

<bean id="myBean"
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <!-- 使用staticMethod属性,直接指定目标类的目标方法 -->
    <property name="staticMethod" value="com.abc.util.ValueGenerator.getStaticValue" />
</bean>

The above is the detailed content of Detailed explanation of unknown injection methods in Java Spring. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn