Spring Bean的获取方式

news/2025/3/19 11:11:36/

参考https://juejin.cn/post/7251780545972994108?searchId=2023091105493913AF7C1E3479BB943C80#heading-12
记录并补充

1.通过BeanFactoryAware

package com.toryxu.demo1.beans;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.stereotype.Component;@Component
public class BeanFactoryHelper implements BeanFactoryAware {private static BeanFactory beanFactory;@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {BeanFactoryHelper.beanFactory = beanFactory;}public static Object getBean(String beanName) {return beanFactory.getBean(beanName);}public static <T> T getBean(Class<T> requireType) {return beanFactory.getBean(requireType);}
}

2.获取启动时的ApplicationContext

存到静态对象里

@SpringBootApplication
public class Demo1Application {public static void main(String[] args) {var applicationContext = SpringApplication.run(Demo1Application.class, args);}}

3.继承ApplicationObjectSupport

需要声明为Bean

@Component
public class SpringContextUtil extends ApplicationObjectSupport {public <T> T getBean(Class<T> requireType) {ApplicationContext ac = getApplicationContext();if (ac == null) return null;return ac.getBean(requireType);}
}

ApplicationObjectSupport继承了ApplicationContextAware,在容器创建完成后会执行setApplicationContext方法

4.继承WebApplicationObjectSupport

@Component
public class WebSpringContextUtil extends WebApplicationObjectSupport {public <T> T getBean(Class<T> requireType) {var applicationContext = getApplicationContext();if (applicationContext == null) return null;return applicationContext.getBean(requireType);}
}

WebApplicationObjectSupport是extends ApplicationObjectSupport的

5.WebApplicationContextUtils

public class SpringContextUtil2 {public <T> T getBean(ServletContext sc, Class<T> requireType) {var webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(sc);return webApplicationContext.getBean(requireType);}
}

Web项目中通过ServletContext获取Bean。

   @RequestMapping("/test/{beanName}")public void test(HttpServletRequest request,@PathVariable("beanName") String beanName){System.out.println("test");var servletContext = request.getServletContext();var webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);var bean = webApplicationContext.getBean(beanName);}

6.通过ApplicationContextAware

public class SpringContextUtil3 implements ApplicationContextAware {

    private static ApplicationContext ac;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {ac = applicationContext;}
}

7.通过ContextLoader(废弃)

public <T> T getBean(Class<T> requireType) {var currentWebApplicationContext = ContextLoader.getCurrentWebApplicationContext();return currentWebApplicationContext.getBean(requireType);
}

ContextLoader中维护了一个Context类加载器和ac的映射关系
通过当前线程获取当前类加载器,从而获得ac。

/*** Obtain the Spring root web application context for the current thread* (i.e. for the current thread's context ClassLoader, which needs to be* the web application's ClassLoader).* @return the current root web application context, or {@code null}* if none found* @see org.springframework.web.context.support.SpringBeanAutowiringSupport*/@Nullablepublic static WebApplicationContext getCurrentWebApplicationContext() {ClassLoader ccl = Thread.currentThread().getContextClassLoader();if (ccl != null) {WebApplicationContext ccpt = currentContextPerThread.get(ccl);if (ccpt != null) {return ccpt;}}retu
 @CallerSensitivepublic ClassLoader getContextClassLoader() {ClassLoader cl = this.contextClassLoader;if (cl == null) {return null;} else {if (!isSupportedClassLoader(cl)) {cl = ClassLoader.getSystemClassLoader();}SecurityManager sm = System.getSecurityManager();if (sm != null) {Class<?> caller = Reflection.getCallerClass();ClassLoader.checkClassLoaderPermission(cl, caller);}return cl;}}

ServletContextListener:
通过ServletContextListener,监听到contextInitialized事件,执行initWebApplicationContext方法,创建context并建立映射关系

一般都是在SSM项目中,需要配置web.xml才行,springboot项目中不会执行SpringBootServletInitializer .startUp方法

现在的项目中是获取不到该值的。

8.通过BeanFactoryPostprocessor

public class SpringContextUtil4 implements BeanFactoryPostProcessor {private static ConfigurableListableBeanFactory beanFactory;@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}public <T> T getBean(Class<T> requireType) {return beanFactory.getBean(requireType);}}

9.直接获取容器中的ApplicationContext

    @Autowiredprivate ApplicationContext applicationContext;@RequestMapping("/test/{beanName}")public void test(HttpServletRequest request,@PathVariable("beanName") String beanName){System.out.println("test");applicationContext.getBean(beanName);
}

总结:

从容器中获取Bean的方式主要在启动时将ApplicationContext(BeanFactory的子接口)或者BeanFactory放进static变量中
其中又主要通过:
1.BeanFactoryAware
2.ApplicationContextAware(建议)
3.BeanFactoryPostProcessor
4.构造方法或者autowired/resource注解获取

1、3都是获取BeanFactory不建议
默认就直接从容器中拿applicationContext就可以了
当我们的对象不在容器中时,要获取applicationContext的话,就只能先搞一个Utils将applicationContext拿到并通过静态资源的形式放进去,这个时候就需要用到ApplicationContextAware。


http://www.ppmy.cn/news/1107280.html

相关文章

青春不一young——建行江门市分行“爱·”时光音乐会圆满成功!

为进一步贯彻落实党的二十大精神&#xff0c;传承和发扬“五四”精神&#xff0c;落实市分行党委关心关爱青年员工工作要求及省分行团委“五四”活动要求&#xff0c;引领青年思想&#xff0c;凝聚青春力量&#xff0c;激发奋斗精神&#xff0c;为市分行高质量发展贡献青春力量…

从构建者到设计者的低代码之路

低代码开发技术&#xff0c;是指无需编码或通过少量代码就可以快速生成应用程序的工具&#xff0c;一方面可降低企业应用开发人力成本和对专业软件人才的需求&#xff0c;另一方面可将原有数月甚至数年的开发时间成倍缩短&#xff0c;帮助企业实现降本增效、灵活迭代。那么&…

干货分享 | 一文了解TSMaster中Seedkey的两种处理方法

在UDS诊断过程中&#xff0c;会涉及到安全访问的问题&#xff0c;也就是常说的Seed&Key。TSMaster中提供了两种 Seed&Key 的处理方法&#xff1a;第一种是直接加载DLL文件&#xff1b;第二种是直接在TSMaster的编译器中直接添加安全算法。 一、加载外部 Seed&Key D…

华为再放大招“重新造车”,这次能否延续手机辉煌?

最近&#xff0c;华为余承东出席AITO问界新M7新车发布仪式。他声称继续在该系列车型投超五亿资金&#xff0c;扬言打造智能座舱天花板。 继华为手机成为世界新闻后&#xff0c;近期这家公司连放大招。理性的看&#xff0c;华为造车能否延续手机辉煌? 01 汽车是大招的集合体 …

易基因: WGBS等揭示DNA甲基化调控林地草莓植株高度和果实大小的分子机制|植物发育

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 DNA甲基化影响基因组稳定性、转座子沉默和基因表达&#xff1b;它主要发生在对称CG和CHG以及不对称CHH (H A, C或T)中的胞嘧啶上。RNA介导的DNA甲基化(RNA-directed DNA methylation&am…

Linux——环境变量

✅<1>主页&#xff1a;&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;Linux——环境变量 ☂️<3>开发环境&#xff1a;Centos7 &#x1f4ac;<4>前言&#xff1a;环境变量(environment variables)一般是指在操作系统中用来指定操作…

【Python】爬虫基础

爬虫是一种模拟浏览器实现&#xff0c;用以抓取网站信息的程序或者脚本。常见的爬虫有三大类&#xff1a; 通用式爬虫&#xff1a;通用式爬虫用以爬取一整个网页的信息。 聚焦式爬虫&#xff1a;聚焦式爬虫可以在通用式爬虫爬取到的一整个网页的信息基础上只选取一部分所需的…

【C++】构造函数意义 ( 构造函数显式调用与隐式调用 | 构造函数替代方案 - 初始化函数 | 初始化函数缺陷 | 默认构造函数 )

文章目录 一、构造函数意义1、类的构造函数2、构造函数显式调用与隐式调用3、构造函数替代方案 - 初始化函数4、初始化函数缺陷5、默认构造函数6、代码示例 - 初始化函数无法及时调用 一、构造函数意义 1、类的构造函数 C 提供的 构造函数 和 析构函数 作为 类实例对象的 初始化…