Spring Boot通过名称获取bean(applicationContext)

IOC容器有BeanFactoryApplicationContext。通常建议使用后者,因为它包含了前者的功能。Spring的核心是ApplicationContext,它负责管理 beans 的完整生命周期。

ApplicationContextAware实现类

我们可以从ApplicationContext里通过bean名称获取安装的bean进行某种操作。不能直接使用ApplicationContext,而需要借助ApplicationContextAware。具体方法如下:

@Component
public class ApplicationContextHelper implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    public ApplicationContextHelper() {
    }

    /**
     * 实现ApplicationContextAware接口的回调方法,设置上下文环境
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextHelper.applicationContext = applicationContext;
    }

    /**
     * 获得spring上下文
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static Object getBean(String beanName) {
        return applicationContext != null ? applicationContext.getBean(beanName) : null;
    }

    public static ICustomService getCustomService(String beanName) {
        return applicationContext != null ? (ICustomService) applicationContext.getBean(beanName) : null;
    }
}
public interface ICustomService {
    void doSomeThing();
}

即声明一个ApplicationContextHelper组件,名字随意。它实现了ApplicationContextAware接口。并重写setApplicationContext方法。在该组件里可以通过名字获取某个bean。使用方式如下:

Component类获取

@Slf4j
@Component(value = "a_service")
public class ACustomService implements ICustomService {
    @Override
    public File doSomeThing() {

    }
}
ICustomService customService = ApplicationContextHelper.getBankService(String.format("%s_service", code).toLowerCase());
if (customService == null) {
    return new SettlementResult<>(RetCodeEnum.CUSTOM_SERVICE_INTERNAL_ERROR);
}
customService.doSomeThing();

Bean方法获取

@SpringBootApplication
public class Application {

   public static void main(String[] args) {
      System.setProperty("user.timezone", "Asia/Shanghai");
      TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
      SpringApplication.run(Application.class, args);
   }

   @Bean(name="restTemplate")
   public RestTemplate restTemplate() {
      RestTemplate restTemplate = new RestTemplate();
      restTemplate.getMessageConverters()
            .add(0, new StringHttpMessageConverter(Charsets.UTF_8));
      return restTemplate;
   }
}

public class TestTask implements Callable<String> {

    private RestTemplate restTemplate = (RestTemplate) ApplicationContextHelper.getBean( "restTemplate" );

    public doSomeThing() {
    }
}

通过Class获取

不只可以通过名称,还可以通过属于某一类Class<T>来获取类。例如,获取所有的requestHandler及其url映射,可以通过如下语句:

RequestMappingHandlerMapping handlerMapping = applicationContext.getBean(RequestMappingHandlerMapping.class);

反射执行方法

此外,还可以通过反射方式执行Bean方法:

//反射方式执行
Object object = ApplicationContextHelper.getBean(beanName);

Method method = ReflectionUtils.findMethod(object.getClass(), methodName, argsClass);

Object o = ReflectionUtils.invokeMethod(method, object, args);
上一篇 Spring Cloud手动创建Feign客户端后zipkin调用链断层问题解决
下一篇 Spring Boot配置文件yml自定义数组或List集合
目录
文章列表
1 Dagger2使用详解
Dagger2使用详解
2
响应式编程以及 Spring Boot Webflux 快速入门
响应式编程以及 Spring Boot Webflux 快速入门
3
jQuery Cannot set property 'display' of undefined
jQuery Cannot set property 'display' of undefined
4
Spring Boot Get请求参数为下划线式
Spring Boot Get请求参数为下划线式
5
Vue监听select标签change事件
Vue监听select标签change事件
最新评论
一位WordPress评论者
一位WordPress评论者
2月12日
您好,这是一条评论。若需要审核、编辑或删除评论,请访问仪表盘的评论界面。评论者头像来自 Gravatar。