Method injection of spring learning

Keywords: Java xml Spring encoding

Single bean injection multiple beans

MyPrototype,MyController

@Component
@Scope("prototype")
public class MyPrototype {
}
@Controller
public class MyController {
    @Autowired
    MyPrototype myPrototype;
    public MyPrototype getMyPrototype() {
        return myPrototype;
    }
}

MyConfig

@Configuration
@ComponentScan(value="com.learn.annotation2")
public class MyConfig {

}

Test code

@Test
public void test(){
    ApplicationContext app =  new AnnotationConfigApplicationContext(MyConfig.class);
    MyController myController=app.getBean("myController",MyController.class);
    System.out.println(myController.getMyPrototype());
    System.out.println(myController.getMyPrototype());
}

The operation results are as follows:

It can be seen that when multiple myprototypes are injected into a single instance of myController, myPrototype is different for myController or an instance. If we want to get different myprototypes each time, what should we do?

ApplicationContextAware

Override MyController, inherit ApplicationContextAware interface to set ApplicationContext, and override getMyPrototype method to get bean through ApplicationContext.

@Controller
public class MyController implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    @Autowired
    MyPrototype myPrototype;

    public MyPrototype getMyPrototype() {
        return applicationContext.getBean("myPrototype",MyPrototype.class);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

Test code unchanged
The operation results are as follows:

You can see that the two addresses are different. But this kind of processing is not elegant, and the coupling between business code and spring framework is too high.

@Lookup

For XML configuration, use the lookup method tag, such as:

<bean id="commandManager" class="com.learn.di.CommandManager">
    <lookup-method name="createCommand" bean="myCommand"/>
</bean>

MyController is rewritten as follows:

@Controller
public abstract class MyController{
    @Autowired
    MyPrototype myPrototype;

    public MyPrototype getMyPrototype() {
        return createMyPrototype();
    }

    @Lookup()
    protected abstract MyPrototype createMyPrototype() ;
}

Test code and so on remain unchanged.
The operation results are as follows:

Through the @ Lookup annotation, you can see that the addresses of the two times are different.

Method substitution

di.xml configuration

<?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:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="myValueCalculator" class="com.learn.di.MyValueCalculator">
        <replaced-method name="computeValue" replacer="replacementComputeValue">
            <arg-type>String</arg-type>
        </replaced-method>
    </bean>

    <bean id="replacementComputeValue" class="com.learn.di.ReplacementComputeValue"/>
</beans>

MyValueCalculator and ReplacementComputeValue

public class MyValueCalculator {
    public String computeValue(String input) {
        System.out.println(input);
        return "old method";
    }
}
public class ReplacementComputeValue implements MethodReplacer {

    @Override
    public Object reimplement(Object o, Method method, Object[] objects) throws Throwable {
        return "new method";
    }
}

Test code

@Test
public void test11() {
    ApplicationContext app = new ClassPathXmlApplicationContext("di10.xml");
    MyValueCalculator myValueCalculator = app.getBean("myValueCalculator", MyValueCalculator.class);
    System.out.println(myValueCalculator.computeValue("input"));
}

The operation results are as follows:

In the configuration file, the computeValue method in myValueCalculator class is set, which is replaced by the method of replacementComputeValue. Finally, the replacement method of replacementComputeValue is called, and new method is output.

Posted by discostudio on Tue, 22 Oct 2019 08:46:44 -0700