2013-08-06 2 views
5

스프링 3.2를 사용 중이며 조건에 따라 컨트롤러에서 서비스 구현을 동적으로 선택하고 싶습니다. 내 컨트롤러에 따라서 동적으로 Spring에서 서비스 구현을 선택하십시오.

public interface DevService { 
    public void add(Device device); 
} 

public class DevServiceImpl implements DevService { 
    public void add(Device device) { 
    } 
} 

public class RemoteDevServiceImpl implements DevService { 
    public void add(Device device) { 
    } 
} 

는 작업이 로컬 사이트 또는 원격 사이트에서 실행되는지 여부에 따라, 나는 로컬로 실행하거나를 보낼 중 하나가 필요합니다 다음과 같이 내가 인터페이스와 두 가지 구현을 고려 명령을 원격 사이트에 보내 실행하십시오. 기본적으로 사용자가 클릭하는 사이트에 따라 호출 할 서비스가 결정됩니다. 아무도 이것을 달성하기위한 깨끗한 방법을 제안 할 수 있습니까?

답변

8

프로덕션 환경에서 두 가지 구현이 모두 필요하다고 가정 할 경우 (그렇지 않은 경우 환경간에 콩을 명확하게 분리하기 위해 스프링 프로파일을 사용하십시오). 간단한 접근 방식은 다음과 같습니다.

interface DevService 
{ 
    void add(Device d); 
    String getName(); 
} 

@Service("devServiceLocal") 
class DevServiceLocalImpl implements DevService 
{ 
    void add(Device d) {...} 
    String getName() {return "local";} 
} 

class Controller 
{ 
    @Autowired 
    Collection<DevService> services; 

    void doSomethingWithService() 
    { 
     // TODO: Check type somehow 
     String servType = "local"; 
     for(DevService s: services) 
     { 
     if(servType.equals(s.getName()) 
     { 
      // Call service methods 
      break; 
     } 
     } 
    } 
} 
0

@Named 주석을 사용하여 이름으로 콩을 가져올 수 있습니다.

이렇게하면 기본 이름 "ServiceName"을 정의하고 설명한 조건에 따라 "Remote"또는 "Local"과 같은 접미사를 추가 할 수 있습니다. 당신은 또한 당신이 동적으로 생성 된 이름을 얻을 (DevService)BeanFactory.getBean("beanName")를 사용하여, 각각

@Named("ServiceNameRemote")@Named("ServiceNameLocal") 컨트롤러에 마지막으로

처럼 콩 (서비스 구현)를 주석해야합니다.

0

이것은 테스트되지 않았지만 Spring MVC를 사용하는 경우 컨트롤러의 헤더를 검사하여 처리 할 수 ​​있어야합니다. 하지만 코드가 어떻게 전개되고 있는지 확실하지 않습니다. 다음 방법은 몇 낙하를 가지고 있지만 작동합니다 : 당신이 당신의 헤더에 대한 목록을 삽입 할 수있는 동안

package <PACKAGE NAME>; 

import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.ModelAttribute; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 

@Controller 
@RequestMapping("/device") 
public class DeviceController { 

    @RequestMapping(headers={"Host=*.local.domain.com"}) 
    public void localDevice(
     @ModelAttribute("device") Device device 
    ) { 
     ... 
    } 

    @RequestMapping(headers={"Host!=*.local.domain.com"}) 
    public void remoteDevice(
     @ModelAttribute("device") Device device 
    ) { 
     ... 
    } 

} 

즉,은, 호스트 같은 체류에 의존, 당신은 여전히 ​​얻을 수 있는지 잘 모르겠어요 그 접근법을 사용하는 원격 호스트에 대한 제외 맵. 또한 요청이 컨트롤러 클래스로 라우팅되는 방법에 크게 중요하다고 생각합니다.

2

귀하의 질문에 "동적으로"라는 것은 시작시 선택할 수 있지만 중간 실행을 변경할 필요가 없다는 것을 의미합니다. 그렇다면 @Profile을 사용하는 것이 좋습니다. 어노테이션 기반 구성을 사용하는 나의 평소 연습은 그곳에서 사용할 수 있어야하는 특정 프로파일 @Bean을 정의하는 각 프로파일에 대해 별도의 @Configuration 클래스를 갖는 것입니다. 프로덕션 모드에서는 완전히 비활성화 된 개발 전용 @Controller 만 정의하는 것이 쉽습니다. 입력을 피하기 위해 각 프로파일에 대해 String 상수가있는 클래스를 정의하십시오.

관련 문제