Spring Boot中的继承:@Autowired字段为空(需要在非Spring托管类中自动装配 - 多个实例)

时间:2017-07-13 07:01:41

标签: java spring autowired

我已经使用基于注释的配置运行Spring Boot,但我对于Spring来说是一个很新的东西。我真的找不到其他地方的问题解决方案。 我使用以下继承结构获得了Task对象:

  • ParentTask
    • SystemTask
    • UserTask
      • SpecificUserTask

现在我想将一些Repository自动装配到SystemTask。此外,我想将存储库和一些服务自动装配到UserTask(及其所有子节点)。

我该怎么做?使用以下代码,我得到一个Null Pointer Exception。

父母:

public abstract class ParentTask implements Runnable {

    // some fields

    protected ParentTask(/*fields*/) {
        //this.fields = fields;
    }

    @Override
    public abstract void run();

}

第一个孩子:

public class SystemTask extends ParentTask {

    @Autowired
    protected SomeService someService;

    protected SystemTask(/*fields*/) {
        super(fields);
        //set some other fields
    }

    @Override
    public void run() {
        someService.doSomething(); // <-- nullPointerException
    }
}

第二个孩子:

public abstract class UserTask extends ParentTask {

    @Autowired
    protected SomeService someService;
    @Autowired
    protected SomeRepository someRepository;

    protected UserTask(/*fields*/) {
        super(fields);
    }

    @Override
    public abstract void run();

}

UserTask的子级(应具有UserTask的自动连接资源)

public class SpecificUserTask extends UserTask{

    private SpecificUserTask (/*fields*/) {
        super(fields);
        //set some other fields
    }

    @Override
    public void run() {
        // do something
    }
}

My Repository是一个标准的mongo存储库imlpementation,不应该有任何错误。我的&#34; someService&#34;看起来像这样:

@Service
public class SomeService{

    // some fields

    @Autowired
    private someOtherRepository someOtherRepository;

    // some methods

    public void doSomething() {
        //...
    }
}

再次提出我的问题:

  1. 如何解决NullPointerException?
  2. 如何在UserTask中自动装配字段,以便它们在SpecificUserClass中可用?
  3. 提前谢谢大家。

    编辑:这是我在需要时创建新任务的方式:

    @Service
    public class TaskAdministration {
    
        private final TaskAdministrationRepository taskAdministrationRepository;
    
        public void commissionSystemTask(fields) {
    
            SystemTask task = new SystemTask(fields);
            taskScheduler.schedule(task, taskTrigger);
    
            // persist task to restore if necessary
            taskAdministrationRepository.save(task);
        }
    }
    

2 个答案:

答案 0 :(得分:8)

您需要在SpecificUserTask类上添加注释,例如@Component。然后,当你@Autowired SpecificUserTask春天将为它和它的超级类注入一切。

如果您没有使用spring的特定注释对Spring进行注释,那么Spring对您的SpecificUserTask对象一无所知。

通过将一个bean的实例放入另一个bean的实例中的字段来实现自动装配。这两个类都应该是bean,并且应该&#34; live&#34;在应用程序上下文中。

&#34;活&#34;在应用程序上下文中意味着上下文实例化对象,而不是你,你永远不应该new MyClass()。容器找到每个注入点并在那里设置一个实例。

因此,当您使用注释(如@Service@Component注释bean时,spring会查找并实例化。

答案 1 :(得分:0)

我解决了我的问题,实际上需要在非Spring托管类中使用自动服务的服务/存储库。 我使用了如下所述的手动依赖注入:
How do I manually autowire a bean with Spring?

这样我可以有一个类的多个实例,也可以使用spring管理的服务。这是我现在的代码:

@Service
public class TaskAdministration {

    @Autowired
    private ApplicationContext appContext;

    private final TaskAdministrationRepository taskAdministrationRepository;

    public void commissionSystemTask(fields) {

        SystemTask task = new SystemTask(trigger);
        AutowireCapableBeanFactory factory = appContext.getAutowireCapableBeanFactory();
        factory.autowireBean( task );
        factory.initializeBean( task, "SystemTask" );

        taskScheduler.schedule(task, task.trigger);

        // persist task to restore if necessary
        taskAdministrationRepository.save(task);
    }
}
相关问题