java - 如何根据一些 session 信息 Autowiring Spring bean

标签 java spring autowired

我们正在开发基于 Spring 的多语言 Web 应用程序(不是 Spring Boot)。

现在我们正在寻找执行以下操作的“ Spring 方式”。

  1. 用户使用一些参数启动 http session ,例如区域设置“de”和/或国家/地区代码“DE”(参数类型并不重要)
  2. 用户使用应用程序
  3. 在某些时候,用户会触发一个操作,而该操作在内心深处需要“本地化”功能

示例(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
    }
}

如何将基于实际 HttpSession 中的某些信息(例如 CustomServiceUK 或 CustomServiceDE)的自定义服务注入(inject)到 CommonService 中? 我们有什么选择来解决这个问题?是否有类似动态 @Qualifier 或 @Autowired Spring-Factory 之类的东西?

(要使用的服务实现不一定取决于用户的区域设置,而是取决于其他一些 session /请求信息)

最佳答案

感谢您的回答。

实际上,我们最终得到了以下适合我们的解决方案。

我们创建了一个名为 CustomServiceProxy 的 ICustomService 附加实现。 该服务有 @Primary 注释来告诉 Spring 当未提供显式限定符时应注入(inject)该组件。 该服务获取 sessionData 和一个 Map,其中注入(inject)了所有 Spring 管理的 ICustomService-Components(Map-Key = 组件的限定符)。 现在,当调用 CustomServiceProxy 上的某些方法时,它会根据实际的 sessionData(例如语言)生成 Map-Key,在 Map 中查找 ICustomService 并将调用委托(delegate)给该特定服务。

// 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
    }
}

关于java - 如何根据一些 session 信息 Autowiring Spring bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56289460/

相关文章:

java - 基于命令行参数注入(inject)实现

java - 请解释一下在 Spring 中通过构造函数 Autowiring 的这种(歧义)行为

java - 与仅创建布局相比,创建自定义 ActionBar 有何优势?

java - BigDecimal 错误舍入

java - 根据用户属性自定义授权

java - Bean创建异常: Error creating bean with name '/' defined in ServletContext

java - Spring JDBC 持久化 ZonedDateTime

java - RichFaces4 不渲染组件

java - 当 SonarQube 检测到新的违规行为时,是否可以在不使用 Build Breaker 插件的情况下中断 Maven 构建?

java - 为什么@Autowired注释将同一类的每个bean关联到context.xml中?