[英]How to register bean dynamically in Spring Boot?
I am looking to override the SSLContext of Spring at runtime.我希望在运行时覆盖 Spring 的 SSLContext。 Hence I am trying to find ways to register the below method as a bean dynamically.因此,我试图找到将以下方法动态注册为 bean 的方法。
For Ex .对于 Ex 。 When a GetMapping endpoint is invoked, the below method should be injected as a bean into Spring IoC.当调用 GetMapping 端点时,以下方法应作为 bean 注入 Spring IoC。
public static SSLContext getSSLContext() throws Exception {
TrustManager[] trustManagers = new TrustManager[] {
new ReloadableX509TrustManager(truststoreNewPath)
};
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagers, null);
return sslContext;
}
How can I do this?我怎样才能做到这一点?
You can use the ConfigurableBeanFactory to register beans manually at runtime.您可以使用 ConfigurableBeanFactory 在运行时手动注册 bean。
@Service
public class RegisterBeansDynamically implements BeanFactoryAware {
private ConfigurableBeanFactory beanFactory;
public <T> void registerBean(String beanName, T bean) {
beanFactory.registerSingleton(beanName, bean);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = (ConfigurableBeanFactory) beanFactory;
}
}
But keep in mind: Your context must be refreshed making other beans able getting your new bean automatically injected or they have to access them dynamically from the application context.但请记住:必须刷新您的上下文,使其他 bean 能够自动注入您的新 bean,否则它们必须从应用程序上下文动态访问它们。
The BeanFactory can also be accessed directly through the application context see this answer . BeanFactory 也可以通过应用程序上下文直接访问,请参阅此答案。
you should annotate the method with @bean and class with @configuration see docs https://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch02s02.html您应该使用@bean 和类使用@configuration 注释方法,请参阅文档https://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch02s02.html
@Bean
public static SSLContext getSSLContext() throws Exception {
TrustManager[] trustManagers = new TrustManager[] {
new ReloadableX509TrustManager(truststoreNewPath)
};
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagers, null);
return sslContext;
}
Here is the demo.这是演示。
public class Demo implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
ConfigurableApplicationContext context = (ConfigurableApplicationContext)applicationContext;
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)context.getBeanFactory();
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(YourClass.class);
beanDefinitionBuilder.addPropertyValue("property1", "propertyValue");
beanDefinitionBuilder.addPropertyValue("property2", applicationContext.getBean(AnotherClass.class));
beanFactory.registerBeanDefinition("yourBeanName", beanDefinitionBuilder.getBeanDefinition());
}
}
You can move the register part to your method(start from BeanDefinitionBuilder
).您可以将注册部分移动到您的方法中(从BeanDefinitionBuilder
开始)。 I suppose this will suit your demand.我想这将满足您的需求。
Spring 5 provides Bean registration, which can be done dynamically. Spring 5 提供了可以动态完成的 Bean 注册。 Please look at documentation here and example here .请查看此处的文档和此处的示例。
Supplier<SSLContext> sslcontextSupplier = () -> getSSLContext();
context.registerBean("sslcontext",SSLContext.class,sslcontextSupplier);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.