Spring Bean的生命周期从哪里开始?
Bean的生命周期不是从
方法返回那一刻算起,也不是从
实例化开始——而是从Spring容器调用
真正介入时启动。这个方法内部会依次触发:实例化(通过构造器或工厂)、属性填充、Aware接口回调、初始化前置/后置处理器、
、自定义
、最后才是可用状态。
常见误区是认为
在
之前执行——其实它属于“初始化回调”的一部分,且优先级高于
和
,但晚于所有Aware接口。
关键顺序(简化):
构造函数调用(非单例Bean每次getBean都走这步)
(如果实现了)
标注的方法
指定的方法
为什么@Bean的initMethod不生效?
最常见原因是:你把
写在了
注解里,但方法签名不对或没被Spring识别。
这要求
必须有无参
方法。如果方法是
、带参数、返回值非
,或者类路径下存在多个同名方法(重载),Spring会静默忽略——不会报错,也不会执行。
另外注意:
和
不能共存于同一方法;若同时存在,
优先,
会被跳过。
验证方式:在方法里加
并启动应用,没输出就说明没触发。
立即学习
“
Java免费学习笔记(深入)
”;
Eclipse导入Android或其他的JAVA项目的正确方法 WORD版
本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
下载
DisposableBean与destroy-method为何有时不执行?
销毁逻辑只在**容器关闭时**触发,且前提是Bean由Spring完全管理生命周期。以下情况会导致
或
完全不调用:
使用
但没调用
或
Web环境用
,但没配置
或等价机制
Bean作用域为
:Spring不负责销毁,需手动清理资源
容器异常退出(如kill -9),JVM直接终止,钩子来不及运行
推荐写法:
对应类中必须有
;若方法不存在,Spring默认查找
或
——但这是隐式行为,不建议依赖。
如何在生命周期中安全获取其他Bean?
不能在构造器里直接注入依赖Bean并立即使用,尤其当目标Bean尚未初始化完成时。典型错误:
正确时机是:
在
中使用(此时所有依赖已注入,且本Bean初始化阶段刚开始)
在
中使用(同上,但需实现接口)
在
中使用(此时整个Bean已就绪)
如果必须在构造器里访问其他Bean,确保它们是
或底层无状态工具类;否则应重构为延迟加载(
或
)。
Spring Bean生命周期里最易被忽略的点:**初始化完成 ≠ 线程安全可用**。比如一个Bean在
里启了一个后台线程,该线程可能早于其他Bean初始化完毕就开始执行——这时候靠的是开发者的显式同步或启动顺序控制(
),Spring本身不保证跨Bean的初始化时序。
@BeannewAbstractAutowireCapableBeanFactory#createBean()InitializingBean#afterPropertiesSet()init-method@PostConstructafterPropertiesSet()InitializingBeaninit-methodBeanNameAware#setBeanName()BeanFactoryAware#setBeanFactory()ApplicationContextAware#setApplicationContext()PostProcessor#postProcessBeforeInitialization()@PostConstructInitializingBean#afterPropertiesSet()init-methodPostProcessor#postProcessAfterInitialization()init-method@Bean@Configuration
public class AppConfig {
@Bean(initMethod = "init")
public MyService myService() {
return new MyService();
}
}MyServicepublic void init()privatevoidinitMethod@PostConstruct@PostConstructinitMethodSystem.out.println("init triggered")destroy-methodDisposableBean#destroy()new ClassPathXmlApplicationContext(...)close()registerShutdownHook()AnnotationConfigServletWebServerApplicationContextContextLoaderListenerprototype@Configuration
public class AppConfig {
@Bean(destroyMethod = "cleanup")
public ResourceManager resourceManager() {
return new ResourceManager();
}
}public void cleanup()close()shutdown()public class A {
private final B b;
public A(B b) {
this.b = b;
b.doSomething(); // ❌ 可能NPE或逻辑错乱,B还没走完自己的init流程
}
}@PostConstructafterPropertiesSet()postProcessAfterInitialization()staticObjectProvider@Lazyinit-method@DependsOn