2012-06-30 51 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