源码
BeanDefinition
BeanDefinition
是 Spring 用于描述 Bean 配置元信息的核心接口,定义了 Bean 的类名、作用域、依赖、构造参数、属性、初始化和销毁方法等配置项,是 Spring 容器注册和实例化 Bean 的基础数据结构。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;
// Modifiable attributes
void setParentName(@Nullable String parentName);
@Nullable
String getParentName();
void setBeanClassName(@Nullable String beanClassName);
@Nullable
String getBeanClassName();
void setScope(@Nullable String scope);
@Nullable
String getScope();
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
void setDependsOn(@Nullable String... dependsOn);
@Nullable
String[] getDependsOn();
void setAutowireCandidate(boolean autowireCandidate);
boolean isAutowireCandidate();
void setPrimary(boolean primary);
boolean isPrimary();
void setFallback(boolean fallback);
boolean isFallback();
void setFactoryBeanName(@Nullable String factoryBeanName);
@Nullable
String getFactoryBeanName();
void setFactoryMethodName(@Nullable String factoryMethodName);
@Nullable
String getFactoryMethodName();
ConstructorArgumentValues getConstructorArgumentValues();
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
MutablePropertyValues getPropertyValues();
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
void setInitMethodName(@Nullable String initMethodName);
@Nullable
String getInitMethodName();
void setDestroyMethodName(@Nullable String destroyMethodName);
@Nullable
String getDestroyMethodName();
void setRole(int role);
int getRole();
void setDescription(@Nullable String description);
@Nullable
String getDescription();
// Read-only attributes
ResolvableType getResolvableType();
boolean isSingleton();
boolean isPrototype();
boolean isAbstract();
@Nullable
String getResourceDescription();
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}
1. AbstractBeanDefinition
AbstractBeanDefinition
是 Spring 中用于描述 Bean 元信息的基础类,它统一封装了 Bean 的类、作用域、依赖注入方式、初始化/销毁方法、工厂方法、构造函数参数、属性值等配置,是容器内部 Bean 注册和创建的核心数据结构。
@SuppressWarnings("serial")
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable {
public static final String SCOPE_DEFAULT = "";
public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
public static final int DEPENDENCY_CHECK_NONE = 0;
public static final int DEPENDENCY_CHECK_OBJECTS = 1;
public static final int DEPENDENCY_CHECK_SIMPLE = 2;
public static final int DEPENDENCY_CHECK_ALL = 3;
public static final String PREFERRED_CONSTRUCTORS_ATTRIBUTE = "preferredConstructors";
public static final String ORDER_ATTRIBUTE = "order";
public static final String INFER_METHOD = "(inferred)";
// 可以是 Class 或 class 名字的字符串,表示 Bean 的类型
@Nullable
private volatile Object beanClass;
// Bean 的作用域,默认单例
@Nullable
private String scope = SCOPE_DEFAULT;
// 是否为抽象 Bean 定义(不能实例化),常用于父定义。
private boolean abstractFlag = false;
// 是否允许在后台线程初始化,主要用于优化启动性能。
private boolean backgroundInit = false;
// 是否懒加载。若为 true,容器启动时不实例化此 Bean。
@Nullable
private Boolean lazyInit;
// 自动装配模式,默认不自动装配
private int autowireMode = AUTOWIRE_NO;
// 依赖检查级别, 默认不检查
private int dependencyCheck = DEPENDENCY_CHECK_NONE;
// 当前 Bean 所依赖的其他 Bean 名称(先初始化它们)。
@Nullable
private String[] dependsOn;
// 当前 Bean 是否可以被自动注入到其他 Bean 中。
private boolean autowireCandidate = true;
// 是否为默认候选 Bean,配合 @Autowired 使用。
private boolean defaultCandidate = true;
// 当前 Bean 是否为主要候选(@Primary 的效果)。
private boolean primary = false;
// 是否作为备用候选(很少使用)。
private boolean fallback = false;
// 限定符,用于控制自动注入时的匹配(类似于 @Qualifier 注解)。
private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>();
// 提供实例的函数式接口,可自定义 Bean 的创建逻辑。
@Nullable
private Supplier<?> instanceSupplier;
// 是否允许访问非 public 构造器或字段。
private boolean nonPublicAccessAllowed = true;
// 是否宽松解析构造器(主要用于构造器注入)。
private boolean lenientConstructorResolution = true;
// 指定创建当前 Bean 的 FactoryBean 名称(factory-bean 属性)。
@Nullable
private String factoryBeanName;
// 工厂方法名称(可配合 FactoryBean 或 static 方法)。
@Nullable
private String factoryMethodName;
// 构造器参数值列表,用于构造器注入。
@Nullable
private ConstructorArgumentValues constructorArgumentValues;
// Bean 属性值集合(setter 注入)。
@Nullable
private MutablePropertyValues propertyValues;
// 方法覆盖定义(用于覆盖 lookup-method、replace-method)。
private MethodOverrides methodOverrides = new MethodOverrides();
// 初始化方法名列表(对应 init-method)。
@Nullable
private String[] initMethodNames;
// 销毁方法名列表(对应 destroy-method)。
@Nullable
private String[] destroyMethodNames;
// 是否强制调用 init 方法。
private boolean enforceInitMethod = true;
// 是否强制调用 destroy 方法。
private boolean enforceDestroyMethod = true;
// 是否为系统生成的合成 Bean(用户不可见)。
private boolean synthetic = false;
// Bean 的角色类型(如应用级、支持级、基础设施级)。
private int role = BeanDefinition.ROLE_APPLICATION;
// 描述信息,仅用于文档或调试。
@Nullable
private String description;
// 来源资源(如 XML 文件、注解等)。
@Nullable
private Resource resource;
protected AbstractBeanDefinition() {
this(null, null);
}
protected AbstractBeanDefinition(@Nullable ConstructorArgumentValues cargs, @Nullable MutablePropertyValues pvs) {
this.constructorArgumentValues = cargs;
this.propertyValues = pvs;
}
// ...
}
RootBeanDefinition
@SuppressWarnings("serial")
public class RootBeanDefinition extends AbstractBeanDefinition {
/**
* 被装饰的 BeanDefinitionHolder,记录该 Bean 定义是否经过装饰(如代理等)。
*/
@Nullable
private BeanDefinitionHolder decoratedDefinition;
/**
* 关联的注解元素(类、方法等),用于限定符匹配和元数据访问。
*/
@Nullable
private AnnotatedElement qualifiedElement;
/**
* 标记该 BeanDefinition 是否需要重新合并(刷新/重新处理),用于保证配置最新。
*/
volatile boolean stale;
/**
* 是否允许缓存相关的元数据信息,开启缓存能提升性能。
*/
boolean allowCaching = true;
/**
* 标识是否唯一确定了工厂方法(用于通过工厂方法实例化 Bean)。
*/
boolean isFactoryMethodUnique;
/**
* 缓存的目标类型,支持泛型类型解析。
*/
@Nullable
volatile ResolvableType targetType;
/**
* 缓存解析出的 Bean 类,避免重复反射调用。
*/
@Nullable
volatile Class<?> resolvedTargetType;
/**
* 缓存该 Bean 是否为 FactoryBean 类型,避免重复判断。
*/
@Nullable
volatile Boolean isFactoryBean;
/**
* 缓存泛型工厂方法的返回类型。
*/
@Nullable
volatile ResolvableType factoryMethodReturnType;
/**
* 缓存用于实例化的唯一工厂方法,方便反射调用。
*/
@Nullable
volatile Method factoryMethodToIntrospect;
/**
* 缓存销毁方法名(包含显式指定或推断的)。
*/
@Nullable
volatile String resolvedDestroyMethodName;
/**
* 用于同步访问构造函数相关字段的锁对象。
*/
final Object constructorArgumentLock = new Object();
/**
* 缓存解析出的构造器或工厂方法。
*/
@Nullable
Executable resolvedConstructorOrFactoryMethod;
/**
* 标记构造参数是否已全部解析完成。
*/
boolean constructorArgumentsResolved = false;
/**
* 缓存完全解析好的构造参数数组。
*/
@Nullable
Object[] resolvedConstructorArguments;
/**
* 缓存部分准备好的构造参数,可能用于延迟解析。
*/
@Nullable
Object[] preparedConstructorArguments;
/**
* 用于同步访问后置处理相关字段的锁对象。
*/
final Object postProcessingLock = new Object();
/**
* 标记是否已应用过 MergedBeanDefinitionPostProcessor 后置处理。
*/
boolean postProcessed = false;
/**
* 标记是否已应用过实例化前的后置处理(如代理增强)。
*/
@Nullable
volatile Boolean beforeInstantiationResolved;
/**
* 外部管理的配置成员集合(如方法、字段),不由 Spring 管理。
*/
@Nullable
private Set<Member> externallyManagedConfigMembers;
/**
* 外部管理的初始化方法名称集合,不由 Spring 调用。
*/
@Nullable
private Set<String> externallyManagedInitMethods;
/**
* 外部管理的销毁方法名称集合,不由 Spring 调用。
*/
@Nullable
private Set<String> externallyManagedDestroyMethods;
// ...
}
ChildBeanDefinition
ChildBeanDefinition
是一种基于父 Bean 定义继承属性的子级配置,用于在 Spring 中实现 BeanDefinition 的复用与扩展。
@SuppressWarnings("serial")
public class ChildBeanDefinition extends AbstractBeanDefinition {
@Nullable
private String parentName;
public ChildBeanDefinition(String parentName) {
super();
this.parentName = parentName;
}
@Override
public void setParentName(@Nullable String parentName) {
this.parentName = parentName;
}
@Override
@Nullable
public String getParentName() {
return this.parentName;
}
@Override
public void validate() throws BeanDefinitionValidationException {
super.validate();
if (this.parentName == null) {
throw new BeanDefinitionValidationException("'parentName' must be set in ChildBeanDefinition");
}
}
@Override
public AbstractBeanDefinition cloneBeanDefinition() {
return new ChildBeanDefinition(this);
}
// ...
}
GenericBeanDefinition
GenericBeanDefinition
是 Spring 提供的通用 Bean 定义实现类,既支持独立定义 Bean,也支持通过 parentName
继承其他 Bean 的配置,适用于 XML、注解等多种配置方式。
@SuppressWarnings("serial")
public class GenericBeanDefinition extends AbstractBeanDefinition {
@Nullable
private String parentName;
public GenericBeanDefinition() {
super();
}
@Override
public void setParentName(@Nullable String parentName) {
this.parentName = parentName;
}
@Override
@Nullable
public String getParentName() {
return this.parentName;
}
@Override
public AbstractBeanDefinition cloneBeanDefinition() {
return new GenericBeanDefinition(this);
}
// ...
}
特性/类名 | ChildBeanDefinition | GenericBeanDefinition | RootBeanDefinition |
---|---|---|---|
继承关系 | AbstractBeanDefinition | AbstractBeanDefinition | AbstractBeanDefinition |
父类支持 | ✅ 明确有 parentName 且必须设置 | ✅ 可选设置 parentName | ❌ 通常为顶层定义(无 parent) |
典型用途 | 用于继承父 Bean 进行属性覆盖 | 用于通用场景(XML/注解/编程注册) | Spring 内部标准实现,多数合并后的定义是它 |
是否可独立注册 | ❌ 不可,无 parentName 会抛异常 | ✅ 可以直接使用 | ✅ 可独立使用或合并后生成 |
Spring 是否自动生成 | ❌ 否 | ✅ 是 | ✅ 是(合并 Bean 定义时默认生成) |
是否支持合并父定义 | ✅ 是,依赖父定义合并 | ✅ 是,具备父定义字段 | ✅ 是,合并后默认使用此类型 |
注解支持 | ⛔ 通常用于 XML 配置 | ✅ 注解/编程均可 | ✅ 通用,内部用 |
常用场景 | XML 中的 <bean parent="..."/> | 通用注册、注册器手动注册 | Spring 容器合并后的内部表示 |
是否序列化字段多 | ❌ 少 | ✅ 一般 | ✅ 非常多(缓存类名、工厂方法等) |
是否推荐扩展 | ❌ 不推荐 | ✅ 可扩展 | ❌ 内部使用,不建议扩展 |
2. AnnotatedBeanDefinition
AnnotatedBeanDefinition
是一个扩展自 BeanDefinition 的接口,表示包含注解元数据的 Bean 定义,通常用于通过注解方式(如 @Component、@Configuration 等)注册的 Bean,支持获取类级别和工厂方法的注解信息。
public interface AnnotatedBeanDefinition extends BeanDefinition {
AnnotationMetadata getMetadata();
@Nullable
MethodMetadata getFactoryMethodMetadata();
}
AnnotatedGenericBeanDefinition
AnnotatedGenericBeanDefinition
是一个支持注解驱动的通用 Bean 定义类,既可以表示类级注解 Bean,也可以表示通过 @Bean 工厂方法注册的 Bean,具备完整的注解元数据支持。
@SuppressWarnings("serial")
public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
private final AnnotationMetadata metadata;
@Nullable
private MethodMetadata factoryMethodMetadata;
public AnnotatedGenericBeanDefinition(Class<?> beanClass) {
setBeanClass(beanClass);
this.metadata = AnnotationMetadata.introspect(beanClass);
}
public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata) {
Assert.notNull(metadata, "AnnotationMetadata must not be null");
if (metadata instanceof StandardAnnotationMetadata sam) {
setBeanClass(sam.getIntrospectedClass());
}
else {
setBeanClassName(metadata.getClassName());
}
this.metadata = metadata;
}
public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata, MethodMetadata factoryMethodMetadata) {
this(metadata);
Assert.notNull(factoryMethodMetadata, "MethodMetadata must not be null");
setFactoryMethodName(factoryMethodMetadata.getMethodName());
this.factoryMethodMetadata = factoryMethodMetadata;
}
@Override
public final AnnotationMetadata getMetadata() {
return this.metadata;
}
@Override
@Nullable
public final MethodMetadata getFactoryMethodMetadata() {
return this.factoryMethodMetadata;
}
}
ScannedGenericBeanDefinition
ScannedGenericBeanDefinition 是在类路径扫描过程中创建的 Bean 定义,封装了注解元数据但不涉及工厂方法,主要用于处理 @Component 等注解类的注册。
@SuppressWarnings("serial")
public class ScannedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
private final AnnotationMetadata metadata;
public ScannedGenericBeanDefinition(MetadataReader metadataReader) {
Assert.notNull(metadataReader, "MetadataReader must not be null");
this.metadata = metadataReader.getAnnotationMetadata();
setBeanClassName(this.metadata.getClassName());
setResource(metadataReader.getResource());
}
@Override
public final AnnotationMetadata getMetadata() {
return this.metadata;
}
@Override
@Nullable
public MethodMetadata getFactoryMethodMetadata() {
return null;
}
}
特性 | ScannedGenericBeanDefinition | AnnotatedGenericBeanDefinition |
---|---|---|
继承结构 | GenericBeanDefinition → AnnotatedBeanDefinition | 同上 |
典型创建来源 | 类路径扫描:ClassPathBeanDefinitionScanner | 手动注册:如使用 AnnotatedBeanDefinitionReader |
使用场景 | @Component 、@Service 等自动扫描的 Bean | @Configuration 中的 @Bean 或编程式注册 |
是否立刻类加载 | ❌ 不加载类,只基于 MetadataReader 获取类信息 | ✅ 加载类,用 AnnotationMetadata.introspect 分析注解 |
性能 | ⭐ 高性能,适合大规模扫描 | ⛔ 稍慢,需要加载类 |
是否包含类注解元数据 | ✅ 是,使用 ASM 获取 | ✅ 是,使用反射获取 |
是否包含工厂方法元数据 | ❌ 永远为 null | ✅ 可包含 @Bean 等方法信息 |
是否设置 beanClass | ❌ 只设置 beanClassName(字符串) | ✅ 设置了实际 Class 对象 |
适用 Bean 类型 | 普通组件类(@Component ) | 组件类或配置类中的 @Bean 方法返回值 |
构造方式 | ScannedGenericBeanDefinition(MetadataReader) | AnnotatedGenericBeanDefinition(Class<?>) 或 AnnotatedGenericBeanDefinition(AnnotationMetadata) |
是否可用于 @Configuration 类 | ❌ 不适合 | ✅ 支持 |
是否支持 @Bean 工厂方法 | ❌ | ✅ 支持 getFactoryMethodMetadata() |
BeanDefinitionRegistry
BeanDefinitionRegistry
是用于向容器注册、删除、查询 BeanDefinition
的接口,是 Spring 容器构建阶段最核心的注册入口,继承自 AliasRegistry
,也支持别名管理。
// DefaultListableBeanFactory
public interface BeanDefinitionRegistry extends AliasRegistry {
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
boolean containsBeanDefinition(String beanName);
String[] getBeanDefinitionNames();
int getBeanDefinitionCount();
default boolean isBeanDefinitionOverridable(String beanName) {
return true;
}
boolean isBeanNameInUse(String beanName);
}
public interface AliasRegistry {
void registerAlias(String name, String alias);
void removeAlias(String alias);
boolean isAlias(String name);
String[] getAliases(String name);
}
BeanDefinitionReader
BeanDefinitionReader
是用于从指定资源中读取并加载 BeanDefinition
到 BeanDefinitionRegistry
的接口,是 Spring IoC 容器初始化过程中配置元数据解析的核心组件。
// XmlBeanDefinitionReader
public interface BeanDefinitionReader {
BeanDefinitionRegistry getRegistry();
@Nullable
ResourceLoader getResourceLoader();
@Nullable
ClassLoader getBeanClassLoader();
BeanNameGenerator getBeanNameGenerator();
int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;
int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;
int loadBeanDefinitions(String location) throws BeanDefinitionStoreException;
int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException;
}
实战
基于文件
配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- RootBeanDefinition 示例 -->
<bean id="rootBean" class="xyz.idoly.demo.RootService" scope="singleton" lazy-init="true"
depends-on="initHelper" autowire-candidate="true" primary="true"
init-method="init" destroy-method="cleanup">
<constructor-arg value="Root Constructor Arg"/>
<property name="name" value="Root Bean"/>
</bean>
<!-- ChildBeanDefinition 通过 parent 继承 rootBean 配置,覆盖部分属性 -->
<bean id="childBean" parent="rootBean" scope="prototype" lazy-init="false"
autowire-candidate="false" primary="false" init-method="childInit"
destroy-method="childDestroy">
<property name="name" value="Child Bean"/>
</bean>
<!-- GenericBeanDefinition 通用 bean 配置,使用工厂方法示范 -->
<bean id="genericBean" class="xyz.idoly.demo.GenericServiceFactory" factory-method="createService"
scope="singleton" depends-on="rootBean" lazy-init="false" autowire-candidate="true"
primary="false" init-method="setup" destroy-method="teardown">
<property name="description" value="Generic Bean from Factory"/>
</bean>
<!-- 依赖的辅助 Bean -->
<bean id="initHelper" class="xyz.idoly.demo.InitHelper" init-method="initialize" />
</beans>
代码
package xyz.idoly.demo;
// RootBeanDefinition 目标 Bean
public class RootService {
private String name;
private String constructorArg;
public RootService(String constructorArg) {
this.constructorArg = constructorArg;
}
public void setName(String name) {
this.name = name;
}
public void init() {
System.out.println("RootService init method called");
}
public void cleanup() {
System.out.println("RootService destroy method called");
}
@Override
public String toString() {
return "RootService[name=" + name + ", constructorArg=" + constructorArg + "]";
}
// ChildBeanDefinition特有的方法
public void childInit() {
System.out.println("ChildBean childInit method called");
}
public void childDestroy() {
System.out.println("ChildBean childDestroy method called");
}
}
// GenericBeanDefinition 使用工厂方法创建的目标 Bean
public class GenericService {
private String description;
public void setDescription(String description) {
this.description = description;
}
public void setup() {
System.out.println("GenericService setup called");
}
public void teardown() {
System.out.println("GenericService teardown called");
}
@Override
public String toString() {
return "GenericService[description=" + description + "]";
}
}
package xyz.idoly.demo;
// 工厂类示范
public class GenericServiceFactory {
public static GenericService createService() {
System.out.println("GenericServiceFactory.createService called");
return new GenericService();
}
}
public class InitHelper {
public void initialize() {
System.out.println("InitHelper initialized");
}
}
public class Application {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
RootService rootBean = (RootService) context.getBean("rootBean");
RootService childBean = (RootService) context.getBean("childBean");
GenericService genericBean = (GenericService) context.getBean("genericBean");
System.out.println(rootBean);
System.out.println(childBean);
System.out.println(genericBean);
context.registerShutdownHook(); // 销毁时调用 destroy-method
}
}
结果
PS D:\workspace\java\redis-demo> d:; cd 'd:\workspace\java\redis-demo'; & 'D:\plugins\jdk\bin\java.exe' '@C:\Users\idoly\AppData\Local\Temp\cp_3vwz0q7yixgsgf7cdq1n4wgmo.argfile' 'xyz.idoly.demo.Application'
InitHelper initialized
RootService init method called
GenericServiceFactory.createService called
GenericService setup called
ChildBean childInit method called
RootService[name=Root Bean, constructorArg=Root Constructor Arg]
RootService[name=Child Bean, constructorArg=Root Constructor Arg]
GenericService[description=Generic Bean from Factory]
GenericService teardown called
RootService destroy method called
基于注解
代码
package xyz.idoly.demo;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("rootService")
@Scope("singleton")
@Lazy
@Primary
public class RootService {
private final String constructorArg;
private String name;
// 构造器注入参数模拟
public RootService() {
this.constructorArg = "Root Constructor Arg";
}
public void setName(String name) {
this.name = name;
}
@PostConstruct
public void init() {
System.out.println("RootService @PostConstruct init called");
}
@PreDestroy
public void cleanup() {
System.out.println("RootService @PreDestroy cleanup called");
}
@Override
public String toString() {
return "RootService[name=" + name + ", constructorArg=" + constructorArg + "]";
}
public void childInit() {
System.out.println("RootService childInit method called");
}
public void childDestroy() {
System.out.println("RootService childDestroy method called");
}
}
package xyz.idoly.demo;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("childService")
@Scope("prototype")
public class ChildService extends RootService {
@Override
@PostConstruct
public void init() {
System.out.println("ChildService @PostConstruct init called");
}
@Override
@PreDestroy
public void cleanup() {
System.out.println("ChildService @PreDestroy cleanup called");
}
@Override
public String toString() {
return "ChildService extends " + super.toString();
}
}
package xyz.idoly.demo;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
public class GenericService {
private String description;
public void setDescription(String description) {
this.description = description;
}
@PostConstruct
public void setup() {
System.out.println("GenericService @PostConstruct setup called");
}
@PreDestroy
public void teardown() {
System.out.println("GenericService @PreDestroy teardown called");
}
@Override
public String toString() {
return "GenericService[description=" + description + "]";
}
}
package xyz.idoly.demo;
public class GenericServiceFactory {
public GenericService createService() {
System.out.println("GenericServiceFactory.createService called");
GenericService service = new GenericService();
service.setDescription("Created by factory method");
return service;
}
}
package xyz.idoly.demo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
@Configuration
public class AppConfig {
@Bean(initMethod = "setup", destroyMethod = "teardown")
@DependsOn("rootService")
public GenericService genericService() {
return new GenericServiceFactory().createService();
}
}
public class Application {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("xyz.idoly.demo");
RootService rootService = context.getBean("rootService", RootService.class);
ChildService childService = context.getBean("childService", ChildService.class);
GenericService genericService = context.getBean(GenericService.class);
rootService.setName("Root Bean Name");
System.out.println(rootService);
System.out.println(childService);
System.out.println(genericService);
context.registerShutdownHook();
}
}
结果
PS D:\workspace\java\redis-demo> d:; cd 'd:\workspace\java\redis-demo'; & 'D:\plugins\jdk\bin\java.exe' '@C:\Users\idoly\AppData\Local\Temp\cp_3vwz0q7yixgsgf7cdq1n4wgmo.argfile' 'xyz.idoly.demo.Application'
RootService @PostConstruct init called
GenericServiceFactory.createService called
GenericService @PostConstruct setup called
ChildService @PostConstruct init called
RootService[name=Root Bean Name, constructorArg=Root Constructor Arg]
ChildService extends RootService[name=null, constructorArg=Root Constructor Arg]
GenericService[description=Created by factory method]
GenericService @PreDestroy teardown called
RootService @PreDestroy cleanup called