背景:
使用 springboot,要从spring容器里面取到一个bean,那是很容易的。
但从静态方法里面取出一个bean,有什么方法呢?
比如:
场景1:要写一个工具类,可以提供静态方法去获取一个bean。
场景2:要写一个工具类,可以提供静态方法去获取一个bean,并且这个工具类不能给spring管理(因为常规操作,交给 spirng管理,就得对包进行扫描,一些公共模块,被多处依赖,被迫添加依赖,总感觉不太好。)
场景3:有一个类,想交给spirng进行管理,但它在公共模块,并不想加注解,也不想加包扫描,如果做这样的修改后,其它用到这个类的地方,会有些影响。该怎样做呢
场景1:要写一个工具类,可以提供静态方法去获取一个bean。
方法比较多,
比如:写一个工具类去实现ApplicationContextAware接口,并把这个工具类交给Spring管理,通过这个工具类中的静态方法从spirng容器里面,通过beanName把 bean 捞出来,
@Component
public class ApplicationContextUtil implements ApplicationContextAware {
private static ApplicationContext context;
private ApplicationContextUtil() {
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ApplicationContextUtil.setContext(applicationContext);
}
public static <T> T getBean(Class<T> t) {
return context.getBean(t);
}
public static Object getBean(String name) {
return context.getBean(name);
}
public static void setContext(ApplicationContext context) {
ApplicationContextUtil.context = context;
}
}
使用的时候
XXBean xx = ApplicationContextUtil.getBean(XXBean.class);
这种方式,需要把工具类交给Spring管理,然后,使用的地方就不受该限制了,随便哪里可以从spring容器里面找到对应的 bean。
但这个方法就是有个管理,一个工具类,它受到的限制应该越少越好,比如说,不想在工具类上面添加 @Component,并且工具类的路径,也要被扫描,这个工具类才能真正能用起来。
场景2:要写一个工具类,可以提供静态方法去获取一个bean,并且这个工具类不能给spring管理
有没有不交结spirng管理,却可以使用呢?
方法有,自身不想被spring管理,却又想用 spring 容器里面的内容,咋整呢,
来到场景2
想从spirng容器里面拿bean, 重点就在于 spring管理的上下文,就是 context, 如果把 context 拿到后,其实也就好办了。
方法如下:
还是那个工具类,但不需要再加 @Component 这个注解,把它干掉,也不用实现 ApplicationContextAware 了,就一个很普通的工具类,然后它有一个属性 context, 对应spring 里面的 ConfigurableApplicationContext
public class ApplicationContextUtils {
public static ApplicationContext context;
public static void setContext(ApplicationContext applicationContext) {
context = applicationContext;
}
public static <T> T getBean(String beanName, Class<T> requiredType) {
try{
return context.getBean(beanName, requiredType);
} catch (Exception e){
log.error("get bean error, {}", e.getMessage());
return null;
}
}
}
然后在启动方法里面,把 ConfigurableApplicationContext set 进去,比如
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
ApplicationContextUtils.setContext(context);
}
这样,拿到了 context, 也就可以为所欲为了。
嗯。获取 spirng 容器 bean 的大概如此。。。
场景3:有一个类,想交给spirng进行管理,但它在公共模块,并不想加注解,也不想加包扫描
还有一个问题三,
现在有一个普通的类,想把它加到 spirng 管理, 但又不能对这个类进行任何的修改,就好像是一个第三方的类,想把它加到 Spring 管理。
比如:
import org.springframework.web.client.RestTemplate;
public class DemoApplication {
// ......
// 这个 RestTemplate 就是一个普通的类,想把它将给 spring 管理,就可以用这种方法
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
再比如
@Configuration
public class DemoDataAutoConfig {
@Value("${data.enabled: false}")
private boolean enabled;
@Bean
public DataConfig dataConfig() {
return new DataConfig(enabled);
}
}
// DataConfig 就是一个极度普通的类
public class DataConfig {
private boolean enabled;
// Getter 和 Setter
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public DataConfig(boolean enabled) {
this.enabled = enabled;
}
}
DataConfig 是一个普通类,不能/不想对它做改造,不想去扫描这个包路径,那 @Bean 就是一个很不错的方法了。
以上,做下笔记。
标签:静态方法,SpringBoot,spring,enabled,bean,context,工具,public From: https://www.cnblogs.com/aaacarrot/p/18408919