文章目录IOCIOC容器的工作原理Bean的生命周期Bean的自动装配AutowiredResourceInject使用Spring底层组件IOCSpring的核心之一是IOCIOC全称为Inversion of Control中文译为控制反转是面向对象编程中的一种设计原则可以用来减低计算机代码之间的耦合度。IOC的一个重点是在系统运行中动态的向某个对象提供它所需要的其他对象。这一点是通过DIDependency Injection依赖注入来实现的。所谓IOC对于Spring框架来说就是由Spring来负责对象的创建、配置和管理所以可将IOC理解为一个大容器。IOC通过将对象创建和管理的控制权从应用代码转移到Spring容器中实现了松耦合设计。IOC使用依赖注入DI来管理组成一个应用程序的组件这些对象被称为Spring Beans。管理Bean的创建、配置和生命周期Spring提供了两个主要的IOC容器BeanFactory和ApplicationContext。IOC容器管理的对象通常使用注解如Component、Service、Autowired或XML配置声明Bean。IOC容器的工作流程读取配置通过XML文件、注解或Java配置类读取Bean定义和依赖关系。创建和配置Bean容器根据配置实例化Bean并注入它们的依赖。管理Bean生命周期容器负责调用Bean的初始化和销毁方法管理其整个生命周期。通过Spring的IOC容器开发者可以更加专注于业务逻辑而无需关心对象的创建和管理从而提高了代码的可维护性和可扩展性。IOC容器的工作原理IOC容器是Spring框架的核心它负责管理应用程序中对象的生命周期和依赖关系。想要管理Bean首先需要将Bean加载进来。IOC容器首先需要加载应用程序的配置元数据这些配置可以通过XML文件、Java注解或者Java配置类等方式定义。加载完配置之后容器会使用相应的解析器如Dom4j解析XML配置文件将配置信息转换为容器可以理解的数据结构通常是BeanDefinition对象。BeanDefinition包含了类的名称、依赖关系、初始化方法、销毁方法等元数据信息。!-- applicationContext.xml -- bean iduserRepository classcom.example.UserRepository !-- 定义UserRepository的依赖或配置 -- /bean bean iduserService classcom.example.UserService property nameuserRepository refuserRepository / /bean // 加载和解析XML配置 ApplicationContext context new ClassPathXmlApplicationContext(applicationContext.xml);一旦容器解析了Bean的配置信息它会根据这些信息使用Java的反射机制来创建Bean的实例。通常情况下Spring会调用Bean的默认构造方法来实例化对象。// 获取UserService Bean UserService userService (UserService) context.getBean(userService);对象实例化完成容器会根据配置文件或者注解中定义的依赖关系将其他Bean的实例或者值注入到当前Bean中。依赖注入可以通过构造函数注入、Setter方法注入或者字段注入来完成。public class UserService { private UserRepository userRepository; // Setter方法注入 public void setUserRepository(UserRepository userRepository) { this.userRepository userRepository; } // 其他方法 }在依赖注入完成后如果配置了初始化方法例如使用init-method指定的方法、实现InitializingBean接口的方法或者使用PostConstruct注解标记的方法容器会调用这些方法来执行一些初始化的操作例如加载资源、建立连接等。!-- applicationContext.xml -- bean iduserRepository classcom.example.UserRepository init-methodinit destroy-methoddestroy !-- 定义UserRepository的依赖或配置 -- /bean // UserRepository.java public class UserRepository { // 初始化方法 public void init() { System.out.println(UserRepository 初始化方法被调用); } // 销毁方法 public void destroy() { System.out.println(UserRepository 销毁方法被调用); } }Bean的生命周期Spring中的Bean是指由Spring容器管理的对象实例。在Spring框架中Bean是应用程序的核心组件它们由Spring容器创建、组装和管理以帮助开发者实现松耦合、可测试和可维护的代码。Spring Bean的生命周期包含从创建到销毁的一系列过程。即Bean的实例化-初始化-使用-销毁的过程。Spring中的Bean可以根据其作用域的不同可分为单例Bean、原型Bean不同作用域的Bean生命周期也不同。特征单例Bean原型Bean创建容器启动时创建一次。每次请求时创建新实例。作用域管理由Spring容器管理。每次请求时由Spring容器管理新实例。线程安全性单例Bean在多线程环境下共享。原型Bean本身不具备线程安全性。适用性适用于无状态Bean、缓存对象、共享资源等。Spring中的默认作用域。适用于有状态Bean、需要频繁重新初始化的对象等。在每次请求时需要新实例。销毁管理由Spring容器自动管理。- PreDestroy 方法如果存在。- DisposableBean.destroy() 方法如果实现。- 自定义销毁方法如果在Bean定义中指定。没有自动的Spring管理销毁过程。- 需要由客户端手动管理销毁。- 可以通过实现DisposableBean接口或自定义方法手动释放资源。单实例Bean生命周期实例化在容器启动时创建该Bean的唯一实例。初始化初始化前置处理调用所有注册的BeanPostProcessor的postProcessBeforeInitialization方法可以在初始化之前对Bean进行修改。初始化按照顺序执行以下方法如果Bean实现了InitializingBean接口则调用其afterPropertiesSet方法如果在Bean定义中指定了init-method则调用这个方法如果Bean中有用PostConstruct注解标记的方法则调用该方法。初始化后处理调用所有注册的BeanPostProcessor的postProcessAfterInitialization方法可以在初始化之后对Bean进行修改。使用当Bean初始化之后Bean处于就绪状态可以被应用程序中的其他组件使用。销毁销毁前处理在销毁之前Spring容器会依次调用注册的所有BeanPostProcessor的postProcessBeforeDestruction方法。如果Bean类中有用PreDestroy注解标记的方法Spring容器会在销毁之前调用该方法。销毁如果在Bean的定义中通过配置destroy-method属性指定了销毁方法Spring容器会调用这个方法来执行特定的清理操作。单例Bean和多实例Bean的生命周期主要区别在于实例化和销毁的管理方式单例Bean在容器启动时创建一个实例并由容器负责管理其生命周期的完整过程。而多实例Bean在每次请求时创建新的实例并且销毁过程需要开发者手动管理。Configuration public class AppConfig { Bean(initMethod init, destroyMethod destroy) Scope(singleton) public SingletonBean singletonBean() { return new SingletonBean(); } Bean(initMethod init, destroyMethod destroy) Scope(prototype) public PrototypeBean prototypeBean() { return new PrototypeBean(); } public static class SingletonBean implements InitializingBean, DisposableBean { public SingletonBean() { System.out.println(SingletonBean 实例化); } PostConstruct public void postConstruct() { System.out.println(SingletonBean PostConstruct 方法调用); } Override public void afterPropertiesSet() { System.out.println(SingletonBean afterPropertiesSet 方法调用); } public void init() { System.out.println(SingletonBean 自定义初始化方法调用); } PreDestroy public void preDestroy() { System.out.println(SingletonBean PreDestroy 方法调用); } Override public void destroy() { System.out.println(SingletonBean destroy 方法调用); } public void customDestroy() { System.out.println(SingletonBean 自定义销毁方法调用); } } public static class PrototypeBean implements InitializingBean, DisposableBean { public PrototypeBean() { System.out.println(PrototypeBean 实例化); } PostConstruct public void postConstruct() { System.out.println(PrototypeBean PostConstruct 方法调用); } Override public void afterPropertiesSet() { System.out.println(PrototypeBean afterPropertiesSet 方法调用); } public void init() { System.out.println(PrototypeBean 自定义初始化方法调用); } PreDestroy public void preDestroy() { System.out.println(PrototypeBean PreDestroy 方法调用); } Override public void destroy() { System.out.println(PrototypeBean destroy 方法调用); } public void customDestroy() { System.out.println(PrototypeBean 自定义销毁方法调用); } } public static void main(String[] args) { AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(AppConfig.class); SingletonBean singletonBean1 context.getBean(SingletonBean.class); SingletonBean singletonBean2 context.getBean(SingletonBean.class); System.out.println(singletonBean1 singletonBean2 : (singletonBean1 singletonBean2)); PrototypeBean prototypeBean1 context.getBean(PrototypeBean.class); PrototypeBean prototypeBean2 context.getBean(PrototypeBean.class); System.out.println(prototypeBean1 prototypeBean2 : (prototypeBean1 prototypeBean2)); context.close(); // 手动销毁 Prototype Bean prototypeBean1.destroy(); prototypeBean2.destroy(); } }举个例子来更好的理解Bean的生命周期首先在Spring的配置文件如XML配置或者使用注解方式我们定义UserService类作为一个Bean并配置它的初始化方法、销毁方法以及其他属性。// UserService.java public class UserService implements InitializingBean, DisposableBean, BeanNameAware { private String message; // 初始化方法 public void init() { System.out.println(UserService 初始化方法被调用); } // 销毁方法 public void destroy() { System.out.println(UserService 销毁方法被调用); } // Setter 方法 public void setMessage(String message) { this.message message; } // Getter 方法 public String getMessage() { return message; } // 实现 InitializingBean 接口的方法 Override public void afterPropertiesSet() throws Exception { System.out.println(UserService InitializingBean 的 afterPropertiesSet 方法被调用); } // 实现 DisposableBean 接口的方法 Override public void destroy() throws Exception { System.out.println(UserService DisposableBean 的 destroy 方法被调用); } // 实现 BeanNameAware 接口的方法 Override public void setBeanName(String name) { System.out.println(UserService BeanNameAware 的 setBeanName 方法被调用Bean的名称为 name); } }在Spring的配置文件中我们将UserService类定义为一个Bean并配置初始化方法、销毁方法以及其他属性。!-- applicationContext.xml -- bean iduserService classcom.example.UserService init-methodinit destroy-methoddestroy property namemessage valueHello, Spring! / /bean当应用程序启动并且Spring容器加载配置时将会执行以下步骤来管理UserServiceBean的生命周期实例化Spring容器根据配置文件或者注解实例化UserService类的一个对象实例。依赖注入将配置的属性如message注入到UserService实例中。初始化调用init-method指定的初始化方法或者InitializingBean接口的afterPropertiesSet()方法例如执行init()方法。在初始化过程中还可以调用BeanNameAware接口的方法获取和设置Bean的名称。使用UserServiceBean可以被应用程序的其他组件使用执行其业务逻辑如打印消息。销毁当应用程序关闭时Spring容器会调用destroy-method指定的销毁方法或者DisposableBean接口的destroy()方法例如执行destroy()方法。Bean的自动装配Bean的自动装配是Spring框架提供的一种便捷的方式用于自动解析和设置Bean之间的依赖关系而无需显式配置每一个依赖关系的方式。Spring支持以下几种自动装配的方式根据类型自动装配Spring会自动将一个属性与同一上下文中具有兼容类型的Bean进行匹配。如果容器中存在多个符合类型的Bean则会抛出异常。public interface UserRepository { // 接口定义 } Component public class UserRepositoryImpl1 implements UserRepository { // 实现1 } Component public class UserRepositoryImpl2 implements UserRepository { // 实现2 } // 示例根据类型自动装配 Autowired private UserRepository userRepository;根据名称自动装配Spring会自动将一个属性与容器中相同名称的Bean进行匹配要求Bean的名称必须与属性名称完全一致。public interface UserRepository { // 接口定义 } Component(userRepository1) public class UserRepositoryImpl1 implements UserRepository { // 实现1 } Component(userRepository2) public class UserRepositoryImpl2 implements UserRepository { // 实现2 } // 示例根据名称自动装配 Autowired private UserRepository userRepository;构造函数自动装配Spring会自动通过构造函数来注入依赖从而避免了使用Autowired注解的繁琐。Spring会查找与构造函数参数类型相匹配的Bean并自动进行注入。// 示例构造函数自动装配 Autowired public UserService(UserRepository userRepository) { this.userRepository userRepository; }自动装配标识符可以使用Autowired注解结合Qualifier注解来指定具体的Bean名称来解决多个相同类型Bean的自动装配歧义问题。// 示例结合Qualifier注解指定Bean名称 Autowired Qualifier(userRepository) private UserRepository userRepository;自动装配和主候选Bean可以使用Primary注解来标识一个主要的Bean候选者当存在多个匹配的Bean时Spring会优先选择标有Primary注解的Bean进行注入。// 示例使用Primary注解标识主候选Bean Component Primary public class PrimaryUserRepository implements UserRepository { // 实现代码 }在Spring中用于实现自动装配的注解有三个它们都能自动注入依赖但在一些细节上有所区别。自动装配来源装配方式支持 Primary支持的属性AutowiredSpring 框架原生根据类型装配是required(boolean)指定是否必须注入默认为true。ResourceJSR-250 (Java EE 标准)根据名称装配按名称找不到时根据类型否name(String)指定要装配的 Bean 名称默认为属性名称。InjectJSR-330 (Java EE 标准)根据类型装配是无在日常开发中都是使用SpringBoot进行开发一般使用Autowired注解就够了适合大多数Spring应用场景。AutowiredAutowired是Spring框架中用于自动装配Bean的主要方式之一。它可以根据类型来自动注入依赖关系。Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) Retention(RetentionPolicy.RUNTIME) Documented public interface Autowired { /** * Declares whether the annotated dependency is required. * pDefaults to {code true}. */ boolean required() default true; }在使用Autowired时Spring会尝试将一个属性与容器中具有兼容类型的Bean进行匹配。Component public class UserService { private UserRepository userRepository; Autowired public void setUserRepository(UserRepository userRepository) { this.userRepository userRepository; } }如果存在多个同类型的Bean可以结合Primary注解指定优先级最高的Bean进行注入。Component public class UserRepositoryImpl1 implements UserRepository { // implementation } Component Primary public class UserRepositoryImpl2 implements UserRepository { // implementation } Component public class UserService { private UserRepository userRepository; Autowired public void setUserRepository(UserRepository userRepository) { this.userRepository userRepository; } }除了使用Primary还可以使用Qualifier注解来指定具体的Bean名称来解决多个相同类型Bean的自动装配歧义问题。Component(userRepository1) public class UserRepositoryImpl1 implements UserRepository { // 实现1 } Component(userRepository2) public class UserRepositoryImpl2 implements UserRepository { // 实现2 } // 示例结合Qualifier注解指定Bean名称 Autowired Qualifier(userRepository2) private UserRepository userRepository;Autowired可以使用required属性控制是否要求依赖关系存在默认为true表示必须存在兼容的Bean设为false可以允许null值注入。Component public class UserService { private UserRepository userRepository; Autowired(required false) public void setUserRepository(UserRepository userRepository) { this.userRepository userRepository; } }Autowired可以放在构造器、参数、方法、属性上。构造器注入可以在构造器上使用Autowired来完成构造器注入Spring会自动根据类型进行注入。Component public class UserService { private final UserRepository userRepository; Autowired public UserService(UserRepository userRepository) { this.userRepository userRepository; } }属性注入可以直接在属性上使用Autowired注解来进行依赖注入。Component public class UserService { Autowired private UserRepository userRepository; }方法注入可以在方法上使用Autowired注解Spring会在初始化Bean时调用这些方法完成依赖注入。Component public class UserService { private UserRepository userRepository; Autowired public void setUserRepository(UserRepository userRepository) { this.userRepository userRepository; } }参数注入可以在方法参数上使用Autowired注解Spring会根据参数类型自动注入对应的Bean。Component public class UserService { private UserRepository userRepository; Autowired public void setUserRepository(UserRepository userRepository) { this.userRepository userRepository; } public void processUserData(Autowired User user) { } }Autowired的实现原理是通过Autowired后置处理器实现的。在Autowired注解文档注释上面可以看到与之息息相关的一个类AutowiredAnnotationBeanPostProcessor即Autowired后置处理器。看到该类实现了MergedBeanDefinitionPostProcessor接口在postProcessMergedBeanDefinition方法上打一个断点就可以看到Autowired的调用栈。/* * see AutowiredAnnotationBeanPostProcessor */ Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) Retention(RetentionPolicy.RUNTIME) Documented public interface Autowired{}Autowired注解调用栈AbstractApplicationContext.refresh(容器初始化) --- registerBeanPostProcessors (注册AutowiredAnnotationBeanPostProcessor) --- finishBeanFactoryInitialization --- AbstractAutowireCapableBeanFactory.doCreateBean --- AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors --- MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition --- AutowiredAnnotationBeanPostProcessor.findAutowiringMetadata核心调用postProcessMergedBeanDefinition ---findAutowiringMetadata ---buildAutowiringMetadata Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class? beanType, String beanName) { // 调用 findAutowiringMetadata InjectionMetadata metadata findAutowiringMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); } private InjectionMetadata findAutowiringMetadata(String beanName, Class? clazz, Nullable PropertyValues pvs) { // Fall back to class name as cache key, for backwards compatibility with custom callers. String cacheKey (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); // Quick check on the concurrent map first, with minimal locking. InjectionMetadata metadata this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this.injectionMetadataCache) { metadata this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { if (metadata ! null) { metadata.clear(pvs); } // 调用buildAutowiringMetadata metadata buildAutowiringMetadata(clazz); this.injectionMetadataCache.put(cacheKey, metadata); } } } return metadata; } private InjectionMetadata buildAutowiringMetadata(final Class? clazz) { LinkedListInjectionMetadata.InjectedElement elements new LinkedList(); Class? targetClass clazz;//需要处理的目标类 do { final LinkedListInjectionMetadata.InjectedElement currElements new LinkedList(); // 通过反射获取该类所有的字段并遍历每一个字段并通过方法findAutowiredAnnotation遍历每一个字段的所用注解 // 如果用autowired修饰了则返回auotowired相关属性 ReflectionUtils.doWithLocalFields(targetClass, field - { AnnotationAttributes ann findAutowiredAnnotation(field); if (ann ! null) {//校验autowired注解是否用在了static方法上 if (Modifier.isStatic(field.getModifiers())) { if (logger.isWarnEnabled()) { logger.warn(Autowired annotation is not supported on static fields: field); } return; }//判断是否指定了required boolean required determineRequiredStatus(ann); currElements.add(new AutowiredFieldElement(field, required)); } }); // 和上面一样的逻辑但是是通过反射处理类的method ReflectionUtils.doWithLocalMethods(targetClass, method - { Method bridgedMethod BridgeMethodResolver.findBridgedMethod(method); if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) { return; } AnnotationAttributes ann findAutowiredAnnotation(bridgedMethod); if (ann ! null method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { if (Modifier.isStatic(method.getModifiers())) { if (logger.isWarnEnabled()) { logger.warn(Autowired annotation is not supported on static methods: method); } return; } if (method.getParameterCount() 0) { if (logger.isWarnEnabled()) { logger.warn(Autowired annotation should only be used on methods with parameters: method); } } boolean required determineRequiredStatus(ann); PropertyDescriptor pd BeanUtils.findPropertyForMethod(bridgedMethod, clazz); currElements.add(new AutowiredMethodElement(method, required, pd)); } }); // 用Autowired修饰的注解可能不止一个因此都加在currElements这个容器里面一起处理 elements.addAll(0, currElements); targetClass targetClass.getSuperclass(); } while (targetClass ! null targetClass ! Object.class); return new InjectionMetadata(clazz, elements); }通过上面的源码可以看到Spring在运行时通过反射查找Autowired注解并自动注入相关字段。Spring框架利用反射遍历目标类及其超类的所有字段和方法查找并收集所有使用了Autowired注解的元素。对于每个字段和方法首先通过反射获取注解信息如果字段或方法被Autowired注解修饰且符合条件如非静态则将其封装成对应的注入元素AutowiredFieldElement或AutowiredMethodElement并添加到当前元素列表中。最后这些注入元素会被封装到InjectionMetadata对象中并用于实际的依赖注入过程从而实现Spring的自动注入功能。ResourceResource注解来自JSR-250JDK自带主要用于通过名称注入依赖。它的行为类似于Autowired但它更倾向于按名称进行注入。默认情况下Resource注解按名称进行注入。如果找不到同名的Bean再按类型进行匹配。它不支持Primary如果存在多个同类型的Bean且未指定name属性会抛出异常。Component public class UserService { Resource(name userRepositoryImpl1) private UserRepository userRepository; }假设我们有一个旧项目其中大量使用了JDK标准的Resource注解进行依赖注入而我们现在想要将项目迁移到Spring同时保持现有的依赖注入逻辑不变。在这种情况下我们可以继续使用Resource注解进行依赖注入。InjectInject注解来自JSR-330需要导入javax.inject包。它的行为与Autowired类似但没有任何属性。dependency groupIdjavax.inject/groupId artifactIdjavax.inject/artifactId version1/version /dependencyInject注解按类型进行注入可以结合Primary注解指定优先级最高的Bean进行注入。Component public class UserService { Inject Named(userRepositoryImpl1) private UserRepository userRepository; } // Define multiple implementations Component Named(userRepositoryImpl1) public class UserRepositoryImpl1 implements UserRepository { // implementation details } Component Named(userRepositoryImpl2) public class UserRepositoryImpl2 implements UserRepository { // implementation details }也可以结合Named注解显式指定要注入的Bean名称解决多个同类型Bean的注入问题。Component(userRepository1) public class UserRepositoryImpl1 implements UserRepository { // 实现1 } Primary Component(userRepository2) public class UserRepositoryImpl2 implements UserRepository { // 实现2 } Component public class UserService { Inject Named(userRepository1) private UserRepository userRepository; }假设我们有一个项目需要在不同的环境中运行。在本地开发时我们使用Spring但在生产环境中我们使用 Java EE 容器这些容器使用 CDIContexts and Dependency Injection作为依赖注入框架。为了在不同的环境中都能够使用相同的代码进行依赖注入我们可以使用JSR-330标准的Inject注解。这种方式使得代码能够在Spring和Java EE环境中都能正常运行。CDIContexts and Dependency Injection上下文与依赖注入是 Java EE 标准的一部分定义了一种类型安全的依赖注入机制主要用于管理 Java EE 应用程序中的生命周期和依赖关系。CDI 提供了一种统一的、标准的依赖注入方式使得开发者可以更容易地管理对象的创建、销毁以及对象之间的依赖关系。使用Spring底层组件为了在Spring框架的基础上实现更加细粒度的控制或定制化需求可以使用Spring底层组件。Aware接口是一组特定于Spring容器的接口允许beans感知和与Spring容器进行交互。通过实现Aware接口的子接口来使用Spring的底层的组件。Aware接口类似于回调方法的形式在Spring加载的时候将我们自定以的组件加载。/** * A marker superinterface indicating that a bean is eligible to be notified by the * Spring container of a particular framework object through a callback-style method. * The actual method signature is determined by individual subinterfaces but should * typically consist of just one void-returning method that accepts a single argument. */ public interface Aware {}常用的Aware接口ApplicationContextAware允许Bean访问ApplicationContext从而可以访问容器中的其他Bean或执行更高级的容器操作。Component public class MyBean implements ApplicationContextAware { private ApplicationContext applicationContext; Override public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext applicationContext; } public void someMethod() { // 使用 ApplicationContext 获取其他 Bean AnotherBean anotherBean applicationContext.getBean(AnotherBean.class); // 执行更高级的容器操作如发布事件等 applicationContext.publishEvent(new CustomEvent(this, Some message)); } }BeanFactoryAware允许Bean访问配置它的Bean工厂。Component public class MyBean implements BeanFactoryAware { private BeanFactory beanFactory; Override public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory beanFactory; } public void someMethod() { // 使用 BeanFactory 获取其他 Bean AnotherBean anotherBean beanFactory.getBean(AnotherBean.class); // 可以进一步操作 BeanFactory如获取 Bean 的定义信息等 String[] beanDefinitionNames beanFactory.getBeanDefinitionNames(); } }BeanPostProcessor也是常用的底层组件。它是Bean的后置处理器在初始化前后进行处理工作。需要在Bean实例化后和初始化前后执行自定义的处理逻辑如AOP切面的实现、自定义注解处理等。调用顺序为创建对象 -- postProcessBeforeInitialization -- 初始化 -- postProcessAfterInitialization -- 销毁 public class MainTest { public static void main(String[] args) { // 获取Spring IOC容器 AnnotationConfigApplicationContext annotationConfigApplicationContext new AnnotationConfigApplicationContext(DemoConfiguration.class); System.out.println(容器初始化完成...); annotationConfigApplicationContext.close(); System.out.println(容器销毁了...); } } Configuration class DemoConfiguration implements BeanPostProcessor { Bean(initMethod init, destroyMethod destroy) public DemoEntity getDemoEntity(){ return new DemoEntity(); } Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println(调用了 postProcessBeforeInitialization); return bean; } Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println(调用了 postProcessAfterInitialization); return bean; } } Component class DemoEntity { public DemoEntity(){ System.out.println(调用了构造器...); } public void destroy(){ System.out.println(调用了销毁方法...); } public void init() { System.out.println(调用了初始化方法...); } }通过打断点可以看到在创建Bean的时候会调用AbstractAutowireCapableBeanFactory类的doCreateBean方法这也是创建Bean的核心方法。protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { // 创建 Bean 实例 Object beanInstance createBeanInstance(mbd, beanName, args); // 提前暴露已经创建的 Bean 实例用于解决循环依赖问题 Object exposedObject beanInstance; try { // 给 Bean 实例应用属性填充包括依赖注入 populateBean(beanName, mbd, instanceWrapper); // 初始化 Bean执行各种初始化方法 exposedObject initializeBean(beanName, exposedObject, mbd); }catch (Exception ex) { throw new BeanCreationException(beanName, Initialization of bean failed, ex); } // 注册销毁回调用于在 Bean 销毁时执行清理操作 registerDisposableBeanIfNecessary(beanName, exposedObject, mbd); return exposedObject; }doCreateBean方法中核心方法为populateBean方法其调用栈大致如下populateBean(){ applyBeanPostProcessorsBeforeInitialization() -- invokeInitMethods() -- applyBeanPostProcessorsAfterInitialization() }在初始化之前调用populateBean()方法给Bean进行属性赋值之后再调用applyBeanPostProcessorsBeforeInitialization方法。public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException { Object result existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current processor.postProcessBeforeInitialization(result, beanName); if (current null) { return result; } result current; } return result; }该方法作用是遍历容器中所有的BeanPostProcessor挨个执行postProcessBeforeInitialization方法一旦返回null将不会执行后面Bean的postProcessBeforeInitialization方法。之后在调用invokeInitMethods方法进行Bean的初始化最后在执行applyBeanPostProcessorsAfterInitialization方法执行一些初始化之后的工作。