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);

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/11/spring-boot-obtains-bean-by-name-with-applicationcontext/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Spring Boot通过名称获取bean(applicationContext)
IOC容器有BeanFactory和ApplicationContext。通常建议使用后者,因为它包含了前者的功能。Spring的核心是ApplicationContext,它负责管理 beans 的完整生命周……
<<上一篇
下一篇>>
文章目录
关闭
目 录