Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot 如何选择Springbean在运行时调用_Spring Boot_Spring Security - Fatal编程技术网

Spring boot 如何选择Springbean在运行时调用

Spring boot 如何选择Springbean在运行时调用,spring-boot,spring-security,Spring Boot,Spring Security,原始标题:如何以声明方式为同一接口配置多个bean,并在运行时选择正确的bean 我最近有一个项目需要实现以下web应用程序: 当用户登录到系统时,她将指定一个范围(B2C、B2B)。当她使用应用程序时,对后端系统的一些调用必须根据当前登录的范围路由到后端系统的不同实例 webapplication由两部分组成(前面是SPA,后面是Spring Boot应用程序,后面是REST端点)和后端系统实例的集合,例如B2C存档和B2B存档 当前的实现处理REST请求并决定要调用哪个存档的登录范围。这是可

原始标题:如何以声明方式为同一接口配置多个bean,并在运行时选择正确的bean

我最近有一个项目需要实现以下web应用程序:

当用户登录到系统时,她将指定一个范围(B2C、B2B)。当她使用应用程序时,对后端系统的一些调用必须根据当前登录的范围路由到后端系统的不同实例

webapplication由两部分组成(前面是SPA,后面是Spring Boot应用程序,后面是REST端点)和后端系统实例的集合,例如B2C存档和B2B存档

当前的实现处理REST请求并决定要调用哪个存档的登录范围。这是可行的,但我想让它成为声明性的,而不是显式的编码。因此,为不同的作用域添加新的后端实例应该很容易

首先,我想定义两个bean,一个用于访问B2C归档,另一个用于访问B2B归档。两者将实现相同的接口;实际上,它们是具有不同配置值的同一类的实例

处理REST调用时,我希望spring根据当前登录的范围(B2C或B2B)选择要调用的正确bean

我对如何解决这个问题有不同的想法(作用域代理、AOP、自定义
AutowireSolver
、对象池),但目前我陷入了困境,不能说我是否走上了正确的道路

已经有人做过这样的事了吗

更新 感谢并支持使用工厂+作用域代理并将其返回到调用代码的想法

更新2 我刚刚实现了一个能够运行以下测试的spring扩展(此处为完整代码:)

内部类只是为了将测试保持在一起。当它们在单独的文件中时,它也应该工作

主要的一点是,接口由两个不同的bean实现,spring在运行时通过计算注释中的spEL表达式来决定哪个bean应该实际处理调用


@试验
public void testProxiedResourceInjectionWithField(){
caseSwitch.switchValue=“B2B”;
assertEquals(“您知道……”,client.proxiedService.doCoolStuff());
caseSwitch.switchValue=“B2C”;
assertEquals(“这就可以了…”,client.proxiedService.doCoolStuff());
}
公共静态类ProxiedServiceClient{
@自动连线
公共代理服务接口代理服务;
}
@ServiceProviderProxy
公共静态接口ProxiedServiceInterface{
公共字符串doCoolStuff();
}
@ProxiedService(表达式=“#{switch.switchValue=='B2B'}”)
公共静态类B2BServiceImpl实现ProxiedServiceInterface{
@凌驾
公共字符串doCoolStuff(){
返回“好吧,你知道……”;
}
}
@ProxiedService(表达式=“#{switch.switchValue=='B2C'}”)
公共静态类B2CServiceImpl实现ProxiedServiceInterface{
@凌驾
公共字符串doCoolStuff(){
返回“这就行了…”;
}
}
公共静态类CaseSwitch{
公共字符串switchValue=“”;
}

这可用于已设置为的,例如:


Spring将使用AOP代理在运行时创建新的bean,例如在每次请求时,使用工厂bean实现。您可以使用本地线程来传递当前上下文。

我将创建一个工厂bean,它实现选择适当bean的逻辑。然后我会把这个工厂注入控制器。嗨,谢谢你的回答。我认为这是一个很好的答案,当你喜欢访问的bean是短暂的,很容易创建。但是,如果两个归档bean是单例的(每个归档一个),因为创建它们既困难又缓慢(因为它们包含连接),这是不够的。但这是一个很好的开始:传入ThreadLocal,检查上下文并选择合适的bean。
@Bean(name = "archive")
@Scope(value= "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public ArchiveFactory archiveFactory() {
    ArchiveFactory factory = new ArchiveFactory();
    return factory;
}