spring学习总结006 --- Bean级生命周期接口
spring提供的Bean级生命周期接口有BeanNameAware、BeanFactoryAware、InitializingBean、DisposableBean;
1、BeanNameAware和BeanFactoryAware
BeanNameAware接口用于为实现了该接口的Bean设置BeanName;BeanFactoryAware接口用于为实现了该接口的bean设置BeanFactory;
这两个接口实际应用场景是什么呢?这两个接口可以通过静态方法在应用程序任意位置获取Bean
示例:
@Component public class SpringBeanUtil implements BeanNameAware, BeanFactoryAware { private static String beanName; private static BeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { SpringBeanUtil.beanFactory = beanFactory; } @Override public void setBeanName(String name) { SpringBeanUtil.beanName = name; } public static <T> T getBean(Class<T> tClass) { return Objects.nonNull(beanFactory) ? beanFactory.getBean(tClass) : null; } public static String getCurrentBeanName() { return beanName; } }
@Slf4j public class Test2 { public static void main(String[] args) { new ClassPathXmlApplicationContext("classpath:bean2.xml"); log.info("Aware bean name: {}", SpringBeanUtil.getCurrentBeanName()); log.info("SpringBeanUtil get user bean: {}", SpringBeanUtil.getBean(User.class)); } }
运行结果:
那么BeanNameAware.setBeanName方法和BeanFactoryAware.setBeanFactory方法是什么时候被调用的呢?在初始化bean时调用
AbstractApplicationContext.finishBeanFactoryInitialization ----->
DefaultListableBeanFactory.preInstantiateSingletons ------>
AbstractBeanFactory.getBean -------->
AbstractBeanFactory.doGetBean -------->
AbstractAutowireCapableBeanFactory.createBean ------->
AbstractAutowireCapableBeanFactory.doCreateBean ------->
AbstractAutowireCapableBeanFactory.initializeBean ------->
AbstractAutowireCapableBeanFactory.invokeAwareMethods ------->
2、InitializingBean和DisposableBean
实现InitializingBean接口的bean在bean初始化时执行afterPropertiesSet方法,类似于bean定义指定的init-method方法;
实现DisposableBean接口的bean在bean销毁时执行destroy方法,类似于bean定义时指定的destory-method方法;
实现接口bean的优先级高于bean定义指定的方法
示例:
@Slf4j @ToString public class InitDestroyBean implements InitializingBean, DisposableBean { private String desc; public void initMethod() { log.info("Invoke init method."); } public void destroyMethod() { log.info("Invoke destroy method."); } @Override public void afterPropertiesSet() throws Exception { log.info("Invoke afterPropertiesSet...."); this.desc = "Test initializing bean..."; } @Override public void destroy() throws Exception { log.info("Invoke destroy...."); } }
@Slf4j public class Test3 { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean3.xml"); log.warn("InitDestroyBean: {}", context.getBean(InitDestroyBean.class)); context.destroy(); } }
<bean class="com.demo.bean.InitDestroyBean" init-method="initMethod" destroy-method="destroyMethod" />
执行结果:
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步