Spring注解@Autowired是如何工作的?
Posted
技术标签:
【中文标题】Spring注解@Autowired是如何工作的?【英文标题】:How does Spring annotation @Autowired work? 【发布时间】:2011-04-01 23:44:05 【问题描述】:我遇到了@Autowired
的例子:
public class EmpManager
@Autowired
private EmpDao empDao;
我很好奇 empDao
是如何获取集合的,因为没有 setter 方法并且它是私有的。
【问题讨论】:
看这个帖子***.com/questions/3153546/… Understanding Spring @Autowired usage的可能重复 【参考方案1】:Java 允许通过 AccessibleObject.setAccessible()
method 关闭字段或方法的访问控制(是的,首先要通过安全检查),这是反射框架的一部分(Field
和 Method
都继承自AccessibleObject
)。一旦可以发现并写入该字段,剩下的就很简单了;只是一个Simple Matter Of Programming。
【讨论】:
如果您没有猜到,我对 Spring 人员编写代码的流畅程度印象深刻。我知道他们是怎么做到的,但这并不能改变它的好坏。 我遇到了在添加公共 setter 方法之前不会注入自动装配属性的代码。是什么原因造成的? @Snekse:暂时不知道。将其作为一个完整的问题提出,包括使用的 Spring 的确切版本和有问题的代码,也许——可能——有人会告诉你。 这可能是由于设置了 Java 安全策略,因此它禁止使用反射访问私有字段。 如果我得到了你的答案,只需交叉检查它......你的意思是 - 访问控制被自动关闭,那么如果它是 @Autowired,那么在一个类中需要什么私有访问说明符跨度> 【参考方案2】:Java 允许您通过反射与类的私有成员进行交互。
查看ReflectionTestUtils,这对于编写单元测试非常方便。
【讨论】:
【参考方案3】:不需要任何设置器,您只需使用注释 @component
声明 EmpDao
类,以便 Spring 将其识别为 ApplicationContext 中包含的组件的一部分...
你有两个解决方案:
在 XML 文件 applicationContext 中手动声明 bean:<bean class="package.EmpDao" />
通过在上下文文件中查看这些行来使用自动检测:
<context:component-scan base-package="package" />
<context:annotation-config />
AND 使用 spring 注释来声明你的 spring 容器将作为组件管理的类:
@Component
class EmpDao ...
AND 以 @Autowired
注释其引用:
@Component (or @Controller, or @Service...)
class myClass
// tells the application context to inject an instance of EmpDao here
@Autowired
EmpDao empDao;
public void useMyDao()
empDao.method();
...
自动装配是通过将一个 bean 的实例放入另一个 bean 实例的所需字段中来实现的。这两个类都应该是 bean,即它们应该被定义为存在于应用程序上下文中。
Spring 知道 EmpDao
和 MyClass
bean 的存在,并会在 MyClass
中自动实例化 EmpDao
的实例。
【讨论】:
【参考方案4】:Spring 使用CGLib API 提供自动装配的依赖注入。
参考文献
Usage of CGLib forum comment by Rod Johnson 3.3.1. Injecting dependencies Pro Spring - Analyzing Spring Dependencies进一步阅读
Introduction to the Spring Framework 罗德·约翰逊(Rod Johnson)【讨论】:
除非我弄错了,@Autowired 不需要任何工具,只需要反射。 @Transactional 等其他注释确实需要检测。 我同意,@Autowired 不应该使用 CGLib。只有工厂注入或代理类等。以上是关于Spring注解@Autowired是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章