【问题标题】:How to make @Autowired work in a regular class?如何让@Autowired 在普通课堂上工作?
【发布时间】:2017-01-09 11:28:28
【问题描述】:

这是我得到的:

@Component
class FooController {

    fun createFoo() {
        val foo = FooEntity()
        foo.name = "Diogo"

        fooRepository.save(foo)
    }

    @Autowired
    internal lateinit var fooRepository: FooRepository

}

在尝试调用createFoo() 时,我收到以下错误:

kotlin.UninitializedPropertyAccessException: lateinit property fooRepository has not been initialized

我认为在顶部添加 @Component 会使 Spring 发现我的类,从而使 @Autowired 工作,但也许我弄错了?

【问题讨论】:

标签: dependency-injection spring-boot kotlin


【解决方案1】:

仅仅在类中添加@Component 是不够的。

1) 当您使用@Component 时,您必须确保该类被组件扫描所扫描。这取决于您如何引导您的应用程序,但您可以使用 <context:component-scan base-package="com.myCompany.myProject" /> 进行 XML 配置或使用 @ComponentScan 进行 Java 配置。

如果你使用 Spring boot - 你不需要自己声明@ComponentScan,因为@SpringBootApplication 继承了它,并且默认情况下它会扫描当前包中的所有类及其所有子包。

2) 你必须从 spring 上下文中获取 bean。使用new 创建对象将不起作用。

基本上有两种方法可以从应用程序上下文中获取 bean:

  • 如果您有权访问 ApplicationContext 对象,则可以执行以下操作:

ApplicationContext ctx = ...; MyBean mb = ctx.getBean(MyBean.class);//getting by type

  • 在上下文中声明的任何 spring bean 都可以使用依赖注入 (@Autowired) 访问其他 bean

【讨论】:

  • 为了清楚起见,如果 OP 使用的是无 xml 配置(例如在 Spring Boot 中),那么组件扫描也可以在注释中声明,并且没有任何必要直接使用应用程序上下文来获取任何 bean。这将由 Spring 自动完成。
  • 我用的是Spring Boot,所以不用声明@ComponentScan?我必须同时执行这两个步骤吗?
  • @dccarmo 如果你有@SpringBootApplication - 它已经继承了@ComponentScan
  • 是的,你是对的。我发现了我的问题并在这里创建了自己的答案。谢谢你的详细解释!
【解决方案2】:

所以我对 Spring 非常陌生,并试图通过 new 创建它的实例来调用 FooController,而不是到处使用 @Autowireing。当我添加 FooController 作为调用它的类的依赖项时,它起作用了。

【讨论】:

  • 这是我需要的,在经历了几十个教程和讨论之后。似乎每个人都认为这有点明显。
猜你喜欢
  • 2015-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-03
  • 2017-03-25
  • 2013-04-01
  • 1970-01-01
  • 2019-03-26
相关资源
最近更新 更多