2012-06-30 47 views
4

我有一個項目,我有一個接口,一個實現相同接口的Abstract類,然後是一組實現此接口並擴展Abstract Class的具體類。Spring Autowiring不適用於抽象類

public interface Invoice 
{ 
    void process(); 
} 

@component 
public abstract class AbstractInvoice(){ 

    @Resource 
    protected Writer writer; 

    protected validateInvoice(){ 
    //some implementation 
    } 
} 

@Component 
public Class TypeAInvoice() extends AbstractInvoice implements Invoice{ 

    @Override 
    public void process(){ 
     //... some code 
     writer.write(); 
    } 
} 

public Interface Writer(){ 
    public void write(); 
} 

@Component 
public class CDWriter implements Writer{ 
    @Override 
    pubic void write(){ // implementation.....} 
} 

Spring文件具有包的組件掃描。

<context:annotation-config> 
<context:component-scan base-package="com.xyz" /> 

我使用一個工廠來獲得TypeAInvoice發票 現在呼籲invoice.process()的實例前往write.write()

時得到了NPE我不知道我是什麼在這裏失蹤。我試圖看到組件掃描和範圍,並且在概念上找不到任何錯誤。

+1

從'AbstractInvoice'中刪除'@ component'註釋並嘗試。 – xyz

+1

向我們展示如何獲得TypeAInvoice的實例。 –

回答

5

我使用一個工廠來獲得TypeAInvoice發票

根據您的工廠做什麼的情況下,這可能是問題。如果工廠創建新的TypeAInvoice,則彈簧接線不適用。你必須查詢Bean的Spring上下文。一種方法(雖然不是很漂亮)是使用ContextLoader

return ContextLoader.getCurrentWebApplicationContext().getBean(TypeAInvoice.class) 

我說靜態工廠及春季不要去得很好。 Spring代表反轉控制模式,而工廠代表服務定位器模式。我建議你擺脫你的工廠並自動連接你的Spring Beans。

0

一切都很好,除了使用工廠獲取TypeAInvoice的事實。如果你像TypeAInvoice typer = new TypeAInvoice()那樣創建它,那麼Spring對它一無所知,Writer不是自動裝配的,因爲你得到了NullPointerException。您應該從Spring應用程序上下文中獲取bean。

-1

在我的情況下,在Spring4應用程序中,我不得不使用經典的抽象工廠模式(爲此我從 - http://java-design-patterns.com/patterns/abstract-factory/的想法中)創建實例,每次都有一個操作要完成。代碼是設計,如:

public abstract class EO { 
    @Autowired 
    protected SmsNotificationService smsNotificationService; 
    @Autowired 
    protected SendEmailService sendEmailService; 
    ... 
    protected abstract void executeOperation(GenericMessage gMessage); 
} 

public final class OperationsExecutor { 
    public enum OperationsType { 
     ENROLL, CAMPAIGN 
    } 

    private OperationsExecutor() { 
    } 

    public static Object delegateOperation(OperationsType type, Object obj) 
    { 
     switch(type) { 
      case ENROLL: 
       if (obj == null) { 
        return new EnrollOperation(); 
       } 
       return EnrollOperation.validateRequestParams(obj); 
      case CAMPAIGN: 
       if (obj == null) { 
        return new CampaignOperation(); 
       } 
       return CampaignOperation.validateRequestParams(obj); 
      default: 
       throw new IllegalArgumentException("OperationsType not supported."); 
     } 
    } 
} 

@Configurable(dependencyCheck = true) 
public class CampaignOperation extends EO { 
    @Override 
    public void executeOperation(GenericMessage genericMessage) { 
     LOGGER.info("This is CAMPAIGN Operation: " + genericMessage); 
    } 
} 

最初在抽象類注入依賴我嘗試了所有的刻板印象註釋像@Component,@Service等,但即使Spring上下文文件已經ComponentScanning整個包,但不知何故當創建像CampaignOperation這樣的子類的實例時,超級抽象類EO的屬性爲null,因爲spring無法識別並注入其依賴關係經過大量的試驗和錯誤,我使用了這個註解,最終Spring能夠注入依賴關係,並且我能夠使用子類中的屬性,而不會使用太多的屬性混淆它們。

<context:annotation-config /> 
<context:component-scan base-package="com.xyz" /> 

我也嘗試過這些引用找到一個解決辦法:

  1. http://www.captaindebug.com/2011/06/implementing-springs-factorybean.html#.WqF5pJPwaAN
  2. http://forum.spring.io/forum/spring-projects/container/46815-problem-with-autowired-in-abstract-class
  3. https://github.com/cavallefano/Abstract-Factory-Pattern-Spring-Annotation
  4. http://www.jcombat.com/spring/factory-implementation-using-servicelocatorfactorybean-in-spring
  5. https://www.madbit.org/blog/programming/1074/1074/#sthash.XEJXdIR5.dpbs
  6. Using abstract factory with Spring framework
  7. Spring and Abstract class - injecting properties in abstract classes
  8. Inject spring dependency in abstract super class
  9. Spring autowire dependency defined in an abstract class
  10. Spring can you autowire inside an abstract class?

請嘗試使用**@Configurable(dependencyCheck = true)**和更新這個帖子,我可能會嘗試幫助你如果你遇到任何問題。

在這裏,我精確地指出,你不需要一直從spring上下文獲取bean。

+0

......我不確定你與誰溝通,但似乎你認爲你是在自己的問題....如果是這樣......寫一個新的問題,並鏈接到當前的問題,如果需要,但。 ..現在它看起來很混亂,並觸發分流審查..不必要的,這不是你想要的,因爲我可以從你付出的努力中看到。總之,創建你自己的問題,並在這裏刪除答案或修改你的答案,使它看起來不像一個問題。 – ZF007