动态定义在Spring中自动装配哪个bean(使用限定符)

zle*_*and 8 java spring

我有一个Java EE + Spring应用程序,它支持XML配置的注释.bean总是有原型范围.

我现在的应用程序业务规则取决于用户请求所在的国家/地区.所以我会有这样的事情(请记住这个例子大大简化了):

@Component
public class TransactionService {
    @Autowired
    private TransactionRules rules;
    //..
}


@Component
@Qualifier("US")
public class TransactionRulesForUS implements TransactionRules {
     //..
}

@Component
@Qualifier("CANADA")
public class TransactionRulesForCanada implements TransactionRules {
     //..
}
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种方法,使自动布线机制根据当前请求的国家/地区自动注入正确的bean(在此示例中为美国或加拿大).该国家/地区将存储在ThreadLocal变量中,并且会在每个请求中更改.对于没有自己特定规则的所有国家,也会有全球一流的课程.

我想我必须自定义Spring决定如何创建它将注入的对象的方式.我发现这样做的唯一方法是使用FactoryBean,但这并不是我所希望的(不够通用).我希望做这样的事情:

  1. 在Spring实例化一个对象之前,必须调用我自己的自定义代码.
  2. 如果我检测到所请求的接口有多个实现,我会在我的ThreadLocal变量中查找正确的国家/地区,并动态地将相应的限定符添加到自动连线请求中.
  3. 在那之后,Spring会尽其所能.如果添加了限定符,则必须考虑这一点; 如果没有,流程将照常进行.

我在正确的道路上吗?对我有什么想法吗?

谢谢.

dig*_*oel 0

您可以提供一个 Configuration 类,它将根据 ThreadLocal 值返回正确的 bean。假设您使用的是 Spring 3。我做了一些测试以确保在每个请求上调用提供者方法。这就是我所做的。

@Configuration
public class ApplicationConfiguration
{
    private static int counter = 0;

    @Bean( name="joel" )
    @Scope( value="request", proxyMode=ScopedProxyMode.TARGET_CLASS)
    List<String> getJoel()
    {
        return Arrays.asList( new String[] { "Joel " + counter++ } );
    }
}
Run Code Online (Sandbox Code Playgroud)

并引用我的控制器中的值,如下所示。

@Resource( name="joel" )
private List<String> joel;
Run Code Online (Sandbox Code Playgroud)

在提供程序的实现中,您可以检查 ThreadLocal 的区域设置并返回正确的 TransactionRules 对象或类似的东西。ScopedProxy 的东西是因为我注入到一个 Controller 中,它是 Singleton 范围的,而值是 request 范围的。