公司项目引用了一个依赖jar,配置封装太封闭了,不能扩展。业务变动一次那个jar就要跟着升级一次,而且不同的项目还引用了这个jar的不同版本。领导问我能不能给它搞成可扩展的,研究了一下,实现了可扩展定制化。
原本的配置类似是这样的:
@Configuration(proxyBeanMethods = false)
public class MyConfiguration {
/**
* bean
*/
@Bean
ConfigBean configBean(Config config) {
//todo 逻辑
return new ConfigBean(config)
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
如果想根据项目的不同定制不同的ConfigBean就不太好弄了。如果能在Config对象传入ConfigBean构造之前放一个修改Config的口子就好了。这样ConfigBean的初始化生命周期也变成了
发现Config对象-> 修改Config对象-> 初始化ConfigBean
- 1.
于是我定义了一个可以修改Config对象的接口:
@FunctionalInterface
public interface ConfigCustomizer {
/**
* Customize.
*
* @param config the config
*/
void customize(Config config);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
上面整个配置就变成这样的了:
@Configuration(proxyBeanMethods = false)
public class MyConfiguration {
private List<ConfigCustomizer> configCustomizers = Collections.emptyList();
/**
* bean
*/
@Bean
ConfigBean configBean(Config config) {
// 其它公共逻辑省略
// 最后定制逻辑注入
configCustomizers
.forEach(configCustomizer -> configCustomizer.customize(config));
return new ConfigBean(config)
}
@Autowired(required = false)
void setConfigCustomizers(List<ConfigCustomizer> configCustomizers) {
this.configCustomizers = configCustomizers;
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
这样我们需要改动配置时只需要声明一个ConfigCustomizerBean即可,它会被setConfigCustomizers自动发现并执行自定义的方法。
这里会有朋友说@ConditionalOnMissingBean系列注解也能干这个事啊,没错!这样我们完全可以声明一个新的ConfigBean取而代之。但是这是两种策略:一种是修修补补就能用;一种是推到重来。我们在封装组件的时候要合理利用这些策略,该开口子的要开口子,不该开放的保持封闭,另外保证组件的扩展性也是很重要的。
本文转载自微信公众号「码农小胖哥」,可以通过以下二维码关注。转载本文请联系码农小胖哥公众号。