Spring运行时使用swap bean类

时间:2013-10-29 17:32:34

标签: java spring dependency-injection

@Component
@Qualifier("SUCCESS")
public class RandomServiceSuccess implements RandomService{
    public String doStuff(){
       return "success";
   }
}

@Component
@Qualifier("ERROR")
public class RandomServiceError implements RandomService{
    public String doStuff(){
       throw new Exception();
   }
}

调用代码

 @Controller
    public class RandomConroller {
        @Autowired 
        private RandomService service;
        public String do(){
           service.doStuff();
       }
    }

我需要做的是根据可以从http请求中的某个自定义http标头检索的值来交换它们。谢谢!

3 个答案:

答案 0 :(得分:3)

我完全同意Sotirios Delimanolis你需要注入所有实现并在运行时选择其中一个。

如果您有许多RandomService的实现,并且不希望RandomController与选择逻辑混淆,那么您可以使RandomService实现负责选择,如下所示:

public interface RandomService{
    public boolean supports(String headerValue);
    public String doStuff();
}

@Controller
public class RandomConroller {
    @Autowired List<RandomService> services;

    public String do(@RequestHeader("someHeader") String headerValue){
        for (RandomService service: services) {
            if (service.supports(headerValue)) {
                 return service.doStuff();
            }
        }
        throw new IllegalArgumentException("No suitable implementation");
    }
}

如果要为不同的实现定义优先级,可以使用Ordered并将注入的实现放入TreeSet OrderComparator

答案 1 :(得分:1)

为什么不注射两者并只使用你需要的那个?

@Inject
private RandomServiceSuccess success;

@Inject
private RandomServiceError error;

...
String value = request.getHeader("some header");
if (value == null || !value.equals("expected")) {
    error.doStuff();
} else {
    success.doStuff();
}

答案 2 :(得分:0)

在为每个实例指定不同的ID之后,应使用限定符来指定要在字段中注入的接口实例。按照@Soritios的建议,您可以执行以下操作:

@Component("SUCCESS")
public class RandomServiceSuccess implements RandomService{
    public String doStuff(){
       return "success";
   }
}

@Component("ERROR")
public class RandomServiceError implements RandomService{
    public String doStuff(){
       throw new Exception();
   }
}


@Component
public class MyBean{
    @Autowired
    @Qualifier("SUCCESS")
    private RandomService successService;

    @Autowired
    @Qualifier("ERROR")
    private RandomService successService;

    ....
    if(...)
}

...或者您可以根据您的参数从应用程序上下文中获取所需的实例:

@Controller
public class RandomConroller {
    @Autowired
    private ApplicationContext applicationContext;

    public String do(){
        String myService = decideWhatSericeToInvokeBasedOnHttpParameter();

        // at this point myService should be either "ERROR" or "SUCCESS"
        RandomService myService = applicationContext.getBean(myService);

        service.doStuff();
   }
}