我正在开发一个SpringBoot项目,希望能够通过applicationContext
获取bean的名称。我尝试了许多来自网络的解决方案,但都没有成功。我的要求是,我有一个控制器。
ControllerA
在控制器中,我有一个名为getBean(String className)
的方法。我想要获取注册bean的实例。我有Hibernate实体,并且我希望通过仅在getBean
方法中传递类名来获取bean的实例。如果有人知道解决方案,请帮忙。
我正在开发一个SpringBoot项目,希望能够通过applicationContext
获取bean的名称。我尝试了许多来自网络的解决方案,但都没有成功。我的要求是,我有一个控制器。
ControllerA
在控制器中,我有一个名为getBean(String className)
的方法。我想要获取注册bean的实例。我有Hibernate实体,并且我希望通过仅在getBean
方法中传递类名来获取bean的实例。您可以将ApplicationContext自动连接到字段。
@Autowired
private ApplicationContext context;
或一种方法
@Autowired
public void context(ApplicationContext context) { this.context = context; }
最后使用
context.getBean(SomeClass.class)
您可以使用ApplicationContextAware。
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实例化bean时,它会查找ApplicationContextAware接口的实现类,如果找到了,它将调用setApplicationContext()方法。
这样,Spring就设置了当前的应用程序上下文。
来自Spring源代码的代码片段:
private void invokeAwareInterfaces(Object bean) {
.....
.....
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
}
}
一旦您获得了应用程序上下文的引用,您可以使用getBean()获取所需的任何bean。
Spring
什么时候会调用 setApplicationContext()
方法? - Shihe Zhang实际上,您想从Spring引擎获取对象,其中引擎已经在Spring应用程序启动时(初始化Spring引擎)维护所需类的对象。现在问题是,您只需要将该对象获取到一个引用。
在服务类中
@Autowired
private ApplicationContext context;
SomeClass sc = (SomeClass)context.getBean(SomeClass.class);
现在在sc的参考中,您拥有该对象。希望解释得很清楚。如果有任何疑问,请让我知道。
我尝试过使用SpringApplication.run(Class<?> primarySource, String... arg)
,成功了。例如:
@SpringBootApplication
public class YourApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(YourApplication.class, args);
}
}
ConfigurableApplicationContext
获取任何一个被@Component
、@Repository
或@Service
注解的类的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);
}
}
@Component
public class SpringContext implements ApplicationContextAware{
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws
BeansException {
this.applicationContext=applicationContext;
}
}
然后,您可以在与所需Bean相同的类中实现一个getter方法来获取Bean。例如:
applicationContext.getBean(String serviceName,Interface.Class)
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);
}
}
}
}
@Controller
bean),就不应该使用Spring上下文实例。直接自动装配className
bean即可。当我不确定Bean的名称时,我使用的一个API方法是org.springframework.beans.factory.ListableBeanFactory#getBeanNamesForType(java.lang.Class<?>)
。我只需传入类类型,它就会为我检索出一系列的Beans。您可以根据需要指定特定或通用的方式来检索与该类型及其子类型相关联的所有Beans,例如:
@Autowired
ApplicationContext ctx
...
SomeController controller = ctx.getBeanNamesForType(SomeController)
package com.codewithsouma.firstspringproject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class TestBinarySearch {
@Autowired
private ApplicationContext applicationContext;
public void execute(){
BinarySearchImpl binarySearch = applicationContext.getBean(BinarySearchImpl.class);
int index = binarySearch.binarySearch(new int[]{10,20,30,40,50},30);
System.out.println("The number is present at index: "+index);
}
}
String[] beans = appContext.getBeanDefinitionNames(); Arrays.stream(beans).sorted().forEach(System.out::println); }; }` [如何显示Spring Boot加载的所有bean/](https://mkyong.com/spring-boot/how-to-display-all-beans-loaded-by-spring-boot/)
- Nick Dong