【问题标题】:How does Spring annotation @Autowired work?Spring注解@Autowired是如何工作的?
【发布时间】:2011-04-01 23:44:05
【问题描述】:

我遇到了@Autowired的例子:

public class EmpManager {
   @Autowired
   private EmpDao empDao;
}

我很好奇 empDao 是如何获取集合的,因为没有 setter 方法并且它是私有的。

【问题讨论】:

标签: spring dependency-injection autowired


【解决方案1】:

Java 允许通过 AccessibleObject.setAccessible() method 关闭字段或方法的访问控制(是的,首先要通过安全检查),这是反射框架的一部分(FieldMethod 都继承自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 知道 EmpDaoMyClass bean 的存在,并会在 MyClass 中自动实例化 EmpDao 的实例。

    【讨论】:

      【解决方案4】:

      Spring 使用CGLib API 提供自动装配的依赖注入。


      参考文献

      进一步阅读

      【讨论】:

      • 除非我弄错了,@Autowired 不需要任何工具,只需要反射。 @Transactional 等其他注释确实需要检测。
      • 我同意,@Autowired 不应该使用 CGLib。只有工厂注入或代理类等。
      猜你喜欢
      • 1970-01-01
      • 2015-09-29
      • 2014-02-12
      • 1970-01-01
      • 2021-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多