77

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)

    }

应用程序上下文.xml

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

4 回答 4

44

我有那种弹簧设置工作

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

public abstract class AbstractJobRoute extends RouteBuilder {

    @Autowired
    private GlobalSettingsService settingsService;

和几个用@Component注释定义的孩子。

于 2013-11-13T22:50:15.427 回答
38

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

请参阅以供进一步参考。

@Service并且@Component都是在 Spring 容器内创建带注释类型的 bean 的构造型。正如 Spring Docs 所说,

这个注解作为@Component 的一个特化,允许通过类路径扫描自动检测实现类。

于 2013-11-13T22:49:56.677 回答
5

如果您需要任何数据库操作,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)

}

在我看来,注入一次无处不在:)

于 2019-03-18T09:09:25.623 回答
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 是由于spring无法识别和注入其依赖项,因此其属性为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/#stash.XEJXdIR5.dpbs
  6. 在 Spring 框架中使用抽象工厂
  7. Spring自动装配不适用于抽象类
  8. 在抽象超类中注入spring依赖
  9. Spring 和 Abstract 类 - 在抽象类中注入属性
    1. 在抽象类中定义的 Spring 自动装配依赖项

请尝试使用**@Configurable(dependencyCheck = true)**和更新这篇文章,如果您遇到任何问题,我可能会尝试帮助您。

于 2018-03-09T23:26:46.167 回答