假设我有一个带有一个构造函数的类,该构造函数接受一个或多个参数。我们还假设这些参数是来自用户的某种输入。即参数不能在编译时或配置时知道,只能在运行时知道。我应该将我的类定义为原型 spring bean 还是应该用“new”创建它。
如果我应该将它定义为一个 bean,我该如何传递参数?
假设我有一个带有一个构造函数的类,该构造函数接受一个或多个参数。我们还假设这些参数是来自用户的某种输入。即参数不能在编译时或配置时知道,只能在运行时知道。我应该将我的类定义为原型 spring bean 还是应该用“new”创建它。
如果我应该将它定义为一个 bean,我该如何传递参数?
这在 Spring 中是有问题的。如果您的类不依赖于其他 bean,只需使用new
. 如果您有一个依赖于其他 Spring bean 的类,但仍想传递一些运行时参数,则当前 Spring 不支持它。
但是,请查看SPR-7431和我关于将自定义参数传递给<lookup-methods/>
. 如果一切顺利,这个特性应该是 Spring 3.2 的一部分,它应该符合你的要求。它基本上允许创建prototype
-scoped beans,同时仍然传递一些构造函数参数。
除非您的类还依赖于上下文中的其他 bean,否则不,您不应该将其设为 bean - 没有意义。只需使用new
.
使它成为 bean 的唯一令人信服的理由是它是否确实依赖于其他 bean,在这种情况下,原型范围的 bean 是合理的。但是,如果该类在其构造函数中需要这些运行时值,那么您不能真正做到这一点,除非更改类以通过某种方法而不是使用构造函数来注入它们。
使用查找方法将参数传递给构造函数的弹簧功能在 Spring 3.2.11 中不起作用,但在 Spring 版本 4.1.1 中起作用
这是我用来检查它的代码:
这是接口工厂...
package prueba;
public interface Factory {
Person createPersonWithDependencies(String name);
}
这是我们要由spring管理的bean,注入helloWorldService...
package prueba;
public class Person {
private HelloWorldService helloWorldService;
public final void setHelloWorldService(HelloWorldService extraService) {
this.helloWorldService = extraService;
}
public Person() {
super();
}
public Person(String name) {
super();
this.name = name;
}
private String name;
public final String sayHello() {
return helloWorldService.getGreeting()+" I am "+name;
}
}
这是著名的 helloworld 服务:
package prueba;
public class HelloWorldService {
public String getGreeting(){
return "hello world";
}
}
这是一个使用工厂的示例服务
package prueba;
public class Service {
private Factory factory;
public final void setFactory(Factory factory) {
this.factory = factory;
}
public void doSomeThing(){
Person bean1= factory.createPersonWithDependencies("Jhon");
System.out.println(bean1.sayHello());
Person bean2= factory.createPersonWithDependencies("Maria");
System.out.println(bean2.sayHello());
System.out.println(bean1.sayHello());
}
}
这是测试所有人的主要课程
package prueba;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestLookupMethodWithArguments {
/**
* Main method.
*/
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
Service service=applicationContext.getBean("service",Service.class);
service.doSomeThing();
}
}
最后是spring配置文件:
<?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="helloWorldService" class="prueba.HelloWorldService" />
<bean id="Person" class="prueba.Person" scope="prototype">
<property name="helloWorldService" ref="helloWorldService" />
</bean>
<bean id="myFactory" class="prueba.Factory">
<lookup-method name="createPersonWithDependencies" bean="Person" />
</bean>
<bean id="service" class="prueba.Service">
<property name="factory" ref="myFactory" />
</bean>
</beans>
使用弹簧 4.1.1 的输出
hello world I am Jhon
hello world I am Maria
hello world I am Jhon