我正在使用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不知道请求对象。
有没有一种干净的方法来解决这个问题?
谢谢,
答案 0 :(得分:1)
一种方法是在spring config上为所有客户创建配置对象:
<bean id="customerAConfig"../>
<bean id="customerBConfig"../>
<bean id="customerCConfig"../>
并且有一个会话范围的ConfigurationService,它充当指向配置活动的指针
public class ConfigurationService {
private CustomerConfig activeConfig;
// getters & setters..
}
在spring配置中为此服务配置单例代理,以便将其注入单例组件。您需要在Spring的类路径中使用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();
...
}
...
}
如果您的程序没有像登录页面那样的单个入口点,则可以将类似的逻辑编码为过滤器。检查是否在会话中设置了活动配置,如果没有根据主机名
查找