如何在spring boot中使用应用程序上下文获取bean

时间:2015-12-04 12:47:23

标签: java spring spring-boot dependency-injection

我正在开发一个SpringBoot项目,我希望使用applicationContext来获取bean的名称。我已尝试过很多来自网络的解决方案,但无法成功。我的要求是我有一个控制器

ControllerA

在控制器内部我有一个方法getBean(String className)。我想获取已注册bean的实例。我有hibernate实体,我想通过仅在getBean方法中传递类的名称来获取bean的实例。

如果有人知道解决方案,请提供帮助。

11 个答案:

答案 0 :(得分:48)

您可以将ApplicationContext自动装配为字段

@Autowired
private ApplicationContext context;

或方法

@Autowired
public void context(ApplicationContext context) { this.context = context; }

最后使用

context.getBean(SomeClass.class)

答案 1 :(得分:31)

您可以使用 ApplicationContextAware

  

<强>了ApplicationContextAware

     

由希望得到通知的任何对象实现的接口   它运行的ApplicationContext的实现。实现此接口   例如,当一个对象需要访问一组时,这是有意义的   合作豆。

有一些方法可以获取对应用程序上下文的引用。您可以实现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正在设置当前 applicationcontext。

Spring source code的代码段:

private void invokeAwareInterfaces(Object bean) {
        .....
        .....
 if (bean instanceof ApplicationContextAware) {                
  ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
   }
}

获得对Application上下文的引用后,可以使用getBean()获取所需的bean。

答案 2 :(得分:7)

实际上你想从Spring引擎中获取对象,其中引擎已经在spring应用程序的初始化(Spring引擎初始化)中维护了所需类的对象。现在你只需得到它该对象是参考。

在服务类

@Autowired
private ApplicationContext context;

SomeClass sc = (SomeClass)context.getBean(SomeClass.class);

现在在sc的引用中你正在拥有该对象。 希望解释得很好。如有任何疑问,请告诉我。

答案 3 :(得分:1)

即使您的类不是RestController或Configuration类,即使在添加@Autowire之后,applicationContext对象也将作为null出现。尝试使用下面的方法创建新类,并且运行良好:

@Component
public class SpringContext implements ApplicationContextAware{

   private static ApplicationContext applicationContext;

   @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws 
     BeansException {
    this.applicationContext=applicationContext;
   }
 }

然后,您可以根据需要在同一类中实现getter方法,以获取Bean。喜欢:

    applicationContext.getBean(String serviceName,Interface.Class)

答案 4 :(得分:0)

如果你在Spring bean里面(在这种情况下是@Controller bean)你根本不应该使用Spring上下文实例。直接自动装配className bean。

顺便说一下,避免使用现场注射,因为它被认为是不好的做法。

答案 5 :(得分:0)

您可以使用可以提供应用程序上下文的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);
            }
        }
    }

}

答案 6 :(得分:0)

只需使用:

  

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()
}

答案 7 :(得分:0)

使用[18/Sep/2020 16:36:33] "POST /result HTTP/1.1" 200 33229 [18/Sep/2020 16:36:33] "GET /result HTTP/1.1" 200 33229 对我有用。例如:

 computed: {
                byweight: function () {
                    return this.mices.sort((a,b)=>
                      {return a.weight - b.weight });
                }
        },

答案 8 :(得分:0)

当我不确定bean名称是exec /system/bin/chargemon.stock时使用的一种API方法。我简单地将其传递给类类型,然后为我检索一个bean列表。您可以根据需要检索特定的或一般的与该类型及其子类型相关的所有bean,例如

org.springframework.beans.factory.ListableBeanFactory#getBeanNamesForType(java.lang.Class<?>)

答案 9 :(得分:0)

在配置类中调用 BEAN 注释方法的简单方法。是的,你没听错---- :P 调用 SpringBoot @Bean 注释方法从 config 返回相同的 bean。我试图从 bean 调用配置类中的 @predestroy 方法中的注销,并直接调用该方法以获得相同的结果豆 。 附注: 我在@bean 注释的方法中添加了调试,但即使我调用它也没有进入该方法。当然要怪 -----> Spring Magic <----

答案 10 :(得分:-1)

您可以使用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);
}
相关问题