Spring InitializingBean源码详解(详细注释版)
1. InitializingBean接口源码
/*
* InitializingBean接口是Spring框架中用于bean初始化的回调接口
* 当Bean实现了这个接口,Spring容器会在设置完所有属性后调用afterPropertiesSet()方法
* 这为Bean提供了在完全初始化后执行自定义初始化逻辑的机会
*
* 注意:官方推荐使用@PostConstruct注解或init-method配置而不是实现此接口
* 因为实现接口会将代码与Spring框架耦合
*/
package org.springframework.beans.factory;
/**
* 在BeanFactory设置完Bean的所有属性后,需要执行初始化的Bean实现的接口
*
* 这个接口的主要用途:
* 1. 允许Bean在所有必需属性设置完毕后执行初始化逻辑
* 2. 提供一种标准的方式来执行初始化操作
* 3. 确保在Bean被使用前完成必要的初始化工作
*
* 实现此接口的典型场景:
* - 检查必需属性是否已设置
* - 执行初始化操作(如建立数据库连接)
* - 启动后台线程
* - 加载配置文件等
*
* 注意事项:
* - afterPropertiesSet()方法在所有属性设置完成后调用
* - 如果初始化失败,应该抛出Exception异常
* - 避免在此方法中执行耗时操作,影响应用启动速度
*/
public interface InitializingBean {
/**
* 在BeanFactory设置完Bean的所有属性后调用
*
* 这个方法在以下情况下被调用:
* 1. 所有属性值都已通过BeanFactory注入完成
* 2. Bean实现了Aware接口的相关方法已被调用
* 3. BeanPostProcessor的postProcessBeforeInitialization方法已被调用
*
* 执行时机:
* Bean实例化 -> 属性注入 -> Aware接口方法 -> BeanPostProcessor前置处理 -> afterPropertiesSet() ->
* BeanPostProcessor后置处理 -> 初始化完成
*
* @throws Exception 如果初始化过程中发生错误
*
* 使用建议:
* - 在此方法中检查必需属性是否已正确设置
* - 执行必要的初始化操作
* - 如果初始化失败,抛出异常阻止Bean的使用
* - 避免在此方法中执行复杂的业务逻辑
*/
void afterPropertiesSet() throws Exception;
}
2. AbstractAutowireCapableBeanFactory中InitializingBean的处理
/*
* AbstractAutowireCapableBeanFactory是Spring容器的核心实现类
* 负责Bean的创建、属性注入和初始化等完整生命周期管理
*/
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/**
* 初始化Bean的核心方法
* 处理Bean的完整初始化过程,包括InitializingBean回调
*
* @param beanName Bean名称
* @param bean Bean实例
* @param mbd 合并的Bean定义
* @return 初始化完成的Bean实例
* @throws BeansException 如果初始化过程中发生错误
*/
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
// 调用Aware接口相关方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 应用BeanPostProcessor的前置处理方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用初始化方法(包括InitializingBean的afterPropertiesSet)
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 应用BeanPostProcessor的后置处理方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
/**
* 调用Aware接口相关方法
* 在InitializingBean回调之前执行
*
* @param beanName Bean名称
* @param bean Bean实例
*/
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
/**
* 调用初始化方法
* 这是处理InitializingBean的核心方法
*
* @param beanName Bean名称
* @param bean Bean实例
* @param mbd 合并的Bean定义
* @throws Throwable 如果初始化过程中发生错误
*/
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
// 检查Bean是否实现了InitializingBean接口
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
// 调用InitializingBean的afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
return null;
}
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 直接调用afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null) {
// 检查是否有自定义的初始化方法
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 调用自定义初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
/**
* 调用自定义初始化方法
*
* @param beanName Bean名称
* @param bean Bean实例
* @param mbd 合并的Bean定义
* @throws Throwable 如果调用过程中发生错误
*/
protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
String initMethodName = mbd.getInitMethodName();
final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
if (initMethod == null) {
if (mbd.isEnforceInitMethod()) {
throw new BeanDefinitionValidationException("Couldn't find an init method named '" +
initMethodName + "' on bean with name '" + beanName + "'");
}
else {
if (logger.isDebugEnabled()) {
logger.debug("No default init method named '" + initMethodName +
"' found on bean with name '" + beanName + "'");
}
// Ignore non-existent default lifecycle methods.
return;
}
}
if (logger.isDebugEnabled()) {
logger.debug("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
ReflectionUtils.makeAccessible(initMethod);
return null;
}
});
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
initMethod.invoke(bean);
return null;
}
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
try {
// 通过反射调用自定义初始化方法
ReflectionUtils.makeAccessible(initMethod);
initMethod.invoke(bean);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
}
3. Bean生命周期中的InitializingBean调用时机
/*
* Bean生命周期完整流程
*/
public class BeanLifecycleDemo {
/**
* 完整的Bean生命周期示例
*/
public static class LifecycleBean implements
BeanNameAware,
BeanClassLoaderAware,
BeanFactoryAware,
InitializingBean,
DisposableBean {
private String name;
private String beanName;
private ClassLoader classLoader;
private BeanFactory beanFactory;
// 构造方法
public LifecycleBean() {
System.out.println("1. 构造方法被调用");
}
// Setter方法
public void setName(String name) {
System.out.println("2. Setter方法被调用: " + name);
this.name = name;
}
// BeanNameAware接口方法
@Override
public void setBeanName(String name) {
System.out.println("3. BeanNameAware.setBeanName()被调用: " + name);
this.beanName = name;
}
// BeanClassLoaderAware接口方法
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("4. BeanClassLoaderAware.setBeanClassLoader()被调用");
this.classLoader = classLoader;
}
// BeanFactoryAware接口方法
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("5. BeanFactoryAware.setBeanFactory()被调用");
this.beanFactory = beanFactory;
}
// InitializingBean接口方法
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("7. InitializingBean.afterPropertiesSet()被调用");
// 执行初始化检查
if (name == null) {
throw new IllegalArgumentException("name属性必须设置");
}
// 执行初始化逻辑
System.out.println("执行初始化逻辑...");
}
// 自定义初始化方法
public void init() {
System.out.println("8. 自定义init()方法被调用");
}
// DisposableBean接口方法
@Override
public void destroy() throws Exception {
System.out.println("销毁Bean...");
}
// Getter方法
public String getName() {
return name;
}
public String getBeanName() {
return beanName;
}
}
/**
* BeanPostProcessor示例
*/
public static class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("6. BeanPostProcessor.postProcessBeforeInitialization()被调用: " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("9. BeanPostProcessor.postProcessAfterInitialization()被调用: " + beanName);
return bean;
}
}
}
4. InitializingBean与@PostConstruct的区别
/*
* InitializingBean与@PostConstruct的对比
*/
public class InitializationComparison {
/**
* 使用InitializingBean的方式
*/
@Component
public static class InitializingBeanExample implements InitializingBean {
@Autowired
private SomeService someService;
private String config;
@Override
public void afterPropertiesSet() throws Exception {
// 初始化逻辑
if (someService == null) {
throw new IllegalStateException("SomeService未注入");
}
config = someService.loadConfig();
System.out.println("InitializingBean初始化完成");
}
}
/**
* 使用@PostConstruct的方式
*/
@Component
public static class PostConstructExample {
@Autowired
private SomeService someService;
private String config;
@PostConstruct
public void init() {
// 初始化逻辑
if (someService == null) {
throw new IllegalStateException("SomeService未注入");
}
config = someService.loadConfig();
System.out.println("@PostConstruct初始化完成");
}
}
/**
* 使用init-method的方式
*/
@Component
public static class InitMethodExample {
@Autowired
private SomeService someService;
private String config;
public void customInit() {
// 初始化逻辑
if (someService == null) {
throw new IllegalStateException("SomeService未注入");
}
config = someService.loadConfig();
System.out.println("init-method初始化完成");
}
}
/**
* 三种方式混合使用
*/
@Component
public static class MixedInitializationExample
implements InitializingBean, DisposableBean {
@PostConstruct
public void postConstructInit() {
System.out.println("@PostConstruct方法执行");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean.afterPropertiesSet()执行");
}
public void customInit() {
System.out.println("自定义init方法执行");
}
@PreDestroy
public void preDestroy() {
System.out.println("@PreDestroy方法执行");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean.destroy()执行");
}
public void customDestroy() {
System.out.println("自定义destroy方法执行");
}
}
}
5. 实际应用场景
/*
* InitializingBean的实际应用场景
*/
public class RealWorldExamples {
/**
* 数据库连接池初始化
*/
@Component
public static class DatabaseConnectionPool implements InitializingBean {
@Value("${db.pool.size:10}")
private int poolSize;
@Value("${db.url}")
private String dbUrl;
private Connection[] connections;
private boolean initialized = false;
@Override
public void afterPropertiesSet() throws Exception {
// 验证必需属性
if (dbUrl == null || dbUrl.trim().isEmpty()) {
throw new IllegalArgumentException("数据库URL不能为空");
}
if (poolSize <= 0) {
throw new IllegalArgumentException("连接池大小必须大于0");
}
// 初始化连接池
connections = new Connection[poolSize];
for (int i = 0; i < poolSize; i++) {
// 创建数据库连接
connections[i] = DriverManager.getConnection(dbUrl);
}
initialized = true;
System.out.println("数据库连接池初始化完成,大小: " + poolSize);
}
public Connection getConnection() {
if (!initialized) {
throw new IllegalStateException("连接池未初始化");
}
// 简化的连接获取逻辑
for (Connection conn : connections) {
try {
if (conn != null && !conn.isClosed()) {
return conn;
}
} catch (SQLException e) {
// 处理异常
}
}
return null;
}
}
/**
* 缓存初始化
*/
@Component
public static class CacheManager implements InitializingBean {
@Value("${cache.size:1000}")
private int cacheSize;
@Autowired(required = false)
private List<CacheLoader> cacheLoaders;
private Map<String, Object> cache;
@Override
public void afterPropertiesSet() throws Exception {
// 初始化缓存
cache = new ConcurrentHashMap<>(cacheSize);
// 预加载缓存数据
if (cacheLoaders != null) {
for (CacheLoader loader : cacheLoaders) {
Map<String, Object> data = loader.loadCacheData();
if (data != null) {
cache.putAll(data);
}
}
}
System.out.println("缓存管理器初始化完成,缓存项数量: " + cache.size());
}
public Object get(String key) {
return cache.get(key);
}
public void put(String key, Object value) {
cache.put(key, value);
}
}
/**
* 定时任务调度器
*/
@Component
public static class TaskScheduler implements InitializingBean, DisposableBean {
@Autowired
private List<ScheduledTask> scheduledTasks;
private ScheduledExecutorService executorService;
private boolean started = false;
@Override
public void afterPropertiesSet() throws Exception {
if (scheduledTasks != null && !scheduledTasks.isEmpty()) {
// 初始化调度器
executorService = Executors.newScheduledThreadPool(
Math.min(scheduledTasks.size(), 10));
// 调度任务
for (ScheduledTask task : scheduledTasks) {
executorService.scheduleAtFixedRate(
task.getRunnable(),
task.getInitialDelay(),
task.getPeriod(),
task.getTimeUnit());
}
started = true;
System.out.println("任务调度器启动,调度任务数: " + scheduledTasks.size());
}
}
@Override
public void destroy() throws Exception {
if (executorService != null && !executorService.isShutdown()) {
executorService.shutdown();
try {
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
executorService.shutdownNow();
}
} catch (InterruptedException e) {
executorService.shutdownNow();
Thread.currentThread().interrupt();
}
System.out.println("任务调度器已关闭");
}
}
}
/**
* 配置验证器
*/
@Component
public static class ConfigurationValidator implements InitializingBean {
@Value("${app.name}")
private String appName;
@Value("${app.version}")
private String appVersion;
@Value("${app.environment:dev}")
private String environment;
@Override
public void afterPropertiesSet() throws Exception {
// 验证必需配置
validateRequiredConfig();
// 验证配置格式
validateConfigFormat();
// 记录配置信息
logConfiguration();
}
private void validateRequiredConfig() {
if (appName == null || appName.trim().isEmpty()) {
throw new IllegalStateException("应用名称未配置");
}
if (appVersion == null || appVersion.trim().isEmpty()) {
throw new IllegalStateException("应用版本未配置");
}
}
private void validateConfigFormat() {
// 验证版本格式
if (!appVersion.matches("\\d+\\.\\d+\\.\\d+")) {
throw new IllegalArgumentException("版本格式不正确: " + appVersion);
}
// 验证环境配置
Set<String> validEnvironments = Set.of("dev", "test", "prod");
if (!validEnvironments.contains(environment)) {
throw new IllegalArgumentException("无效的环境配置: " + environment);
}
}
private void logConfiguration() {
System.out.println("应用配置验证通过:");
System.out.println(" 应用名称: " + appName);
System.out.println(" 应用版本: " + appVersion);
System.out.println(" 运行环境: " + environment);
}
}
}
6. 最佳实践和注意事项
/*
* InitializingBean最佳实践
*/
public class BestPractices {
/**
* 正确的InitializingBean实现
*/
@Component
public static class GoodExample implements InitializingBean {
@Autowired
private DataSource dataSource;
@Autowired
private Environment environment;
private String tableName;
private boolean initialized = false;
@Override
public void afterPropertiesSet() throws Exception {
// 1. 参数验证
validateProperties();
// 2. 资源初始化
initializeResources();
// 3. 状态标记
this.initialized = true;
System.out.println("Bean初始化完成");
}
private void validateProperties() {
if (dataSource == null) {
throw new IllegalStateException("DataSource未注入");
}
String env = environment.getProperty("spring.profiles.active");
if (env == null) {
throw new IllegalStateException("环境配置未设置");
}
}
private void initializeResources() throws SQLException {
// 初始化表名
this.tableName = environment.getProperty("app.table.name", "default_table");
// 验证数据库连接
try (Connection conn = dataSource.getConnection()) {
if (conn.isValid(5)) {
System.out.println("数据库连接验证通过");
} else {
throw new RuntimeException("数据库连接无效");
}
}
}
public void doSomething() {
if (!initialized) {
throw new IllegalStateException("Bean未初始化");
}
// 业务逻辑
}
}
/**
* 避免的错误实现
*/
@Component
public static class BadExample implements InitializingBean {
@Autowired
private SomeService someService;
@Override
public void afterPropertiesSet() throws Exception {
// 错误1: 执行耗时操作
Thread.sleep(10000); // 避免这样做
// 错误2: 不处理异常
someService.riskyOperation(); // 应该处理异常
// 错误3: 复杂的业务逻辑
performComplexBusinessLogic(); // 应该移到专门的业务方法中
}
private void performComplexBusinessLogic() {
// 复杂的业务逻辑不应该在这里执行
}
}
/**
* 现代化的替代方案
*/
@Component
public static class ModernApproach {
@Autowired
private SomeService someService;
// 使用@PostConstruct替代InitializingBean
@PostConstruct
public void initialize() {
// 初始化逻辑
System.out.println("使用@PostConstruct初始化");
}
// 或者使用构造方法注入和初始化
@Autowired
public ModernApproach(SomeService someService) {
this.someService = someService;
// 构造方法中进行初始化
initializeInConstructor();
}
private void initializeInConstructor() {
// 构造方法中的初始化逻辑
}
}
}
7. 核心设计要点总结
7.1 设计目的
- 提供标准的Bean初始化回调机制
- 确保Bean在使用前完成必要的初始化工作
- 解耦Bean的初始化逻辑与业务逻辑
7.2 调用时机
- Bean实例化
- 属性注入完成
- Aware接口方法调用
- BeanPostProcessor前置处理
- afterPropertiesSet()方法调用
- BeanPostProcessor后置处理
- Bean可正常使用
7.3 使用建议
- 优先使用@PostConstruct:减少与Spring框架的耦合
- 参数验证:在afterPropertiesSet中验证必需属性
- 资源初始化:初始化数据库连接、文件句柄等
- 异常处理:适当处理初始化过程中可能发生的异常
- 避免耗时操作:不要在初始化方法中执行长时间运行的操作
7.4 与其他初始化机制的关系
- 执行顺序:@PostConstruct → InitializingBean → init-method
- 互斥性:三种方式可以同时使用,但要注意执行顺序
- 优先级:通常@PostConstruct最先执行
7.5 常见应用场景
- 数据库连接池初始化
- 缓存预加载
- 配置文件读取和验证
- 定时任务启动
- 资源文件加载
InitializingBean作为Spring框架的重要组成部分,为开发者提供了灵活而强大的Bean初始化机制,是理解和使用Spring IoC容器的关键知识点。

889

被折叠的 条评论
为什么被折叠?



