[英]Spring configuration for dependency injection
I'm learning spring dependency injection with Struts2, beased on a web project. 我正在通过Struts2学习spring依赖注入,这是在一个Web项目上进行的。 In my example, I created a zoo having animals. 在我的示例中,我创建了一个有动物的动物园 。 Animal will talk if injection is succeed. 如果注射成功,动物会说话。 Eg in the console, we will see dog's talk : 例如在控制台中,我们将看到狗的谈话:
Wowowo ฅ^•ﻌ•^ฅ
However, if injection failed, then we'll see : 但是,如果注入失败,那么我们将看到:
zooService bean has not been injected.
Here's the architecture of my application : 这是我的应用程序的体系结构:
com.zoo.controller.ZooController
is the controller for receiving web actions. com.zoo.controller.ZooController
是用于接收Web操作的控制器。 com.zoo.service.ZooService
is the interface for animal's talk com.zoo.service.ZooService
是动物对话的界面 com.zoo.service.ZooServiceForDog
is the implementation for dog's talk com.zoo.service.ZooServiceForDog
是狗说话的实现 Up to the step, everything is OK. 到步骤为止,一切正常。 And the dependency injection is handled by Spring using an XML file called applicationContext.xml
. Spring通过使用名为applicationContext.xml
的XML文件处理依赖项注入。 However, I've 2 types of configuration for this file, the first one Config 1 works but the second Config 2 doesn't. 但是,我对此文件有2种配置类型,第一种Config 1有效,而第二种Config 2无效。
Injection succeed using config 1. 使用配置1 注入成功 。
<?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="zooService" class="com.zoo.service.ZooServiceForDog" />
</beans>
Injection failed using config 2. 使用配置2 注入失败 。
<?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="zooController" class="com.zoo.controller.ZooController">
<property name="zooService" ref="zooServiceBean" />
</bean>
<bean id="zooServiceBean" class="com.zoo.service.ZooServiceForDog" />
</beans>
Can somebody explain why the Config 2 cannot work ? 有人可以解释为什么Config 2无法正常工作吗?
Here're other codes that might be helpful to the issue : 这是其他可能有助于解决此问题的代码:
Class com.zoo.controller.ZooController
: com.zoo.controller.ZooController
类:
package com.zoo.controller;
import com.zoo.service.ZooService;
import com.opensymphony.xwork2.ActionSupport;
public class ZooController extends ActionSupport {
private static final long serialVersionUID = 1L;
private ZooService zooService;
public String live () {
if (zooService != null) {
zooService.talk();
} else {
System.out.println("zooService bean has not been injected.");
}
return SUCCESS;
}
public ZooService getZooService() {
return zooService;
}
public void setZooService(ZooService zooService) {
this.zooService = zooService;
}
}
It cannot work because the scope of the zooController
is singleton. 它不能工作,因为zooController
的范围是单例。 You should make the scope prototype
. 您应该使范围prototype
。
<bean id="zooController" class="com.zoo.controller.ZooController" scope="prototype" >
<property name="zooService" ref="zooServiceBean" />
</bean>
The dependency management is defined by the container: 依赖项管理由容器定义:
If your actions managed by Struts container, then Struts is creating them in the
default
scope. 如果您的操作由Struts容器管理,则Struts会在default
范围内创建它们。 If your actions is managed by Spring container then you need to define the scope of the action beans, because Spring by default usessingleton
scope and if you don't want to share your action beans between user's requests you should define the corresponding scope. 如果您的操作是由Spring容器管理的,那么您需要定义操作bean的范围,因为默认情况下,Spring使用singleton
范围,并且如果您不想在用户请求之间共享操作bean,则应该定义相应的范围。 You can useprototype
scope, which means a new instance is returned by the Spring each time Struts is being built an action instance. 您可以使用prototype
作用域,这意味着每次构建Struts动作实例时,Spring都会返回一个新实例。
The Struts integrates to Spring via plugin. Struts通过插件集成到Spring。 Make sure it has 确保它有
<constant name="struts.objectFactory" value="spring" />
then you can delegate actions to Spring 然后可以将动作委派给Spring
References: 参考文献:
EDIT: 编辑:
In your first config you declared a bean zooService
that will be injected by Struts using spring
object factory. 在第一个配置中,您声明了一个bean zooService
,它将由Struts使用spring
对象工厂注入。
In your second config you declared two beans zooController
and zooServiceBean
, but you changed the name of the second bean. 在第二个配置中,您声明了两个bean zooController
和zooServiceBean
,但是您更改了第二个bean的名称。 Then you tried to build the action bean using spring
object factory like in the first case. 然后,您尝试像第一种情况一样使用spring
对象工厂来构建action bean。 And because there's no bean with name zooService
the autowiring has been failed. 并且因为没有名称为zooService
的bean,所以自动装配已失败。 Because by default Struts is configured to autowire beans from the application context by name. 因为默认情况下,Struts配置为按名称从应用程序上下文自动装配bean。
Then you changed struts.xml
and used a bean reference in the action class attribute. 然后,您更改了struts.xml
并在操作类属性中使用了bean引用。 It means that Struts will use app context to get a bean from Spring. 这意味着Struts将使用应用上下文从Spring获取Bean。 And because it has an explicit dependency on the second bean, it would be wired before the bean is returned. 并且由于它对第二个bean有明确的依赖关系,因此将在返回该bean之前进行连接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.