Phương thức finishBeanFactoryInitialization trong lớp AbstractApplicationContext đảm bảo hoàn tất quá trình khởi tạo BeanFactory, bao gồm việc tạo các Bean đơn thể không được trì hoãn.
Phương thức mã nguồn
// Chỉ lấy hai dòng quan trọng
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Cố định cấu hình hiện tại, không cho phép thay đổi định nghĩa Bean
beanFactory.freezeConfiguration();
// Khởi tạo các Bean đơn thể còn lại
beanFactory.initializeNonLazySingletons();
}
Tập trung vào phương thức beanFactory.initializeNonLazySingletons()
Mã nguồn phương thức initializeNonLazySingletons
public void initializeNonLazySingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Tiến hành khởi tạo các Bean đơn thể trong " + this);
}
// Lấy danh sách tên định nghĩa Bean
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Duyệt qua từng định nghĩa Bean, tạo các Bean đơn thể không trì hoãn
for (String beanName : beanNames) {
// Lấy định nghĩa Bean cụ thể
RootBeanDefinition def = getMergedLocalBeanDefinition(beanName);
// Kiểm tra điều kiện: không phải abstract, đơn thể, không trì hoãn
if (!def.isAbstract() && def.isSingleton() && !def.isLazyInit()) {
// Kiểm tra xem có phải FactoryBean
if (isFactoryBean(beanName)) {
// Lấy đối tượng thực tế từ FactoryBean
FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
// Nếu không phải FactoryBean, lấy trực tiếp Bean
getBean(beanName);
}
} else {
// Nếu không phải FactoryBean, lấy trực tiếp Bean
// Đây là nơi xử lý cơ chế ba cấp độ lưu trữ chu trình phụ thuộc
getBean(beanName);
}
}
}
// Duyệt các Bean đã tạo và gọi phương thức afterSingletonsInstantiated
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
Giải thích chi tiết
- finishBeanFactoryInitialization:
- Hoàn tất quá trình khởi tạo BeanFactory.
- Gọi phương thức initializeNonLazySingletons để tạo các Bean đơn thể còn lại.
- initializeNonLazySingletons:
- Duyệt danh sách định nghĩa Bean và tạo các Bean đơn thể không trì hoãn.
- Xử lý trường hợp Bean là FactoryBean trước.
- Tạo các Bean đơn thể không trì hoãn.
- Gọi phương thức afterSingletonsInstantiated cho các Bean triển khai giao diện SmartInitializingSingleton.
Vai trò
Phương thức finishBeanFactoryInitialization đảm bảo BeanFactory được khởi tạo đầy đủ, các Bean được tạo và quản lý đúng quy trình. Quá trình này bao gồm tạo các Bean đơn thể không trì hoãn, xử lý chu trình phụ thuộc, và thực hiện các callback vòng đời của Bean.
Cơ chế ba cấp độ lưu trữ chu trình phụ thuộc được xử lý tại đây
Các bước quan trọng nội bộ
- Tạo Bean đơn thể không trì hoãn: Các Bean này được khởi tạo khi ứng dụng bắt đầu, đảm bảo sẵn sàng sử dụng.
- Tiếp xúc trước Bean: Khi xử lý Bean triển khai SmartInitializingSingleton, hệ thống sẽ gọi phương thức afterSingletonsInstantiated sau khi tất cả Bean đã được tạo.
- Xử lý callback vòng đời: Gọi các phương thức khởi tạo (ví dụ: @PostConstruct) và hủy (ví dụ: @PreDestroy) cho các Bean.
- Đăng ký DisposableBean: Hệ thống quản lý việc hủy các Bean đơn thể khi ứng dụng dừng.
- Đăng ký BeanPostProcessor: Xử lý các logic hậu xử lý như tiêm thuộc tính và giải quyết phụ thuộc.
Kết luận
Phương thức finishBeanFactoryInitialization là bước quan trọng trong chuỗi khởi động Spring, đảm bảo BeanFactory được khởi tạo đầy đủ. Quá trình này bao gồm tạo Bean đơn thể, xử lý callback vòng đời, và chuẩn bị môi trường cho ứng dụng hoạt động ổn định.