【SpringBoot】静态方法获取 bean的
背景:
使用 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 就是一个很不错的方法了。
以上,做下笔记。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南