Spring MVC - @Autowired 如何工作?

Posted

技术标签:

【中文标题】Spring MVC - @Autowired 如何工作?【英文标题】:Spring MVC - How does @Autowired work? 【发布时间】:2014-02-12 02:38:21 【问题描述】:

我正在使用 Java 和 Spring 开发一个 Web 应用程序。我是 Spring 的新手,所以作为一个学习的机会,我基本上得到了一个现有的应用程序,并被告知要扩展它。 我无法理解 @Autowired 的工作原理。我了解依赖注入的高级概念,但我想知道@Autowired注解如何知道要注入哪个接口的具体实现?

为了把我的问题放在上下文中,我将解释我遇到的问题:

我有一个名为 PostDao接口,以及一个名为 PostDaoImpl,它实现了 PostDao。然后我有另一个名为 PostDaoPublicImpl,它扩展了 PostDaoImpl。这些类存在于我的持久层中。

然后我有一个名为 PostServiceinterface,以及一个名为 PostServiceImpl,它们实现了 邮政服务。然后我有另一个名为 PostServicePublicImpl,它扩展了 PostServiceImpl。这些类存在于我的服务层中。

PostServiceImpl 中,以下行注入以下对象:

@Autowired private PostDao postDao; 
//This injects an object of the class PostDaoImpl

我的问题是,在 PostServicePublicImpl 中我如何拥有与上述相同的声明,但让它注入类 PostDaoPublicImpl 的对象:

@Autowired private PostDao postDao; 
//This injects an object of the class PostDaoPublicImpl

我觉得好像我理解了@Autowired 注解的工作原理,那么我将能够解决这个问题。任何解决问题的帮助和建议将不胜感激。

【问题讨论】:

【参考方案1】:

首先你需要understand how Autowiring works

然后在 bean 定义中,定义 autowire 策​​略 - 对于我们的情况,让它成为 byName

<bean id="postDaoPublicImpl" class="com.yourpackage.PostDaoPublicImpl" autowire="byName" />

这意味着,如果任何类有一个名为“postDaoPublicImpl”的属性,即上面 bean 的 bean id,将自动注入 bean 实例

之后在你的班级PostServicePublicImpl 定义这样的属性

class PostServicePublicImpl  

@Autowired private PostDaoPublicImpl postDaoPublicImpl; 
//here Spring will auto inject PostDaoPublicImpl implementation, since this property name matches the bean id and (auto wiring strategy is "byName")


【讨论】:

我得到一个运行时错误:原因:org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private xx.persistence.dao.PostDao xx.services.impl.PostServiceImpl.postDao;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有定义类型 [xx.persistence.dao.PostDao] 的唯一 bean:预期的单个匹配 bean 但找到 2:[postDaoImpl,postDaoPublicImpl] 在 bean 定义中,您定义了 2 个可以转换为 za.co.entelect.projects.codereview.persistence.dao.PostDao 的 bean,这会造成混乱。首先将 autowire 策​​略设置为 byName,然后为这 2 个 bean 赋予不同的 bean id sanbhat 您能否将评论中所述的包编辑为我在编辑评论中使用的格式 我不明白为什么它告诉我我已经定义了 2 个可以转换为 xx.persistance.dao.PostDao 的 bean。我只是在 Persistance 层的 application-context.xml 文件中添加了一个 bean。【参考方案2】:

我找到了一个更简单的方法来解决我的问题。使用@Qualifier 标签,我可以为接口的每个实现指定一个唯一的名称。然后在自动连接对象时,我只提供一个限定符,并注入匹配该限定符的实现对象。

【讨论】:

【参考方案3】:

将此添加到您的应用程序上下文中

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

【讨论】:

以上是关于Spring MVC - @Autowired 如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

Spring MVC 自定义标签如何使用@Autowired自动装配注解

NUnit 5 Spring MVC 测试 NoSuchBeanDefinitionException 用于子模块中的 Autowired 依赖项

Maven 工程下 Spring MVC 站点配置 C3P0连接池与@Autowired的应用

spring mvc 里@Autowired注入的bean和ApplicationContext的getBean获取的bean不是同一个(hashCode不一样)

Spring Autowired空指针异常

Spring MVC 中获取 HttpServletRequest request, HttpServletResponse response 对象的方法