【问题标题】:ways to inject a object of a class in spring controller?在spring控制器中注入类对象的方法?
【发布时间】:2013-09-12 06:54:48
【问题描述】:

我需要在spring controllerapplicaionContext.xml 中注入一个java 类的object。我的控制器将是,

@Controller
public class SpringController{

private MyClass obj;

}

我知道我可以使用 @Autowired 注释来做到这一点。

controllerapplicaionContext.xml 创建一个对象真的很好吗?我还可以使用<bean> 标签内的<property> 标签在控制器中注入一个类的对象吗?

这真的可能吗?或者如果这是一个愚蠢的问题,请原谅我。

我需要知道如何在 Spring 控制器中注入类的对象的可能方法?

【问题讨论】:

标签: java spring spring-mvc controller spring-annotations


【解决方案1】:

您当然可以使用@Autowired 注释来自动连接关系,这样可以减少在applicationContext.xml 文件中为controller 定义属性和构造函数参数的需要。并且还要给类添加依赖,不需要修改配置文件。

但它也有一些缺点,比如如果你使用@Autowired,Spring 托管 bean 之间的wiring details 将没有任何明确的文档。并且要了解 bean 之间的关系,您必须检查托管 bean。但是,如果您使用configuration files 定义关系,则可以在一处找到关系详细信息。

您可以通过applicaionContext.xml 将一个类的对象注入您的控制器,如下所示:

基于构造函数的注入

@Controller
public class SpringController{

private MyClass obj;

public SpringController(MyClass obj){
this.obj=obj;
}
}

<bean id="myClassImpl" class="x.y.z.MyClassImpl"></bean>

<bean id="springController" class="x.y.z.web.controllers.SpringController">
    <constructor-arg ref="myClassImpl"></constructor-arg>
</bean>

基于 Setter 的注入

@Controller
public class SpringController{

private MyClass obj;

public void setObj(MyClass obj){
this.obj=obj;
}
public MyClass getObj(){
return obj;
}
}

<bean id="myClassImpl" class="x.y.z.MyClassImpl"></bean>

<bean id="springController" class="x.y.z.web.controllers.SpringController">
    <property name="obj" ref="myClassImpl"></property>
</bean>

【讨论】:

  • 感谢您的回复。我不喜欢构造函数注入。我做了setter和gertter注入。但是构造函数会被调用两次,因为通过这种方式创建了两个对象。
【解决方案2】:

如果你想在控制器中注入一个对象并且你特别想使用xml,那么你应该在应用程序上下文中创建一个单例范围的控制器类的bean,而不是对控制器进行组件扫描。 您的控制器类不需要使用@Controller 进行注释。

然后你必须扩展一些控制器,比如AbstractCommandController, AbstractController, AbstractFormController, AbstractWizardFormController, BaseCommandController, CancellableFormController, MultiActionController SimpleFormController, UrlFilenameViewController

现在要注入特定对象,您可以使用基于构造函数和设置器的注入。 或者您可以按名称或类型使用 Autowring 来自动注入对象。 确保您还在 Application Context 中声明了该对象的 bean。

在 DispatcherServlet 收到请求并完成解析语言环境、主题等的工作后,它会尝试使用 HandlerMapping 解析 Controller。当找到一个Controller处理请求时,将调用定位到的Controller的handleRequest方法;然后,定位到的 Controller 负责处理实际请求并(如果适用)返回适当的 ModelAndView。

就是这样。

【讨论】:

  • 那么我的请求将如何进入控制器,如果我没有指定@Controller?
  • Application Context 是一个容器,负责实例化和自动装配所有 bean 或对象。所以基本上当您使用 context:component scan 时,它会扫描包并创建所有带有注释的类的 bean @controller,@service 等..所以基本上创建了一个控制器类的对象..同样可以通过在xml中手动声明bean来实现。
  • 如果我没有指定@Controller,我想扩展任何类,说它是一个控制器?
  • @KitePlayer 是的,你必须扩展一些控制器,比如 AbstractCommandController、AbstractController、AbstractFormController、AbstractWizardFormController、BaseCommandController、CancellableFormController、MultiActionController SimpleFormController、UrlFilenameViewController
  • @KitePlayer 在 DispatcherServlet 收到请求并完成解析语言环境、主题等的工作后,它会尝试使用 HandlerMapping 解析 Controller。当找到一个Controller处理请求时,将调用定位到的Controller的handleRequest方法;然后,定位到的 Controller 负责处理实际请求并 - 如果适用 - 返回适当的 ModelAndView。
【解决方案3】:

实际上,使用 xml 和注解的注入在幕后是相同的。 Xml 是老式的,而注解是较新的。

基本上有两种注入类型。

byName

按属性名称自动装配。 Spring容器看属性 在 XML 中将 autowire 属性设置为 byName 的 bean 配置文件。然后它尝试匹配和连接它的属性 在配置文件中使用由相同名称定义的 bean。

您可以使用 xml 和注解为 bean 指定明确的名称。

@Service("BeanName")
@Component("BeanName")
@Controller("BeanName")

<bean name="BeanName" class="someclass"></bean>

并使用@Qualifier注解注入bean。

@Autowired
 @Qualifier("BeanName")

和xml

<bean id="MyBean2" class="MyBean2 class">
<property name="Property of MyBean2 which refers to injecting bean" ref="BeanName" />
</bean>

byType

按属性数据类型自动装配。 Spring容器看 将 autowire 属性设置为 byType 的 bean 的属性 在 XML 配置文件中。然后它会尝试匹配并连接一个 属性,如果它的类型与 bean 名称中的一个完全匹配 配置文件。如果存在多个此类 bean,则致命 抛出异常。

默认的自动连线模式是byType,所以spring会在自动连线中寻找匹配的类型。但是,旧版本的 Spring 在注入时具有默认行为none。如果你想使用 xml 注入 byType,你应该明确告诉 spring 容器。

例如 MyBean2 有一个对 MyBean 的引用,通过将 autowired 属性设置为 byType 它会自动处理注入。

<bean id="MyBean" class="MyBean class">
<property name="Property of MyBean2 which refers to injecting bean" ref="BeanName" />
</bean>

<bean id="MyBean2" class="MyBean2 class" 
      autowire="byType">      
 </bean>

这还取决于代码中注入的位置。有两种类型,setter getter 注入和构造函数注入。

注意:@Controller 没有区别,因为它们已经在 spring 上下文中。

另请参阅

Spring Beans Auto wiring

【讨论】:

  • 感谢您的回复。但我知道自动接线。我在问如何用 XML 注入?
  • 查看我的编辑。但是,您的问题并没有具体说明 xml 注入。
  • 我特别要求控制器。
  • 我认为控制器也在 spring 上下文中并且没有区别尝试
【解决方案4】:

我遇到了这样的问题。我得到“发现不明确的映射”。 (我也使用 xml 配置,我将一个 bean 注入到我的控制器中) 然后看着我的控制台,我意识到我的控制器被实例化了两次。 更详细地看,我注意到我的注释

@Controller(value = "aController")

(注意值 = "aController")

与我的 xml 配置不同,我用不同的 bean id 建立同一个控制器

<bean id="aControleRRRRR" class="package.ControllerClassName"
    p:property-ref="beanToInject" />

(注意 id="aControleRRRRR")

因此,总而言之,您的 @Controller 名称 (value = "aController") 需要与您在 XML 配置中提供的名称完全相同 (id="aControleRRRRR"),以便 Spring 可以设法区分它们引用同一个 bean(实例)

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    • 2014-11-06
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 2020-01-15
    相关资源
    最近更新 更多