多次覆盖/包装基于java的配置中的spring bean

时间:2015-11-18 23:50:37

标签: java spring

我有一个(web)应用程序需要基于客户使用该应用程序的特殊配置和/或扩展。我将这些添加内容称为#34;插件&#34;并且在应用程序启动时通过类路径扫描自动发现它们。对于非常容易的扩展。让我们说我想要一个插件添加一个API来打印&#34; hello world&#34;当调用URL / myplugin / greet时:我只是使用相应的@Controller创建一个@RequestMapping带注释的类,将其放在myplugin.jar中,将其复制到类路径中,然后将其复制到@Configuration public class CoreConfiguration { @Bean public Set<String> availableModules() { return Collections.singleton("core"); } } 。是的。

当我想要更改某些默认值时会出现问题,特别是如果我想多次执行此操作。让我们说我的核心应用程序有这样的配置:

@Configuration
public class FirstPluginConfiguration {
    @Bean
    public Set<String> availableModules(Set<String> availableModules) {
        Set<String> extendedSet = new HashSet<>(availableModules);
        extendedSet.add("FirstPlugin");
        return extendedSet;
    }
}

现在我有两个彼此不了解的插件(但他们确实知道CoreConfig),但他们都希望将自己添加到可用模块列表中。我该怎么办?如果我只有一个想要覆盖模块列表的插件,我可以从CoreConfiguration覆盖现有的bean,但是有两个插件会成为问题。我想象的内容是这样的:

SecondPluginConfiguration

当然CrashLogger看起来几乎就是这样,除了Set不是由&#34; FirstPlugin&#34;扩展,而是由#34; SecondPlugin&#34;。我测试了它以检查会发生什么,而spring将永远不会调用First / SecondPluginConfiguration&#34; availableModules&#34;方法但它也没有显示错误。

现在当然在这种情况下,可以通过在CoreConfiguration中使用可变Set然后在其他配置中自动装配和扩展集合来轻松解决这个问题,但是例如我也希望能够将方法拦截器添加到某些bean中。例如,我可能有一个接口logCrash(Throwable t),它有一个ToFileCrashLogger方法,在CoreConfiguration中创建了一个org.springframework.aop.framework.Advised,它将堆栈跟踪写入文件,顾名思义。现在一个插件可以说他也希望得到有关崩溃的通知,例如插件想要通过电子邮件添加到某人的堆栈跟踪。就此而言,插件可以包装由CoreConfiguration配置的CrashLogger并激活BOTH。第二个插件可以再次包装包装器并执行与堆栈跟踪完全不同的操作,并且仍然可以调用其他两个CrashLogger。

后者听起来有点像AOP,如果我只是让我的所有bean都被代理(我没有测试过),我可以将它们自动装入我的插件配置,将它们转换为<button data-url="@Url.Action("MyApi", "Get")"></button> 然后添加操纵行为的建议。然而,为我的每个bean和每个bean生成代理似乎是一个巨大的过度杀伤,只是为了使该插件可以添加一个或两个建议一个或两个bean。

0 个答案:

没有答案