我是Spring的新手,正在尝试理解"将原型bean注入到单例bean中"的概念。据我理解,在单例模式下,每个Spring IoC容器只有一个实例,无论你检索多少次。
在下面的示例中,我开发了一个单例bean,并在其中引用原型bean:
validator.validate(requestId);
因为private RequestValidator validator
还没有被实例化。<bean id="requestProcessor" class="com.injection.testing.RequestProcessor">
<property name="validator" ref="validator" />
</bean>
<bean id="validator" class="com.injection.testing.RequestValidator" scope="prototype" />
RequestProcessor.java
public class RequestProcessor {
private RequestValidator validator;
public RequestProcessor(){
System.out.println("Constructor:: RequestProcessor instance created!");
}
public void handleRequest(String requestId){
System.out.println("Request ID : "+ requestId);
validator.validate(requestId);
}
public RequestValidator getValidator() {
return validator;
}
public void setValidator(RequestValidator validator) {
this.validator= validator;
}
}
请求验证器.java
public class RequestValidator {
private List<String> errorMessages = new ArrayList<String>();
public RequestValidator() {
System.out.println("Constructor:: RequestValidator instance created!");
}
// Validates the request and populates error messages
public void validate(String requestId){
System.out.println("RequestValidator :"+requestId);
}
public List<String> getErrorMessages() {
return errorMessages;
}
}
现在当我调用主方法时,我看到以下输出:MainDemo.java
public class MainDemo {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
RequestProcessor processor = (RequestProcessor) context.getBean("requestProcessor");
processor.handleRequest("1212");
System.out.println("------------------------");
processor.handleRequest("1213");
}
}
输出结果为:
Constructor:: RequestProcessor instance created!
Constructor:: RequestValidator instance created!
Request ID : 1212
RequestValidator :1212
------------------------
Request ID : 1213
RequestValidator :1213
现在看输出结果,第二个调用processor.handleRequest("1213");
时bean未被实例化,而是使用已经实例化的bean,因此构造函数不会再次被调用。所以原型作用域的validator
只充当单例模式。
对我来说:我期望每当我从应用程序上下文中获取requestProcessor时,它都将与new validator
连接,因为我们声明了validator bean是原型范围的。但实际上并没有发生这种情况。
如何解决?我的理解正确吗?
另一种方式:
<!-- Lookup way -->
<bean id="requestProcessor" class="com.injection.testing.RequestProcessor" >
<lookup-method name="getValidator" bean="validator" />
</bean>
<bean id="validator" class="com.injection.testing.RequestValidator" scope="prototype" />
如果我调用我的主方法,我会看到以下的输出和错误:
这里执行了代码validator.validate(requestId);
,而private RequestValidator validator;
没有实例化,所以出现了空指针异常。
下面的代码中我已经展示了:
public class MainDemo {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
RequestValidator requestValidator = (RequestValidator) context.getBean("validator");
RequestProcessor processor = (RequestProcessor) context.getBean("requestProcessor");
processor.handleRequest("1212");
System.out.println("------------------------");
processor.handleRequest("1213");
}
}
现在我看到以下错误:
Constructor:: RequestProcessor instance created!
Constructor:: RequestValidator instance created!
Request ID : 1212
Exception in thread "main" java.lang.NullPointerException
at com.injection.testing.RequestProcessor.handleRequest(RequestProcessor.java:12)
at com.injection.testing.MainDemo.main(MainDemo.java:14)
createValidator
作为查找方法,而不是getValidator
。 - Ken Bekov