Spring可以在抽象类中自动装配吗?

时间:2013-11-13 22:32:35

标签: spring abstract-class autowired

Spring无法自动装载我的对象?是否可以在抽象类中自动装配对象。假设所有模式都在application-context.xml中提供

问题:基础和扩展类(如果有的话)应该是什么注释@Service @Component?

示例

abstract class SuperMan {

    @Autowire
    private DatabaseService databaseService;

    abstract void Fly();

    protected void doSuperPowerAction(Thing thing) {

        //busy code

        databaseService.save(thing);

    }
}

扩展课程

public class SuperGirl extends SuperMan {

    @Override
    public void Fly() {
        //busy code
    }

    public doSomethingSuperGirlDoes() {

        //busy code

        doSuperPowerAction(thing)

    }

应用context.xml中

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

4 个答案:

答案 0 :(得分:35)

我有那种弹簧设置工作

具有自动装配字段的抽象类

public abstract class AbstractJobRoute extends RouteBuilder {

    @Autowired
    private GlobalSettingsService settingsService;

以及使用@Component注释定义的几个孩子。

答案 1 :(得分:27)

通常,Spring应该进行自动装配,只要您的抽象类位于为组件扫描提供的基础包中。

有关详细信息,请参阅thisthis

@Service@Component都是构造型,它们在Spring容器中创建带注释类型的bean。正如Spring Docs所述,

  

此注释用作@Component的特化,允许   要通过类路径扫描自动检测的实现类。

答案 2 :(得分:0)

在我的情况下,在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,但在某种程度上创建Subclasses的实例,如CampaignOperation,Super Abstract由于Spring无法识别并注入其依赖项,因此类EO的属性为null。经过多次试验和错误后,我使用了这个**@Configurable(dependencyCheck = true)**注释,最后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 Autowiring not working for Abstract classes
  8. Inject spring dependency in abstract super class
  9. Spring and Abstract class - injecting properties in abstract classes
    1. Spring autowire dependency defined in an abstract class
  10. 请尝试使用**@Configurable(dependencyCheck = true)**并更新此帖子,如果您遇到任何问题,我可以尝试帮助您。

答案 3 :(得分:0)

如果您需要在SuperGirl中进行任何数据库操作,您将再次将其注入SuperGirl中。

我认为主要思想是在不同的类中使用相同的对象引用。 那么呢:

//There is no annotation about Spring in the abstract part.
abstract class SuperMan {


    private final DatabaseService databaseService;

    public SuperMan(DatabaseService databaseService) {
     this.databaseService = databaseService;
    }

    abstract void Fly();

    protected void doSuperPowerAction(Thing thing) {

        //busy code

        databaseService.save(thing);

    }
}

@Component
public class SuperGirl extends SuperMan {

private final DatabaseService databaseService;

@Autowired
public SuperGirl (DatabaseService databaseService) {
     super(databaseService);
     this.databaseService = databaseService;
    }

@Override
public void Fly() {
    //busy code
}

public doSomethingSuperGirlDoes() {

    //busy code

    doSuperPowerAction(thing)

}

我认为,注入一次可以在所有地方运行:)