一、SpringBoot Bean实例化概述
SpringBoot作为Spring框架的扩展,其核心优势之一在于自动配置和简化的Bean管理机制。Bean实例化作为Spring容器的核心功能,在SpringBoot中得到了进一步优化和自动化。理解SpringBoot Bean实例化的核心逻辑,不仅有助于深入掌握SpringBoot的工作原理,还能帮助开发者更好地进行应用开发和问题排查。
SpringBoot Bean实例化的过程涉及多个组件和阶段,包括Bean定义的加载、解析、注册,以及Bean的创建、依赖注入和初始化等。整个过程通过Spring的IoC容器实现,利用了Java的反射机制、注解处理和工厂模式等技术。
二、SpringBoot启动流程与Bean实例化的关系
SpringBoot的启动过程始于主类的main
方法,通过调用SpringApplication.run()
方法启动应用。这个过程中,SpringBoot会创建并配置Spring容器,加载Bean定义,最终实例化所有需要的Bean。
2.1 SpringApplication类的初始化
SpringApplication类是SpringBoot应用的核心入口点,其构造函数会执行一系列初始化操作:
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {// 设置资源加载器this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));// 推断应用类型(SERVLET、REACTIVE或NONE)this.webApplicationType = WebApplicationType.deduceFromClasspath();// 设置初始化器setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));// 设置监听器setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 推断主类this.mainApplicationClass = deduceMainApplicationClass();
}
2.2 SpringApplication.run()方法的执行流程
run()
方法是SpringBoot应用启动的核心方法,其执行流程包括:
public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();configureHeadlessProperty();// 获取并启动应用监听器SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting();try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);// 准备环境ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);configureIgnoreBeanInfo(environment);// 打印BannerBanner printedBanner = printBanner(environment);// 创建应用上下文context = createApplicationContext();exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,new Class[] { ConfigurableApplicationContext.class }, context);// 准备上下文prepareContext(context, environment, listeners, applicationArguments, printedBanner);// 刷新上下文refreshContext(context);// 刷新后的处理afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}// 发布应用就绪事件listeners.started(context);// 调用应用Runner和CommandLineRunnercallRunners(context, applicationArguments);}catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, listeners);throw new IllegalStateException(ex);}try {listeners.running(context);}catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, null);throw new IllegalStateException(ex);}return context;
}
三、Bean定义的加载与解析
Bean定义的加载与解析是Bean实例化的前置步骤,SpringBoot通过多种方式获取Bean定义信息。
3.1 BeanDefinitionReader的实现类
Spring提供了多种BeanDefinitionReader实现类,用于从不同来源加载Bean定义:
public interface BeanDefinitionReader {// 获取Bean定义注册器BeanDefinitionRegistry getRegistry();// 获取资源加载器@NullableResourceLoader getResourceLoader();// 获取类加载器@NullableClassLoader getClassLoader();// 获取Bean名称生成器BeanNameGenerator getBeanNameGenerator();// 从资源加载Bean定义int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;// 从多个资源加载Bean定义int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;// 从位置模式加载Bean定义int loadBeanDefinitions(String location) throws BeanDefinitionStoreException;// 从多个位置模式加载Bean定义int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException;
}
3.2 AnnotatedBeanDefinitionReader的工作原理
AnnotatedBeanDefinitionReader用于从注解中读取Bean定义:
public class AnnotatedBeanDefinitionReader {private final BeanDefinitionRegistry registry;private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();private ConditionEvaluator conditionEvaluator;public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {this(registry, getOrCreateEnvironment(registry));}public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");Assert.notNull(environment, "Environment must not be null");this.registry = registry;this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);// 注册注解配置处理器AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}// 注册一个或多个注解类public void register(Class<?>... componentClasses) {for (Class<?> componentClass : componentClasses) {registerBean(componentClass);}}// 注册单个注解类public void registerBean(Class<?> beanClass) {doRegisterBean(beanClass, null, null, null, null);}// 实际注册Bean的方法<T> void doRegisterBean(Class<T> beanClass, @Nullable String name,@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,@Nullable BeanDefinitionCustomizer[] customizers) {// 创建注解式Bean定义AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);// 评估条件注解if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}abd.setInstanceSupplier(supplier);// 解析作用域ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);abd.setScope(scopeMetadata.getScopeName());// 生成Bean名称String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));// 处理通用注解AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);// 处理限定符注解if (qualifiers != null) {for (Class<? extends Annotation> qualifier : qualifiers) {if (Primary.class == qualifier) {abd.setPrimary(true);}else if (Lazy.class == qualifier) {abd.setLazyInit(true);}else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));}}}// 应用自定义器if (customizers != null) {for (BeanDefinitionCustomizer customizer : customizers) {customizer.customize(abd);}}// 创建Bean定义持有者BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);// 应用作用域代理模式definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);// 注册Bean定义BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);}
}
四、BeanFactory与ApplicationContext
BeanFactory是Spring容器的核心接口,而ApplicationContext是其高级实现,提供了更多功能。
4.1 BeanFactory接口的定义
public interface BeanFactory {// 用于引用FactoryBean实例,而不是FactoryBean创建的beanString FACTORY_BEAN_PREFIX = "&";// 获取Bean实例Object getBean(String name) throws BeansException;<T> T getBean(String name, Class<T> requiredType) throws BeansException;Object getBean(String name, Object... args) throws BeansException;<T> T getBean(Class<T> requiredType) throws BeansException;<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;// 检查是否包含指定名称的Beanboolean containsBean(String name);// 判断Bean是否为单例boolean isSingleton(String name) throws NoSuchBeanDefinitionException;// 判断Bean是否为原型boolean isPrototype(String name) throws NoSuchBeanDefinitionException;// 判断Bean是否匹配指定类型boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;// 获取Bean的类型@NullableClass<?> getType(String name) throws NoSuchBeanDefinitionException;// 获取Bean的别名String[] getAliases(String name);
}
4.2 ApplicationContext的层次结构
ApplicationContext继承了多个接口,提供了更丰富的功能:
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver {// 返回此应用程序上下文的唯一IDString getId();// 返回此上下文所属的应用程序的名称String getApplicationName();// 返回此上下文的友好名称String getDisplayName();// 返回首次加载此上下文时的时间戳long getStartupDate();// 返回父上下文,如果没有则返回null@NullableApplicationContext getParent();// 暴露AutowireCapableBeanFactory功能AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
五、Bean的生命周期管理
Bean的生命周期包括实例化、依赖注入、初始化和销毁等阶段。
5.1 Bean生命周期的关键接口
Spring提供了多个接口来干预Bean的生命周期:
// BeanNameAware接口允许Bean获取自己在容器中的名称
public interface BeanNameAware extends Aware {void setBeanName(String name);
}// BeanFactoryAware接口允许Bean获取创建它的BeanFactory
public interface BeanFactoryAware extends Aware {void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}// ApplicationContextAware接口允许Bean获取应用上下文
public interface ApplicationContextAware extends Aware {void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}// InitializingBean接口允许Bean在属性设置后执行自定义初始化
public interface InitializingBean {void afterPropertiesSet() throws Exception;
}// DisposableBean接口允许Bean在容器销毁时执行自定义销毁逻辑
public interface DisposableBean {void destroy() throws Exception;
}
5.2 BeanPostProcessor接口
BeanPostProcessor允许在Bean初始化前后进行额外处理:
public interface BeanPostProcessor {// 在Bean初始化前调用@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}// 在Bean初始化后调用@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}
六、自动配置机制与Bean实例化
SpringBoot的自动配置是其核心特性之一,通过条件注解和自动配置类实现。
6.1 @EnableAutoConfiguration注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {// 用于禁用特定的自动配置类String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";// 排除特定的自动配置类Class<?>[] exclude() default {};// 按名称排除特定的自动配置类String[] excludeName() default {};
}
6.2 AutoConfigurationImportSelector类
AutoConfigurationImportSelector负责加载自动配置类:
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {// 选择要导入的自动配置类@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}// 获取自动配置元数据AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);// 获取自动配置类的导入候选者AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}// 获取自动配置入口protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY;}// 获取注解属性AnnotationAttributes attributes = getAttributes(annotationMetadata);// 获取候选配置类List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);// 移除重复的配置类configurations = removeDuplicates(configurations);// 获取需要排除的配置类Set<String> exclusions = getExclusions(annotationMetadata, attributes);// 检查排除的配置类checkExcludedClasses(configurations, exclusions);// 移除需要排除的配置类configurations.removeAll(exclusions);// 应用自动配置导入过滤器configurations = filter(configurations, autoConfigurationMetadata);// 发布自动配置导入事件fireAutoConfigurationImportEvents(configurations, exclusions);return new AutoConfigurationEntry(configurations, exclusions);}// 获取候选配置类protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {// 从META-INF/spring.factories加载自动配置类List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader());Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "+ "are using a custom packaging, make sure that file is correct.");return configurations;}// 获取Spring工厂加载器的工厂类protected Class<?> getSpringFactoriesLoaderFactoryClass() {return EnableAutoConfiguration.class;}
}
七、条件注解与Bean实例化控制
SpringBoot提供了多种条件注解,用于控制Bean的实例化。
7.1 @Conditional注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Conditionals.class)
public @interface Conditional {// 指定条件类,必须实现Condition接口Class<? extends Condition>[] value();
}
7.2 常用条件注解实现
SpringBoot提供了多个常用的条件注解:
// 基于类是否存在的条件注解
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)
public @interface ConditionalOnClass {Class<?>[] value() default {};String[] name() default {};
}// 基于Bean是否存在的条件注解
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnBeanCondition.class)
public @interface ConditionalOnBean {Class<?>[] value() default {};String[] type() default {};String[] name() default {};SearchStrategy search() default SearchStrategy.ALL;
}// 基于属性的条件注解
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnPropertyCondition.class)
public @interface ConditionalOnProperty {String[] value() default {};String prefix() default "";String[] name() default {};String havingValue() default "";boolean matchIfMissing() default false;boolean relaxedNames() default true;
}// 基于资源是否存在的条件注解
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnResourceCondition.class)
public @interface ConditionalOnResource {String[] resources() default {};
}
八、依赖注入与循环依赖处理
依赖注入是Spring的核心特性之一,SpringBoot在这方面提供了强大支持。
8.1 依赖注入的实现方式
Spring支持多种依赖注入方式:
// 构造函数注入
public class MyService {private final MyRepository repository;// 通过构造函数注入依赖public MyService(MyRepository repository) {this.repository = repository;}// 使用注入的依赖public void doSomething() {repository.saveData("test");}
}// Setter方法注入
public class MyService {private MyRepository repository;// 通过Setter方法注入依赖public void setRepository(MyRepository repository) {this.repository = repository;}// 使用注入的依赖public void doSomething() {repository.saveData("test");}
}// 字段注入
public class MyService {// 通过字段注入依赖@Autowiredprivate MyRepository repository;// 使用注入的依赖public void doSomething() {repository.saveData("test");}
}
8.2 循环依赖的处理机制
Spring通过三级缓存来处理循环依赖:
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {// 一级缓存:存储完全初始化的单例Beanprivate final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);// 二级缓存:存储提前暴露的单例Bean(未完全初始化)private final Map<String, Object> singletonFactories = new HashMap<>(16);// 三级缓存:存储单例工厂private final Map<String, ObjectFactory<?>> earlySingletonObjects = new HashMap<>(16);// 正在创建的单例Bean名称集合private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));// 获取单例Bean@Override@Nullablepublic Object getSingleton(String beanName) {return getSingleton(beanName, true);}// 获取单例Bean的核心方法@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {// 从一级缓存中获取Object singletonObject = this.singletonObjects.get(beanName);// 如果一级缓存中没有且正在创建中if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {// 从二级缓存中获取singletonObject = this.earlySingletonObjects.get(beanName);// 如果二级缓存中没有且允许提前引用if (singletonObject == null && allowEarlyReference) {// 从三级缓存中获取单例工厂ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {// 通过单例工厂获取提前暴露的BeansingletonObject = singletonFactory.getObject();// 将Bean放入二级缓存this.earlySingletonObjects.put(beanName, singletonObject);// 从三级缓存中移除this.singletonFactories.remove(beanName);}}}}return singletonObject;}// 创建单例Beanpublic Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name must not be null");synchronized (this.singletonObjects) {// 检查一级缓存Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {// 检查是否在销毁中if (this.singletonsCurrentlyInDestruction) {throw new BeanCreationNotAllowedException(beanName,"Singleton bean creation not allowed while singletons of this factory are in destruction " +"(Do not request a bean from a BeanFactory in a destroy method implementation!)");}if (logger.isDebugEnabled()) {logger.debug("Creating shared instance of singleton bean '" + beanName + "'");}// 标记为正在创建beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();}try {// 通过工厂创建BeansingletonObject = singletonFactory.getObject();newSingleton = true;}catch (IllegalStateException ex) {// 可能是循环依赖导致的异常singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {throw ex;}}catch (BeanCreationException ex) {if (recordSuppressedExceptions) {for (Exception suppressedException : this.suppressedExceptions) {ex.addRelatedCause(suppressedException);}}throw ex;}finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}// 标记创建完成afterSingletonCreation(beanName);}if (newSingleton) {// 将创建好的Bean添加到一级缓存addSingleton(beanName, singletonObject);}}return singletonObject;}}// 添加单例Bean到缓存protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {// 添加到一级缓存this.singletonObjects.put(beanName, singletonObject);// 从三级缓存移除this.singletonFactories.remove(beanName);// 从二级缓存移除this.earlySingletonObjects.remove(beanName);// 添加到已注册的单例集合this.registeredSingletons.add(beanName);}}// 添加单例工厂到缓存protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(singletonFactory, "Singleton factory must not be null");synchronized (this.singletonObjects) {// 如果一级缓存中没有该Beanif (!this.singletonObjects.containsKey(beanName)) {// 添加到三级缓存this.singletonFactories.put(beanName, singletonFactory);// 从二级缓存移除this.earlySingletonObjects.remove(beanName);// 添加到已注册的单例集合this.registeredSingletons.add(beanName);}}}
}
九、BeanPostProcessor与AOP代理创建
BeanPostProcessor在Bean实例化过程中扮演重要角色,特别是在AOP代理创建方面。
9.1 BeanPostProcessor的执行时机
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactoryimplements AutowireCapableBeanFactory {// 创建Bean的核心方法@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// 省略部分代码...try {// 解析Bean的实例化前处理Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}try {// 实际创建Bean实例Object beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {// 直接抛出异常throw ex;}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}}// 实际创建Bean实例protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// 创建Bean实例BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {// 创建Bean实例instanceWrapper = createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// 处理合并的Bean定义synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {// 应用MergedBeanDefinitionPostProcessorapplyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}}// 处理循环依赖:提前暴露单例Beanboolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}// 添加单例工厂到三级缓存addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// 初始化Bean实例Object exposedObject = bean;try {// 填充Bean属性populateBean(beanName, mbd, instanceWrapper);// 调用初始化方法和BeanPostProcessorexposedObject = initializeBean(beanName, exposedObject, mbd);}catch (Throwable ex) {if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);}}// 处理循环依赖和代理if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +"] in its raw version as part of a circular reference, but has eventually been " +"wrapped. This means that said other beans do not use the final version of the " +"bean. This is often the result of over-eager type matching - consider using " +"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");}}}}// 注册销毁回调try {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;}// 初始化Beanprotected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {// 调用Aware接口方法invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {// 应用初始化前的BeanPostProcessorwrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {// 调用初始化方法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()) {// 应用初始化后的BeanPostProcessorwrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}// 应用初始化前的BeanPostProcessor@Overridepublic 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@Overridepublic Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessAfterInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;}
}
9.2 AOP代理的创建过程
Spring AOP代理的创建主要通过AbstractAutoProxyCreator
类实现:
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupportimplements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {// Bean实例化前的处理@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {Object cacheKey = getCacheKey(beanClass, beanName);if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {if (this.advisedBeans.containsKey(cacheKey)) {return null;}if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return null;}}// 如果有自定义TargetSource,创建代理TargetSource targetSource = getCustomTargetSource(beanClass, beanName);if (targetSource != null) {if (StringUtils.hasLength(beanName)) {this.targetSourcedBeans.add(beanName);}Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}return null;}// Bean实例化后的处理@Overridepublic boolean postProcessAfterInitialization(@Nullable Object bean, String beanName) {if (bean != null) {Object cacheKey = getCacheKey(bean.getClass(), beanName);if (this.earlyProxyReferences.remove(cacheKey) != bean) {return wrapIfNecessary(bean, beanName, cacheKey);}}return true;}// 如果需要则包装Bean为代理protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {return bean;}if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {return bean;}if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}// 获取适用的增强和AdvisorObject[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);if (specificInterceptors != DO_NOT_PROXY) {this.advisedBeans.put(cacheKey, Boolean.TRUE);// 创建代理Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}// 创建代理protected Object createProxy(Class<?> beanClass, @Nullable String beanName,@Nullable Object[] specificInterceptors, TargetSource targetSource) {if (this.beanFactory instanceof ConfigurableListableBeanFactory) {AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);}// 创建代理工厂ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.copyFrom(this);if (!proxyFactory.isProxyTargetClass()) {if (shouldProxyTargetClass(beanClass, beanName)) {proxyFactory.setProxyTargetClass(true);}else {evaluateProxyInterfaces(beanClass, proxyFactory);}}// 获取增强和Advisor并添加到代理工厂Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);for (Advisor advisor : advisors) {proxyFactory.addAdvisor(advisor);}// 设置TargetSourceproxyFactory.setTargetSource(targetSource);// 自定义代理工厂customizeProxyFactory(proxyFactory);proxyFactory.setFrozen(this.freezeProxy);if (advisorsPreFiltered()) {proxyFactory.setPreFiltered(true);}// 创建代理return proxyFactory.getProxy(getProxyClassLoader());}
}
十、Scope与Bean的作用域管理
Spring支持多种Bean作用域,包括单例、原型、请求、会话等。
10.1 Scope接口定义
public interface Scope {// 从作用域中获取BeanObject get(String name, ObjectFactory<?> objectFactory);// 从作用域中移除Bean@NullableObject remove(String name);// 注册销毁回调void registerDestructionCallback(String name, Runnable callback);// 解析上下文对象@NullableObject resolveContextualObject(String key);// 获取会话ID@NullableString getConversationId();
}
10.2 单例作用域实现
public class SingletonScope implements Scope {private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);@Overridepublic Object get(String name, ObjectFactory<?> objectFactory) {synchronized (this.singletonObjects) {Object singletonObject = this.singletonObjects.get(name);if (singletonObject == null) {singletonObject = objectFactory.getObject();this.singletonObjects.put(name, singletonObject);}return singletonObject;}}@Overridepublic Object remove(String name) {synchronized (this.singletonObjects) {return this.singletonObjects.remove(name);}}@Overridepublic void registerDestructionCallback(String name, Runnable callback) {// 单例作用域的销毁由容器统一管理}@Overridepublic Object resolveContextualObject(String key) {return null;}@Overridepublic String getConversationId() {return null;}
}
10.3 原型作用域实现
public class PrototypeScope implements Scope {@Overridepublic Object get(String name, ObjectFactory<?> objectFactory) {// 每次都创建新实例return objectFactory.getObject();}@Overridepublic Object remove(String name) {// 原型作用域不跟踪实例,因此无法移除return null;}@Overridepublic void registerDestructionCallback(String name, Runnable callback) {// 原型作用域不管理销毁回调}@Overridepublic Object resolveContextualObject(String key) {return null;}@Overridepublic String getConversationId() {return null;}
}
十一、Lazy初始化与条件加载
SpringBoot支持延迟初始化Bean,提高应用启动性能。
11.1 @Lazy注解
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Lazy {// 是否延迟初始化boolean value() default true;
}
11.2 延迟初始化的实现原理
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactoryimplements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {// 处理延迟初始化@Overridepublic void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// 获取所有Bean定义名称List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// 触发所有非延迟单例Bean的初始化for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);// 检查是否为非抽象、单例且非延迟初始化的Beanif (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {// 检查是否为FactoryBeanif (isFactoryBean(beanName)) {// 处理FactoryBeanObject bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof FactoryBean) {final FactoryBean<?> factory = (FactoryBean<?>) bean;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) {getBean(beanName);}}}else {// 普通Bean直接初始化getBean(beanName);}}}// 触发所有SmartInitializingSingleton Bean的初始化后回调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();}}}}
}
十二、自定义Bean实例化策略
Spring允许通过自定义InstantiationStrategy接口实现来自定义Bean实例化过程。
12.1 InstantiationStrategy接口
public interface InstantiationStrategy {// 实例化BeanObject instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)throws BeansException;// 使用构造函数实例化BeanObject instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,Constructor<?> ctor, Object... args) throws BeansException;// 使用工厂方法实例化BeanObject instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,@Nullable Object factoryBean, Method factoryMethod, Object... args) throws BeansException;
}
12.2 SimpleInstantiationStrategy实现
public class SimpleInstantiationStrategy implements InstantiationStrategy {// 默认的实例化策略@Overridepublic Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {// 检查是否有方法覆盖if (!bd.hasMethodOverrides()) {Constructor<?> constructorToUse;synchronized (bd.constructorArgumentLock) {constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;if (constructorToUse == null) {final Class<?> clazz = bd.getBeanClass();if (clazz.isInterface()) {throw new BeanInstantiationException(clazz, "Specified class is an interface");}try {if (System.getSecurityManager() != null) {constructorToUse = AccessController.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);}else {constructorToUse = clazz.getDeclaredConstructor();}bd.resolvedConstructorOrFactoryMethod = constructorToUse;}catch (Throwable ex) {throw new BeanInstantiationException(clazz, "No default constructor found", ex);}}}// 使用反射实例化return BeanUtils.instantiateClass(constructorToUse);}else {// 对于有方法覆盖的情况,使用CGLIB实例化return instantiateWithMethodInjection(bd, beanName, owner);}}// 使用方法注入实例化protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");}// 使用构造函数实例化@Overridepublic Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,Constructor<?> ctor, Object... args) {if (!bd.hasMethodOverrides()) {// 没有方法覆盖,直接使用构造函数实例化return BeanUtils.instantiateClass(ctor, args);}else {// 有方法覆盖,使用CGLIB实例化return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);}}// 使用方法注入和构造函数实例化protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName,BeanFactory owner, @Nullable Constructor<?> ctor, Object... args) {throw new UnsupportedOperationException("Method Injection not supported in SimpleInstantiationStrategy");}// 使用工厂方法实例化@Overridepublic Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,@Nullable Object factoryBean, Method factoryMethod, Object... args) {try {// 使用反射调用工厂方法ReflectionUtils.makeAccessible(factoryMethod);if (System.getSecurityManager() != null) {return AccessController.doPrivileged((PrivilegedAction<Object>) () ->ReflectionUtils.invokeMethod(factoryMethod, factoryBean, args),getAccessControlContext());}else {return ReflectionUtils.invokeMethod(factoryMethod, factoryBean, args);}}catch (InvocationTargetException ex) {throw new BeanInstantiationException(factoryMethod, "Factory method threw exception", ex.getTargetException());}catch (Throwable ex) {throw new BeanInstantiationException(factoryMethod, "Illegal arguments to factory method", ex);}}
}
十三、Bean实例化中的事件与监听器
Spring通过事件机制允许在Bean实例化的不同阶段执行自定义逻辑。
13.1 核心事件接口
public interface ApplicationEvent extends EventObject {// 返回事件发生的时间戳long getTimestamp();
}public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {// 处理应用事件void onApplicationEvent(E event);
}
13.2 主要的应用事件
// 应用启动事件
public class ApplicationStartingEvent extends ApplicationEvent {public ApplicationStartingEvent(SpringApplication application, String[] args) {super(application);}public SpringApplication getSpringApplication() {return (SpringApplication) getSource();}public String[] getArgs() {return getSpringApplication().getArgs();}
}// 应用环境准备事件
public class ApplicationEnvironmentPreparedEvent extends ApplicationEvent {public ApplicationEnvironmentPreparedEvent(SpringApplication application, String[] args,ConfigurableEnvironment environment) {super(application);this.args = args;this.environment = environment;}public SpringApplication getSpringApplication() {return (SpringApplication) getSource();}public String[] getArgs() {return this.args;}public ConfigurableEnvironment getEnvironment() {return this.environment;}
}// 应用上下文准备事件
public class ApplicationContextInitializedEvent extends ApplicationEvent {public ApplicationContextInitializedEvent(SpringApplication application, String[] args,ConfigurableApplicationContext context) {super(application);this.args = args;this.context = context;}public SpringApplication getSpringApplication() {return (SpringApplication) getSource();}public String[] getArgs() {return this.args;}public ConfigurableApplicationContext getApplicationContext() {return this.context;}
}// 应用上下文刷新事件
public class ApplicationContextEvent extends ApplicationEvent {public ApplicationContextEvent(ApplicationContext source) {super(source);}public final ApplicationContext getApplicationContext() {return (ApplicationContext) getSource();}
}// 应用就绪事件
public class ApplicationReadyEvent extends ApplicationContextEvent {public ApplicationReadyEvent(ConfigurableApplicationContext context,ApplicationArguments args, SpringApplication application) {super(context);this.args = args;this.application = application;}public ApplicationArguments getArgs() {return this.args;}public SpringApplication getSpringApplication() {return this.application;}
}// 应用失败事件
public class ApplicationFailedEvent extends ApplicationEvent {public ApplicationFailedEvent(SpringApplication application, String[] args,ConfigurableApplicationContext context, Throwable exception) {super(application);this.args = args;this.context = context;this.exception = exception;}public SpringApplication getSpringApplication() {return (SpringApplication) getSource();}public String[] getArgs() {return this.args;}@Nullablepublic ConfigurableApplicationContext getApplicationContext() {return this.context;}public Throwable getException() {return this.exception;}
}
十四、Bean实例化中的错误处理与调试
Spring提供了完善的错误处理机制,帮助开发者快速定位和解决问题。
14.1 主要异常类
// Bean相关异常的基类
public abstract class BeansException extends NestedRuntimeException {public BeansException(String msg) {super(msg);}public BeansException(String msg, Throwable cause) {super(msg, cause);}
}// 找不到Bean定义的异常
public class NoSuchBeanDefinitionException extends BeansException {public NoSuchBeanDefinitionException(String name) {super("No bean named '" + name + "' available");this.beanName = name;}public NoSuchBeanDefinitionException(String name, String message) {super("No bean named '" + name + "' available: " + message);this.beanName = name;}public NoSuchBeanDefinitionException(Class<?> type) {super("No qualifying bean of type '" + type.getName() + "' available");this.beanType = type;}public NoSuchBeanDefinitionException(Class<?> type, String message) {super("No qualifying bean of type '" + type.getName() + "' available: " + message);this.beanType = type;}
}// Bean创建异常
public class BeanCreationException extends BeansException {public BeanCreationException(String msg) {super(msg);}public BeanCreationException(String msg, Throwable cause) {super(msg, cause);}public BeanCreationException(String beanName, String msg) {super("Error creating bean with name '" + beanName + "': " + msg);this.beanName = beanName;}public BeanCreationException(String beanName, String msg, Throwable cause) {super("Error creating bean with name '" + beanName + "': " + msg, cause);this.beanName = beanName;}public BeanCreationException(String resourceDescription, String beanName, String msg) {super("Error creating bean with name '" + beanName + "'" +(resourceDescription != null ? " defined in " + resourceDescription : "") + ": " + msg);this.resourceDescription = resourceDescription;this.beanName = beanName;}public BeanCreationException(String resourceDescription, String beanName, String msg, Throwable cause) {super("Error creating bean with name '" + beanName + "'" +(resourceDescription != null ? " defined in " + resourceDescription : "") + ": " + msg, cause);this.resourceDescription = resourceDescription;this.beanName = beanName;}
}// Bean循环依赖异常
public class BeanCurrentlyInCreationException extends BeanCreationException {public BeanCurrentlyInCreationException(String beanName) {super(beanName,"Requested bean is currently in creation: Is there an unresolvable circular reference?");}public BeanCurrentlyInCreationException(String beanName, String msg) {super(beanName, msg);}
}
14.2 调试工具与技巧
- 使用调试模式启动应用,设置断点跟踪Bean实例化过程
- 启用DEBUG日志级别:
logging.level.org.springframework.beans.factory=DEBUG
- 使用Spring提供的BeanPostProcessor检查Bean创建过程
- 使用
@PostConstruct
和@PreDestroy
注解调试生命周期方法 - 使用Spring Boot Actuator的beans端点查看Bean定义和依赖关系
十五、SpringBoot Bean实例化的最佳实践
- 优先使用构造函数注入,确保依赖不可变且明确
- 合理使用@Lazy注解,延迟初始化非关键Bean,提高应用启动速度
- 利用@Conditional系列注解,根据条件动态控制Bean的创建
- 遵循单一职责原则,保持Bean的功能简洁明确
- 使用@ConfigurationProperties注解集中管理配置属性
- 合理使用@Scope注解,根据业务需求选择合适的作用域
- 避免循环依赖,重构代码设计以消除循环依赖
- 使用@Primary和@Qualifier注解解决依赖注入的歧义
- 利用Spring的事件机制,在Bean生命周期的关键节点添加自定义逻辑
- 编写单元测试和集成测试,确保Bean的正确性和稳定性