![](/img/trans.png)
[英]Bean found in ApplicationContext, but not found when attempting to Autowire
[英]Why is an @Autowire null in a bean retrieved from ApplicationContext?
我研究了許多其他關於 Spring 自動裝配問題的 StackOverflow 帖子。 這個問題並不像“不要指望@Autowire 能在你new
的 object 上工作”那么簡單。
我有一個從 class 名稱構造對象的庫。 object 類必須擴展 class F。該庫不是用 Spring 構建的。 它接受 class 加載程序來解析 class 名稱。 它正在這樣做:
Class<?> someClass = Class.forName(className, true, classLoader);
if (F.class.isAssignableFrom(someClass)) {
Class<? extends F> fClass = (Class<? extends F>) someClass;
Constructor constructor = fClass.getConstructor(FMap.class, Object.class);
F fobject = (F) constructor.newInstance(parameterMap, applicationContext);
...
該庫允許傳入一些上下文。這里我提供了 Spring ApplicationContext。 F 的一個特定子類在其構造函數中具有如下代碼:
ApplicationContext applicationContext = (ApplicationContext)context;
X xbean = (X)applicationContext.getBean("xbean");
S sobject = new S(xbean);
Class X 定義如下:
@Component
public class X {
private final Y ybean;
@Autowired
public X(Y ybean) {
this.ybean = ybean;
}
...
Class Y 是另一個@Component。
sobject
能夠調用xbean
中的方法(xbean不為null),但是ybean
是null。 為什么?
我認為 Spring 在應用程序啟動時構建並連接了@Components。 我希望使用 ApplicationContext 中的 object 會給我一個完全構建和連接的 object。
2020 年 6 月 3日更新我按照第一個答案中的建議添加了 @PostConstruct。 這表明 object 是在應用程序生命周期的早期構建的。
我嘗試禁用spring.devtools.restart.enabled
而行為沒有改變。
我嘗試禁用spring.main.lazy-initialization
而行為沒有改變。
我從 build.gradle 中刪除了 spring-boot-devtools ,但行為沒有任何變化。 但是,構造F對象和Y bean時報告的class loader是sun.misc.Launcher$AppClassLoader
我們正在運行 org.springframework.boot:spring-boot-starter-web:2.2.6.RELEASE。
您的 class Y 只有在 Springs 的應用程序上下文中也存在時才會自動裝配。 驗證您確實配置了組件掃描,以便它拾取您的 Y 組件。 您可以通過向 Y 添加一個后構造片段來快速驗證這一點。
@PostConstruct
void init() {
logger.info("Here I am");
}
如果您的記錄器沒有打印任何內容,則絕對不會將 Y 加載到應用程序上下文中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.