[英]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.