- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
这是来自 the Spring documentation 的示例, 第 6.12.5 节:
@Configuration
public class ServiceConfig {
@Autowired
private AccountRepository accountRepository;
@Bean
public TransferService transferService() {
return new TransferServiceImpl(accountRepository);
}
}
我的问题是:为什么一定要在 new TransferServiceImpl()
使用之前创建 accountRepository
?顺便说一下,我不明白 Spring 如何知道第二个依赖于第一个正在设置的(除非它通过 transferService()
字节码)。是不是因为 Spring 做事的顺序保证了 @Autowired
变量在可能调用 @Bean
方法之前被处理?处理顺序是什么?什么样的情况会导致Spring乱序处理?
我问的原因是我遇到这样的情况不起作用,即 new
正在使用 null
参数执行。 @Autowired
变量设置得太晚,或者根本没有设置(我猜是后者,基于一些 log4j.logger.org.springframework.beans
调试输出,但我不确定)。情况当然要复杂得多——它是一个大型应用程序,并且在配置类中有更多的 @Autowired
和 @Bean
定义。使用 @DependsOn
没有帮助。在我得到一个最小的例子之前,通过删除代码来缩小问题范围会花费很多时间,但我想看看我是否可以通过了解更多关于 Spring 如何处理事物的细节来深入了解这个问题,然后再开始困难的代码减少路径。
最佳答案
why must it happen that
accountRepository
is created before it's used by newTransferServiceImpl()
?
事实并非如此。 accountRepository
可能被视为 null
。
来自 documentation you linked 中的注释(它的最新版本)
Make sure that the dependencies you inject that way are of the simplest kind only.
@Configuration
classes are processed quite early during the initialization of the context and forcing a dependency to be injected this way may lead to unexpected early initialization. Whenever possible, resort to parameter-based injection as in the example above.Also, be particularly careful with
BeanPostProcessor
andBeanFactoryPostProcessor
definitions via@Bean
. Those should usually be declared asstatic
@Bean
methods, not triggering the instantiation of their containing configuration class. Otherwise,@Autowired
and@Value
won’t work on the configuration class itself since it is being created as a bean instance too early.
总而言之,Configuration
类最终将只是应用程序上下文中的另一个 bean。因此,它将由所有注册的 BeanPostProcessor
处理。 bean 。
@Autowired
由 AutowiredAnnotationBeanPostProcessor
处理.据推测,您正在使用自动注册的 AnnotationConfigApplicationContext
。
在你的例子中,这是不完整的,因为
...but determining exactly where the autowired bean definitions are declared is still somewhat ambiguous
但是,我们可以假设一些其他配置为 AccountRepository
bean 提供了 bean 定义。一旦应用程序上下文实例化了 ServiceConfig
bean,它就可以对其进行后处理并注入(inject) @Autowired
目标。
@Autowired
目标在 @Configuration
bean 实例中可能为 null
的唯一原因是您试图在 之前读取它code>AutowiredAnnotationBeanPostProcessor
可以处理/注入(inject)它。
考虑循环依赖。将代码段中的 @Configuration
类与以下类的附加 @ComponentScan
@Component
class AccountRepository {
public AccountRepository(Foo foo) {}
}
@Component
class Foo {
public Foo(TransferService ts) {}
}
@Configuration
bean 被初始化。 AutowiredAnnotationBeanPostProcessor
开始处理 accountRepository
字段。它寻找一个 AccountRepository
bean 并尝试初始化它。它需要一个 Foo
bean 来实例化它(用于构造函数注入(inject))。它寻找一个 Foo
bean 并尝试初始化它。它需要一个 TransferService
bean 来实例化它(用于构造函数注入(inject))。它查找 TransferService
bean 并找到 @Bean
工厂方法。它调用它。 accountRepository
尚未初始化,因此仍为 null
。您可以通过在 @Bean
方法中放置一个断点并浏览堆栈跟踪来验证这一点。
您是否按照上面引述的建议使用了参数注入(inject)
Whenever possible, resort to parameter-based injection as in the example above.
Spring 会崩溃并警告你
Caused by:
org.springframework.beans.factory.BeanCurrentlyInCreationException
: Error creating bean with name'accountRepository'
: Requested bean is currently in creation: Is there an unresolvable circular reference?
That's the workaround I ended up doing
我目前无法解释这一点。
关于java - 为什么@Configuration 类中的@Autowired 字段为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41111466/
这更像是一个最佳实践类型的问题。 我听过很多次: a) 在 Spring 中 Autowiring 时,最佳做法是 Autowiring 接口(interface)“而不是”实现。 和.. b) 我还
我正在查看工作区中的一些旧示例。我看不出怎么样由于没有 @Autowired, Autowiring 完成。 Spring boot + facebook 默认配置。 @Controller @Req
事实似乎并非如此。我曾经认为 XML 配置是为了覆盖注释。但是当我在XML配置中设置autowire =“no”时,bean的@Autowired注释属性仍然有效。我不再确定 XML autowire
为什么需要 Autowiring ? Autowiring 概念的解释是什么?@autowired Spring Framework 中的注释. 最佳答案 不需要 Autowiring ,只是方便。
来自this Spring documentation我知道当我使用@Bean时,默认值已经相当于: @Bean(autowire = Autowire.NO) (Default) No autowi
遇到了一个奇怪的要求。我需要将唯一的错误 ID 附加到 log4j 消息并将该消息 ID 返回给接口(interface)。所以,我虽然让我们创建一个 spring 服务,就像这样 public cl
这个问题已经有答案了: @Autowire failing with @Repository (3 个回答) 已关闭 4 年前。 我有一个类“ReportEverythingForm”,它拒绝通过自动
我是 Spring 的新手。我正面临 Spring-Boot 的问题。我正在尝试将一个字段从外部配置文件 Autowiring 到一个 Autowiring 的 bean 中。我有以下类(class)
我有一个带有存储库的 Spring Boot 应用程序。 我还使用@Service并扩展其中的存储库。 当我尝试 @Autowired 我拥有的服务时: Caused by: org.springfr
我有一个接口(interface)C,想要访问另外两个类中的getClassName()。访问 a.getClassName() 时,method1() 中出现异常。 public interface
我遇到了一个奇怪的问题,其中注入(inject)了 @Autowire 的 Component 在一个类中可用,但在另一个类中不可用。 我在Account和Agreement类的属性network中使
考虑以下示例代码: public class SmallCar { private CarEngine carEngine; @Autowired public SmallCa
autowire = "no"和 autowire = "default"有什么区别?如果它们相同,那么为什么我们有这 2 个选项。 最佳答案 Beans The default is "defaul
我已将项目更改为使用注释而不是 xml 文件,但这会增加应用程序部署时间。现在我正在寻找减少它的方法。 按类型 Autowiring 和按名称 Autowiring 之间有性能差异吗? 热烈欢迎任何其
我有一个与 Web 插件一起使用的 spring boot 应用程序。 在一节课中我有: package com.test.company @Component @RestController pub
我有一个可以执行某些操作的系统。该系统使用以下方法为每个对象创建一个单独的线程: stp.scheduleWithFixedDelay((EditSite) ctx.getBean("EditSite
我正在尝试自动连接存储库,但它无法工作。我已经为此苦苦挣扎了一个星期,但我似乎无法弄清楚。有趣的是,当我注释掉人员存储库的 Autowiring 时,程序可以正常工作并正确编译,但是一旦我尝试 Aut
意味着如果具有所需类型的 bean 不超过 1 个,bean 的所有字段将自动注入(inject)依赖项。 问题是当使用注解时它是如何工作的,它到底能不能工作。 我的测试表明即使我使用 @Resou
我有一个 Autowiring 其他 bean 的组件: @Component public class MyComponent { @Autowired private Enviro
这是我的类代码,其中有 @Autowired 字段: 测试A @ContextConfiguration("classpath:spring.xml") public abstract class T
我是一名优秀的程序员,十分优秀!