我正在尝试创建一些东西,这些东西将基于可配置的属性(来自application.yml
等)来自动创建bean。
由于我不能像通常在BeanFactoryPostProcessor
中那样访问属性组件,因此我很困惑如何访问它们。
如何访问BeanFactoryPostProcessor
中的应用程序属性?
答案 0 :(得分:1)
如果您想通过BeanFactoryPostProcessor
以类型安全的方式访问属性,则需要使用Environment
API将它们与Binder
绑定在一起。从本质上讲,这就是Boot本身为支持@ConfigurationProperties
bean所做的事情。
您的BeanFactoryPostProcessor
看起来像这样:
@Bean
public static BeanFactoryPostProcessor beanFactoryPostProcessor(
Environment environment) {
return new BeanFactoryPostProcessor() {
@Override
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory) throws BeansException {
BindResult<ExampleProperties> result = Binder.get(environment)
.bind("com.example.prefix", ExampleProperties.class);
ExampleProperties properties = result.get();
// Use the properties to post-process the bean factory as needed
}
};
}
答案 1 :(得分:1)
我不想使用上面使用 @Bean
生产者方法的解决方案,因为它与使用 @Component
注释类并通过组件扫描拾取的推荐方法相反。幸运的是,通过实现 EnvironmentAware
很简单:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ConditionalDependencyPostProcessor implements BeanFactoryPostProcessor, EnvironmentAware {
/** Logger instance. */
private final Logger logger = LoggerFactory.getLogger(ConditionalDependencyPostProcessor.class);
/** Spring environment. */
private Environment environment;
@Override
public void setEnvironment(final Environment env) {
environment = env;
}
...
private boolean hasRequiredProfiles(final DependencyInfo info) {
final Set<String> activeProfiles = new HashSet<>(Arrays.asList(environment.getActiveProfiles()));
for (String profile : info.requiredProfiles) {
if (!activeProfiles.contains(profile)) {
return false;
}
}
return true;
}
我应该注意什么不起作用:尝试自动装配 Environment
构造函数参数。 BeanFactoryPostProcessors 需要一个无参数的构造函数,并且不支持自动装配,这本身就是由另一个后处理器 AutowiredAnnotationBeanPostProcessor 实现的功能。