简体   繁体   English

如何基于一些会话信息自动装配Spring bean

[英]How to autowire a spring bean based on some session info

We are working on a multilingual Spring based web application (not Spring Boot). 我们正在开发一个基于多语言Spring的Web应用程序(不是Spring Boot)。

Now we are searching for the "spring way" of doing the following. 现在,我们正在寻找执行以下操作的“春天之路”。

  1. user starts a http session with some parameters, eg a locale "de" and/or a country-code "DE" (the type of parameter isn't really important) 用户使用一些参数(例如,区域设置“ de”和/或国家/地区代码“ DE”)启动http会话(参数的类型不是很重要)
  2. user works with application 用户使用应用程序
  3. at some point the user triggers an action that somewhere deep inside needs a "localized" functionality 在某些时候,用户会触发某个动作,该动作需要深入内部某个地方才能实现“本地化”功能

Example (java pseudocode): 示例(java伪代码):

// service with functionality common for all users
@Service
class CommonService implements ICommonService
{
    // how to autowire a service based on some info in the actual HttpSession, eg. CustomServiceUK or CustomServiceDE
    @Autowired
    private ICustomService customServiceImpl;

    @Override
    public void doSomeAction(String param)
    {
        ... do some common stuff

        customResult = customServiceImpl.calculate(param);

        ... do some common stuff with custom result
    }
}

// custom service implementations
@Service("CustomServiceUK")
class CustomServiceUK implements ICustomService
{
    @Override
    public String calculate(String value)
    {
        ... execute logic on value for an "uk" user
    }
}

@Service("CustomServiceDE")
class CustomServiceDE implements ICustomService
{
    @Override
    public String calculate(String value)
    {
        ... execute logic on value for an "de" user
    }
}

How to inject a custom service based on some info in the actual HttpSession (eg CustomServiceUK or CustomServiceDE) into CommonService? 如何基于实际HttpSession中的某些信息(例如CustomServiceUK或CustomServiceDE)将定制服务注入CommonService? What are our options to solve this issue? 我们有什么解决方案? Is there something like a dynamic @Qualifier or some @Autowired Spring-Factory thing? 是否有动态@Qualifier之类的东西或某些@Autowired Spring-Factory之类的东西?

(the service implementation to use must not necessarily depend on the locale of the user but on some other piece of session/request information) (要使用的服务实现不一定一定取决于用户的语言环境,而取决于其他一些会话/请求信息)

Thanks for your answers. 感谢您的回答。

Actually we end up with the following solution which works for us. 实际上,我们最终得到了适用于我们的以下解决方案。

We created an additional implementation of ICustomService with name CustomServiceProxy. 我们创建了名为CustomServiceProxy的ICustomService的其他实现。 This service has @Primary annotation to tell Spring that this component should be injected when no explicit qualifier is supplied. 该服务具有@Primary批注,以告知Spring在未提供显式限定符时应注入此组件。 The service gets the sessionData and a Map with all Spring managed ICustomService-Components injected (Map-Key = Qualifier of the Component). 该服务获取sessionData和一个Map,其中注入了所有Spring管理的ICustomService-Component(Map-Key =组件的限定符)。 Now when some method on CustomServiceProxy gets called, it generates the Map-Key based on the actual sessionData (eg language), lookup the ICustomService in the Map and delegates the call to this specific service. 现在,当调用CustomServiceProxy上的某个方法时,它将基于实际的sessionData(例如语言)生成Map-Key,在Map中查找ICustomService并将调用委托给该特定服务。

// service with functionality common for all users
@Service
class CommonService implements ICommonService
{
    // because of @Primary an instance of CustomServiceProxy will be injected
    @Autowired
    private ICustomService customServiceImpl;

    @Override
    public void doSomeAction(String param)
    {
        ... do some common stuff

        customResult = customServiceImpl.calculate(param);

        ... do some common stuff with custom result
    }
}

// custom service implementations
@Service
@Primary
class CustomServiceProxy implements ICustomService
{
    private CustomData sessionData;
    private Map<String, ICustomService> services;

    @Autowired
    public CustomServiceProxy(CustomData sessionData, Map<String, ICustomService> services)
    {
        this.sessionData = sessionData;
        this.services = services;
    }

    @Override
    public String calculate(String value)
    {
        String serviceName = "CustomService" + sessionData.getLanguage().toUpperCase();
        ICustomService customService = services.get(serviceName);
        // handle missing service: throw exception or maybe switch to a default implementation
        Objects.requireNonNull(customService, "missing CustomService with name " + serviceName);
        return customService.calculate(value);
    }
}

@Service("CustomServiceUK")
class CustomServiceUK implements ICustomService
{
    @Override
    public String calculate(String value)
    {
        ... execute logic on value for an "uk" user
    }
}

@Service("CustomServiceDE")
class CustomServiceDE implements ICustomService
{
    @Override
    public String calculate(String value)
    {
        ... execute logic on value for an "de" user
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM