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

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

ApplicationContextAware实现类

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@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;
}
}
1
2
3
public interface ICustomService {
void doSomeThing();
}

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

Component类获取

1
2
3
4
5
6
7
8
@Slf4j
@Component(value = "a_service")
public class ACustomService implements ICustomService {
@Override
public File doSomeThing() {

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

Bean方法获取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@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映射,可以通过如下语句:

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

反射执行方法

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

1
2
3
4
5
6
//反射方式执行
Object object = ApplicationContextHelper.getBean(beanName);

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

Object o = ReflectionUtils.invokeMethod(method, object, args);

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :