[英]How to get bean using application context in spring boot
我正在開發一個 SpringBoot 項目,我想使用applicationContext
通過它的名字來獲取 bean。 我從網上嘗試了很多解決方案,但都沒有成功。 我的要求是我有一個控制器
ControllerA
在控制器內部,我有一個方法getBean(String className)
。 我想獲取已注冊 bean 的實例。 我有休眠實體,我想通過只在getBean
方法中傳遞類的名稱來獲取 bean 的實例。
如果有人知道解決方案,請幫助。
您可以自動裝配 ApplicationContext,或者作為一個字段
@Autowired
private ApplicationContext context;
或方法
@Autowired
public void context(ApplicationContext context) { this.context = context; }
最后使用
context.getBean(SomeClass.class)
您可以使用ApplicationContextAware 。
應用上下文感知:
由任何希望被通知它運行的 ApplicationContext 的對象實現的接口。例如,當一個對象需要訪問一組協作 bean 時,實現這個接口是有意義的。
有幾種方法可以獲取對應用程序上下文的引用。 您可以按照以下示例實現 ApplicationContextAware:
package hello;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
@Component
public class ApplicationContextProvider implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public ApplicationContext getContext() {
return applicationContext;
}
}
更新:
當Spring 實例化 beans 時,它會查找ApplicationContextAware實現,如果找到,將調用 setApplicationContext() 方法。
通過這種方式,Spring 正在設置當前的應用程序上下文。
Spring source code
代碼片段:
private void invokeAwareInterfaces(Object bean) {
.....
.....
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
}
}
一旦獲得對應用程序上下文的引用,就可以使用 getBean() 獲取所需的 bean。
實際上,您想從 Spring 引擎獲取對象,其中引擎已經在 Spring 應用程序啟動時維護了所需類的對象(Spring 引擎的初始化)。現在,您只需要獲取該對象即可一個參考。
在服務類中
@Autowired
private ApplicationContext context;
SomeClass sc = (SomeClass)context.getBean(SomeClass.class);
現在在您擁有對象的 sc 的參考中。 希望解釋得很好。 如果有任何疑問,請告訴我。
如果您在 Spring bean(在本例中為@Controller
bean)內部,則根本不應使用 Spring 上下文實例。 直接自動裝配className
bean。
順便說一句,避免使用字段注入,因為它被認為是不好的做法。
您可以使用可以提供應用程序上下文的 ApplicationContextAware 類。
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext ctx = null;
public static ApplicationContext getApplicationContext() {
return ctx;
}
@Override
public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
ApplicationContextProvider.ctx = ctx;
}
/**
* Tries to autowire the specified instance of the class if one of the specified
* beans which need to be autowired are null.
*
* @param classToAutowire the instance of the class which holds @Autowire
* annotations
* @param beansToAutowireInClass the beans which have the @Autowire annotation
* in the specified {#classToAutowire}
*/
public static void autowire(Object classToAutowire, Object... beansToAutowireInClass) {
for (Object bean : beansToAutowireInClass) {
if (bean == null) {
ctx.getAutowireCapableBeanFactory().autowireBean(classToAutowire);
}
}
}
}
即使在添加 @Autowire 之后,如果您的類不是 RestController 或 Configuration Class,applicationContext 對象也會為空。 嘗試使用下面的創建新類,它工作正常:
@Component
public class SpringContext implements ApplicationContextAware{
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws
BeansException {
this.applicationContext=applicationContext;
}
}
然后,您可以根據獲取 bean 的需要在同一個類中實現一個 getter 方法。 喜歡:
applicationContext.getBean(String serviceName,Interface.Class)
使用SpringApplication.run(Class<?> primarySource, String... arg)
對我SpringApplication.run(Class<?> primarySource, String... arg)
。 例如:
@SpringBootApplication
public class YourApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(YourApplication.class, args);
}
}
當我不確定 bean 名稱是org.springframework.beans.factory.ListableBeanFactory#getBeanNamesForType(java.lang.Class<?>)
時,我使用的一種 API 方法。 我簡單地將類類型傳遞給它,它會為我檢索一個 bean 列表。 您可以根據需要檢索與該類型及其子類型關聯的所有 bean,具體或通用,例如
@Autowired
ApplicationContext ctx
...
SomeController controller = ctx.getBeanNamesForType(SomeController)
作為替代方法,您可以使用ConfigurableApplicationContext
獲取任何用@Component
、 @Repository
或@Service
注釋的@Component
bean。
假設您想要獲取BaseComponent類的 bean:
@Service
public class BaseComponent {
public String getMessage() {
return "hello world";
}
}
現在您可以使用ConfigurableApplicationContext
來獲取 bean:
@Component
public class DemoComponent {
@Autowired
ConfigurableApplicationContext applicationContext;
public BaseComponent getBeanOfBaseComponent() {
return applicationContext.getBean(BaseComponent.class);
}
}
在配置類中調用 BEAN 注釋方法的簡單方法。 是的,你沒聽錯---- :P 調用 SpringBoot @Bean 注釋方法從 config 返回相同的 bean。我試圖從 bean 調用配置類中的 @predestroy 方法中的注銷,並直接調用該方法以獲得相同的結果豆角,扁豆 。 PS:我在@bean 注釋的方法中添加了調試,但即使我調用它也沒有進入該方法。當然要怪 -----> Spring Magic <----
您可以使用 ServiceLocatorFactoryBean。 首先你需要為你的類創建一個接口
public interface YourClassFactory {
YourClass getClassByName(String name);
}
然后你必須為 ServiceLocatorBean 創建一個配置文件
@Configuration
@Component
public class ServiceLocatorFactoryBeanConfig {
@Bean
public ServiceLocatorFactoryBean serviceLocatorBean(){
ServiceLocatorFactoryBean bean = new ServiceLocatorFactoryBean();
bean.setServiceLocatorInterface(YourClassFactory.class);
return bean;
}
}
現在你可以通過這樣的名字找到你的班級
@Autowired
private YourClassfactory factory;
YourClass getYourClass(String name){
return factory.getClassByName(name);
}
只需使用:
org.springframework.beans.factory.BeanFactory#getBean(java.lang.Class)
例子:
@Component
public class Example {
@Autowired
private ApplicationContext context;
public MyService getMyServiceBean() {
return context.getBean(MyService.class);
}
// your code uses getMyServiceBean()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.