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。这些类存在于我的持久层中。
然后我有一个名为 PostService 的 interface,以及一个名为 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 MVC 中获取 HttpServletRequest request, HttpServletResponse response 对象的方法