2013-07-24 61 views
0

我正在使用Spring的Web應用程序。應用程序使用屬性文件進行配置。 在不同的服務器中有多個應用程序實例,每個實例都有不同的配置文件(每個實例都爲不同的客戶定製)我使用的是控制器和服務。像這樣:取決於請求對象的彈簧依賴注入

public class Controller1 { 
    @Autowired 
    Service1 service1; 

    @RequestMapping(value = "/page.htm", method = { RequestMethod.GET, RequestMethod.POST }) 
    public ModelAndView serve(HttpServletRequest request, HttpServletResponse response) { 
     service1.doSomething(); 
     return new ModelAndView("/something"); 
    } 
} 

@Service 
public class Service1 { 
    @Autowired 
    Service2 service2; 
    public void doSomething() { 
      … 
      service2.doAnotherThing(); 
      … 
     } 
} 

@Service 
public class Service2 { 
    @Value("${propertyValue}") 
    private String propertyValue; 

    //doAnotherThing() will use propertyValue 
    public void doAnotherThing() { 
     … 
     //Do something with propertyValue 
     … 
     } 
} 

現在我有一個新的要求。每個客戶不會有多個實例,但只有一個實例可爲所有客戶提供多個域。 應用程序必須根據控制器中請求對象的主機名決定配置。因此,如果客戶將瀏覽器指向www.app1.com,我必須使用配置文件1,但如果客戶使用www.app2.com,則必須使用配置2等。

我將配置文件移動到數據庫,但後來我意識到我不知道如何進行依賴注入。服務是鏈接的,service1使用service2,service2是必須使用取決於配置的值的人。服務2不知道請求對象。

有沒有一個乾淨的方法來解決這個問題?

感謝,

回答

1

一種方法是創建配置對象爲所有客戶作爲Spring配置一個單:

<bean id="customerAConfig"../> 
<bean id="customerBConfig"../> 
<bean id="customerCConfig"../> 

而且有一個會話範圍ConfigurationService充當哪個configuartion是活動的指針

public class ConfigurationService { 

    private CustomerConfig activeConfig; 

    // getters & setters.. 
} 

在您的spring配置中爲此服務配置一個單例代理,以便它可以注入到單例組件中。你需要在你的classpath CGLIB的春天來創建代理:

<bean class="com.mycompany.ConfigurationService" scope="session"> 
    <aop:scoped-proxy/> 
</bean> 

而且你的登錄控制器上,選擇其配置應該由虛擬主機名被使用並存儲到ConfigurationService用於以後的檢索(記住ConfigurationService是會話範圍)

public class LoginController { 

    @Autowired private CustomerConfig[] custConfigs; 
    @Autowired private ConfigurationService configService; 

    @RequestMapping(method = POST) 
    public String login(HttpServletRequest request, ..) { 
    ... 
    String host = request.getServerName(); 
    CustomerConfig activeConfig = // decide which one based on host.. 
    configService.setActiveConfig(activeConfig); 
    ... 
    } 
} 

下面是一個示例FooController的讀取客戶特定的配置

@Controller 
@RequestMapping("/foo") 
public class FooController { 

    @Autowired private ConfigurationService configService; 

    @RequestMapping(method = "GET") 
    public String get() { 
    ... 
    CustomerConfig config = configService.getActiveConfig(); 
    ... 
    } 

    ... 
} 

如果你的程序沒有像登錄頁面那樣的單個入口點,您可以將類似的邏輯編碼爲過濾器。檢查是否在會話中設置了活動配置,如果沒有根據主機名查找它,則將其設置爲