簡體   English   中英

使用@Autowired將依賴項注入使用“new ...”創建的對象中

[英]Injecting dependencies using @Autowired into objects created with “new …”

將bean注入helper類時遇到問題。 它的工作原理基本上是這樣的:我在頁面構造函數中創建一個對象,它可以完成一些工作,返回一些數據並在頁面上顯示這些數據。 在此輔助對象中,應通過@Autowired批注注入服務。 但是,當我使用它時,我總是得到一個空指針異常。 我也試過@SpringBean但沒有幫助。 另一方面,當我使用@SpringBean將此服務直接注入到頁面中時,它可以訪問並且工作正常。 你知道問題出在哪里嗎?

這是頁面:

public class Page extends BasePage {
    public Page() {
        HelperObject object = new HelperObject(new Application("APP_NAME"));
        String result = object.getData();

        add(new Label("label", result));
    }
}

助手對象:

public class HelperObject {
    private Application app;

    @Autowired
    private Service service;

    public HelperObject(Application app) {
        this.app = app;
    }

    public String getData() {
        // use service, manipulate data, return a string
    }
}

您可以通過調用InjectorHolder.getInjector().inject(this);使用@SpringBean將依賴項注入非Spring-non-Wicket-new-created對象@SpringBean InjectorHolder.getInjector().inject(this); 在它的構造函數中。

例如:

class MyPojo {
    @SpringBean
    MyDumbDAO dao;
    MyPojo() {
        InjectorHolder.getInjector().inject(this);
    }
    void justDoIt() {
        dao.duh(); // dao is there!
    }
}

請注意,它僅在Wicket管理的請求中調用時才有效。 如果不是(即,如果它是Quartz作業,或者在Wicket之前執行過濾器),則Application實例將不可用,並且注入器將不知道如何獲取依賴項。

另一個解決方案是使用Spring的@Configurable 它使用AspectJ來攔截帶注釋對象的創建,並注入其依賴項,即使你直接使用new (或其他一些框架,如Hibernate,在內部創建它們)實例化它們。 但這需要運行時或構建時(對我來說更好)字節碼操作,這對某些人來說可能太神奇了。

最好的做法是通過工廠bean創建對象(具有Spring注入的屬性,並讓工廠將這些屬性注入它產生的對象 - 純IoC)。

你應該真的避免在整個地方使用SpringContext (或任何其他類似的解決方案)。 以下是部分原因列表:

  1. 你的代碼與Spring方式相結合(低內聚)。
  2. 您將管道代碼與業務邏輯混合在一起。
  3. 您的代碼可讀性較差。
  4. 它的可維護性較差(例如,更改服務bean的名稱會導致代碼修改 - 這違反了SRP和OCP)。
  5. 它不太可測試(例如,你需要Spring框架來測試它)。

@SpringBean僅將依賴項注入從Wicket的Component繼承的類中。 @Autowired只將依賴注入Spring自己創建的類中。 這意味着您無法自動將依賴項注入到使用new創建的對象中。

(編輯:你也可以通過在構造函數中注入一個@SpringBean注入: InjectorHolder.getInjector().inject(this);

我的正常解決方法是使用我的應用程序類來提供幫助。 (我對你使用new Application(...)感到有些困惑。我認為這實際上不是org.apache.wicket.Application 。)例如:

public class MyApplication extends AuthenticatedWebApplication implements
    ApplicationContextAware {

    private ApplicationContext ctx;

    public void setApplicationContext(ApplicationContext applicationContext)
        throws BeansException {
        this.ctx = applicationContext;
    }

    public static MyApplication get() {
        return (MyApplication) WebApplication.get();
    }

    public static Object getSpringBean(String bean) {
        return get().ctx.getBean(bean);
    }

    public static <T> T getSpringBean(Class<T> bean) {
        return get().ctx.getBean(bean);
    }

    ....
}

在我的Spring應用程序上下文中

<!-- Set up wicket application -->
<bean id="wicketApplication" class="uk.co.humboldt.Project.MyApplication"/>

然后我的幫助對象按需查找服務:

public class HelperObject {

    private Service getService() {
        return MyApplication.getSpringBean(Service.class);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM