如何使用以工厂/策略模式创建的对象(在运行时创建)使用@Autowired服务?

问题描述 投票:0回答:2

考虑接口Action和2个实现类:StupidActionSmartAction

[SmartAction需要使用其他服务,但是由于在运行时创建了Action,因此@Autowired注释不起作用(该服务为null)。

Spring一起使用策略模式是否错误?有解决这个问题的好方法吗?

我也可以将“ StupidAction”设置为服务,而不是实例化它。我还可以将自动装配的服务传递给方法参数中的“ doSomething”。但是这两种解决方案都非常肮脏。

一些代码示例:

public interface Action {
    void doSomething();
}

public class StupidAction implements Action{

    @Autowired
    private MyService myService;  // THIS IS NULL. because StupidAction is instanciated at runtime.

    public void doSomething(){
        myService.changeSomething()
    }
}

//Pseudo code
@RestController
@RequestMapping(path = "/")
public class WorkflowController {

    @GetMapping("")
    ResponseEntity someAPI() {  
        Action action = new SmartAction(); //create on runtime
        action.doSomething(); //NullPointerExc
    }
}
java spring nullpointerexception strategy-pattern
2个回答
0
投票

您可以使用BeanFactory通过名称从上下文中动态获取Bean:

@Service
public class Service {

  @Autowired BeanFactory beanFactory;

  public void foo(){
    DynamicBean bean = beanFactory.getBean("bean_name", DynamicBean.class)
  }
}

-2
投票

您可以从作为ApplicationContextAware的Util服务获取Bean。

@Service
public class BeanUtility implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }
    public static <T extends Object> T getMyBean(Class<T> beanClass) {
        return context.getBean(beanClass);
    }
}

控制器实现如下:

@RestController
@RequestMapping(path = "/")
public class WorkflowController {

    @Autowired
    BeanUtility beanUtility;

    @GetMapping("action")
    ResponseEntity someAPI() {
        MyService myService = BeanUtility.getMyBean(MyService.class); // use the util class to get a Bean of your choice
        Action action = new SmartAction(myService); // Constructor based DI
        return new ResponseEntity<String>(action.doSomething(), HttpStatus.CREATED);
    }
}

接着是如下的SmartAction类的实现:

@Service
public class SmartAction implements Action{

    private MyService myService;

    public SmartAction(MyService myService){
        this.myService = myService;
    }

    @Override
    public String doSomething() {
        return "Smart action : " + myService.changeSomething();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.