🤡 IoC & DI
2022年6月20日
- frame
🤡 IoC & DI
- IoC
- 由 Spring 容器控制对象的生命周期 & 对象间的关系
- 当我们需要某个对象时,需要从
BeanFactory
&ApplicationContext
容器 中获取 - 优点是:解耦
- DI
- 容器在实例化对象时,将它依赖的类注入给它
- 为什么要有 IoC & DI?
- 实现 解耦
- 硬编码会造成对象间的过度耦合,使用 IoC 后,我们可以不用关心对象间的依赖,专心开发业务
基于 SpringBoot 2.x
1. ManageApplication 启动类
package com.manage;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ManageApplication {
public static void main(String[] args) {
SpringApplication.run(ManageApplication.class, args);
}
}
2. SpringApplication.run(args)
public class SpringApplication {
// ...
// 属性
private Set<Class<?>> primarySources;
private Set<String> sources;
private Class<?> mainApplicationClass;
private Mode bannerMode;
private boolean logStartupInfo;
private boolean addCommandLineProperties;
private boolean addConversionService;
private Banner banner;
private ResourceLoader resourceLoader;
private BeanNameGenerator beanNameGenerator;
private ConfigurableEnvironment environment;
private WebApplicationType webApplicationType;
private boolean headless;
private boolean registerShutdownHook;
private List<ApplicationContextInitializer<?>> initializers;
private List<ApplicationListener<?>> listeners;
private Map<String, Object> defaultProperties;
private List<BootstrapRegistryInitializer> bootstrapRegistryInitializers;
private Set<String> additionalProfiles;
private boolean allowBeanDefinitionOverriding;
private boolean isCustomEnvironment;
private boolean lazyInitialization;
private String environmentPrefix;
private ApplicationContextFactory applicationContextFactory;
private ApplicationStartup applicationStartup;
// 构造函数
public SpringApplication(Class<?>... primarySources) {
this((ResourceLoader)null, primarySources);
}
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
// 属性赋初值
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = Collections.emptySet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
this.applicationStartup = ApplicationStartup.DEFAULT;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
// 1) 判断应用程序类型,分为 Servlet, Reactive, None 三种枚举类型
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 2) 从 SpringFactories 加载 初始化器
this.bootstrapRegistryInitializers = this.getBootstrapRegistryInitializersFromSpringFactories();
// 3) 设置 应用上下文初始化器
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 4) 设置 应用上下文监听器
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
// 5) 找到 main 方法,设置为 运行的主类
this.mainApplicationClass = this.deduceMainApplicationClass();
}
// run() 方法
public ConfigurableApplicationContext run(String... args) {
// 1. 启动计时器
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// 2. 系统属性设置
DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
ConfigurableApplicationContext context = null;
this.configureHeadlessProperty();
// 3. 初始化监视器并启动,发布 ApplicationStartedEvent 事件
// 1) 获取所有 监视器
SpringApplicationRunListeners listeners = this.getRunListeners(args);
// 2) starting 函数 - 执行 multicastEvent 方法,唤醒所有的 事件监听器
// multicastEvent 方法 会执行 invokeListener 方法
// 会执行 invokeListener 方法 会 调用 listener.onApplicationEvent(event),只要事件监听器重写了该方法,那么就会执行 具体事件
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
// 4. 环境配置,发布 ApplicationEnvironmentPreparedEvent 事件
// 在这一步中,会触发相关监视器 ConfigFileApplicationListener,加载 properties & yml 文件
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
this.configureIgnoreBeanInfo(environment);
// 5. 打印 banner
Banner printedBanner = this.printBanner(environment);
// 6. 创建 ApplicationContext
context = this.createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
// 7. 上下文 前置处理,装配 Context 的环境变量等
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 8. 刷新 上下文 - 继续进入
this.refreshContext(context);
// 9. 上下文刷新的后置处理
this.afterRefresh(context, applicationArguments);
// 10. 计时器 结束
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
// 11. 将 上下文 事件 发布 AvailabilityChangeEvent.publish(context, LivenessState.CORRECT)
listeners.started(context);
// 12. 执行 runner 运行器运行
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, listeners);
throw new IllegalStateException(var10);
}
try {
// 13. 事件发布 AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC)
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
}
3. refreshContext(context)
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
// ......
@Override
public void refresh() throws BeansException, IllegalStateException {
// 加锁,保证线程安全
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 1.准备工作
// 记录下容器的启动时间、
// 标记“已启动”状态,关闭状态为false、
// 加载当前系统属性到环境对象中
// 准备一系列监听器以及事件集合对象
prepareRefresh();
// 2. 创建容器对象:DefaultListableBeanFactory,加载 XML 配置文件的属性到当前的工厂中(默认用命名空间来解析),
// 就是上面说的BeanDefinition(bean的定义信息)这里还没有初始化,只是配置信息都提取出来了,(包含里面的value值其实都只是占位符)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. BeanFactory的准备工作,设置BeanFactory的类加载器,添加几个BeanPostProcessor,手动注册几个特殊的bean等
prepareBeanFactory(beanFactory);
try {
// 4. 若 bean 实现了该方法,那么在 bean 被加载、注册,初始化之前,会被调用该方法,进行一些自定义操作
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 5. 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
// 在这一步中,会将 @Value 注解需要的属性值从 properties 文件获取进行赋值
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 注册 BeanPostProcessor 处理器 这里只是注册功能,真正的调用的是getBean方法
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 7.初始化当前 ApplicationContext 的 MessageSource,即国际化处理
initMessageSource();
// 8.初始化当前 ApplicationContext 的事件广播器,
initApplicationEventMulticaster();
// 9. 钩子方法,重写该方法以在这里初始化一些特殊的 Bean(发生在在初始化 singleton beans 之前)
onRefresh();
// 10. 注册事件监听器,监听器需要实现 ApplicationListener 接口
registerListeners();
// 11. 初始化所有的 不允许懒加载的 剩余的 singleton beans -
finishBeanFactoryInitialization(beanFactory);
// 12. 广播事件,ApplicationContext 初始化完成
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
// 初始化剩余的 singleton beans
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// 实例化所有剩余的 & 不是懒加载的单例 bean - 继续跟入
beanFactory.preInstantiateSingletons();
}
}
4. preInstantiateSingletons()
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
// .......
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Pre-instantiating singletons in " + this);
}
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
while(true) {
String beanName;
Object bean;
do {
while(true) {
RootBeanDefinition bd;
do {
do {
do {
if (!var2.hasNext()) { // 不存在后续节点
var2 = beanNames.iterator();
while(var2.hasNext()) {
beanName = (String)var2.next();
Object singletonInstance = this.getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
return;
}
// 存在下一个节点
beanName = (String)var2.next();
// 合并父 Bean 中的配置,例如 <bean id="" class="" parent="" /> 中的 parent
bd = this.getMergedLocalBeanDefinition(beanName);
} while(bd.isAbstract()); // 非抽象
} while(!bd.isSingleton()); // 单例
} while(bd.isLazyInit()); // 非懒加载 - isLazyInit 是 bd 类的一个 boolean 属性
// 通过 FactoryBean 实现的复杂 bean,在 beanName 前面加上 ‘&’ 符号。再调用 getBean
if (this.isFactoryBean(beanName)) {
bean = this.getBean("&" + beanName);
break;
}
// 对于普通的 Bean,只要调用 getBean(beanName) - 继续跟入
this.getBean(beanName);
}
} while(!(bean instanceof FactoryBean));
FactoryBean<?> factory = (FactoryBean)bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
SmartFactoryBean var10000 = (SmartFactoryBean)factory;
((SmartFactoryBean)factory).getClass();
isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
}
}
5. getBean(String name)
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
// ......
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
/**
* Return an instance, which may be shared or independent, of the specified bean.
* @param name 要获取的 bean 的名称
* @param requiredType 要获取的 bean 指定的所属类型
* @param args arguments to use when creating a bean instance using explicit arguments
* (only applied when creating a new instance as opposed to retrieving an existing one)
* @param typeCheckOnly 拥有的实例是否有类型检查
* @return an instance of the bean
* @throws BeansException if the bean could not be created
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
String name,
@Nullable Class<T> requiredType,
@Nullable Object[] args,
boolean typeCheckOnly) throws BeansException {
// 将传入的 bean 名称进行一些转换,如果有特殊的名称,例如 FactoryBean(前面带 ‘&’) 等
String beanName = transformedBeanName(name);
Object beanInstance;
// 判断该 bean 是否已经创建过 - 三级缓存模型获取 单例bean
Object sharedInstance = getSingleton(beanName);
// 已经创建过,则返回
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 如果是 FactoryBean ,返回 factory.getObject() 方法生成的 类对象; 普通 Bean ,直接返回 sharedInstance
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 没有创建过该 bean
// 若该 bean 已经创建了 Prototype 类型,抛异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 检查一下这个 BeanDefinition 在容器中是否存在
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
} else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
} else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
} else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 初始化 该 bean 依赖的所有 bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 依赖的 bean 之间不允许出现循环依赖问题
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep); // 初始化依赖项
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 如果是 singleton scope 的,创建 singleton 的实例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
// 该方法如果发现是 FactoryBean,则会调用 FactoryBean.getObject() 方法得到 bean
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 如果是 prototype scope 的,创建 prototype 的实例
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// // 如果不是 singleton 和 prototype 的话,需要委托给相应的实现类来处理
else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
}
}
return adaptBeanInstance(name, beanInstance, requiredType);
}
}
6. createBean & doCreateBean
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
// 日志打印
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 判断方法是否被重写过
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(
mbdToUse.getResourceDescription(),
beanName,
"Validation of method overrides failed",
ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
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 {
Object beanInstance = doCreateBean(beanName, mbdToUse, args); // 创建 bean,继续进入
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
/**
* 主要包含以下步骤:
* 1. 实例化,创建 bean 实例
* 1.1 实例化完成后,如果满足 提前暴露 条件,需要将该 bean 放入 三级缓存
* 2. 填充属性
* 3. bean 初始化
*/
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
// 1. 实例化 bean
BeanWrapper instanceWrapper = null;
// 如果是单例模式,从 factoryBeanInstanceCache 缓存中获取 BeanWrapper 实例对象并删除缓存
if (mbd.isSingleton()) {
// 如果是 factoryBean,这里 instanceWrapper 会被赋值 != null
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 非 factoryBean,实例化 bean
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 后置处理
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// ------ 解决循环依赖问题 -----------
// 判断是否可以提前暴露
boolean 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");
}
// 将该 bean 放入 三级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 属性填充 & 初始化 bean
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper); // 填充属性
exposedObject = initializeBean(beanName, exposedObject, mbd); // 初始化 bean 实例对象
} 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.");
}
}
}
}
// 注册 bean 的销毁方法
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
// 属性填充 - 依赖注入
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
//1. 校验实例
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
/*
* 2. 在设置属性之前给 InstantiationAwareBeanPostProcessors 最后一次改变 bean 的机会。
* 关于这段后置引用,官方的解释是:让用户可以自定义属性注入。比如用户实现一
* 个 InstantiationAwareBeanPostProcessor 类型的后置处理器,并通过
* postProcessAfterInstantiation 方法向 bean 的成员变量注入自定义的信息。当然,如果无
* 特殊需求,直接使用配置中的信息注入即可。另外,Spring 并不建议大家直接实现
* InstantiationAwareBeanPostProcessor 接口,如果想实现这种类型的后置处理器,更建议
* 通过继承 InstantiationAwareBeanPostProcessorAdapter 抽象类实现自定义后置处理器。
*/
boolean continueWithPropertyPopulation = true;
// bean 不是"合成"的,即未由应用程序本身定义 && 持有 InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 遍历所有的 BeanPostProcessors
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 返回值为是否继续填充 bean
// postProcessAfterInstantiation:如果应该在 bean上面设置属性则返回 true,否则返回 false
// 一般情况下,应该是返回true 。
// 返回 false 的话,将会阻止在此 Bean 实例上调用任何后续的 InstantiationAwareBeanPostProcessor 实例。
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 如果后置处理器发出停止填充命令,则终止后续操作
if (!continueWithPropertyPopulation) {
return;
}
// 3. 获取Bean的属性值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 3.1 xml方式 即xml中<beans>节点中的 default-autowire 属性
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
// 将 PropertyValues 封装成 MutablePropertyValues 对象
// MutablePropertyValues 允许对属性进行简单的操作,并提供构造函数以支持Map的深度复制和构造。
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//根据 Bean 名称 进行 自动装配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
//根据 Bean类型 进行 自动装配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 是否已经注册了 InstantiationAwareBeanPostProcessors
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//是否需要依赖检查(xml)
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
// 3.2 注解方式
if (hasInstAwareBpps || needsDepCheck) { // 已经注册 InstantiationAwareBeanPostProcessors || 需要依赖检查
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 具体处理属性注入(注解方式)- 例,@Value()、@Resource、@Autowire
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
//依赖检查 (xml)
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
//对属性进行注入 (xml)
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
//
// 初始化 bean -- 见下
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// ....
}
}
7. initializeBean()
补充
1) BeanFactory
① 类图
ListableBeanFactory
:可以获取多个 BeanHierarchicalBeanFactory
:可以在应用中起多个 BeanFactory,然后可以将各个 BeanFactory 设置为父子关系BeanFactory
:获取单个 BeanAutowireCapableBeanFactory
:自动装配 Bean,ApplicationContext 虽没有继承它,但通过 getAutowireCapableBeanFactory() 组合了它ConfigurableBeanFactory
:单例bean的注册以及生成实例,统计单例bean等信息ConfigurableListableBeanFactory
:增加了一些其他功能:类加载器、类型转化、属性编辑器、BeanPostProcessor、bean定义、处理bean依赖关系、 bean如何销毁等等一些还有其他的功能DefaultListableBeanFactory
:实现BeanFactory
所有功能同时也能注册BeanDefinition
② 补充
- BeanFactory 采用 延迟加载 方式,只有使用 Bean 时才会进行实例化
- Spring 为 BeanFactory 提供了多种实现,常见的有
XmlBeanDefinitionReader
&DefaultListableBeanFactory
- 常见方法有
getBean(String name)
&createBean()
2) FactoryBean
- 一般情况下,Spring 通过 反射 实现 bean 的实例化,当过程比较复杂时,需要提供大量配置信息,此时就可采用 FactoryBean 的方式,通过 编码 方式得到 bean
- 一种特殊的 bean,为工厂类接口,用户可以通过实现该接口定制实例化 Bean 的逻辑,常用于完成复杂的 bean 的创建工作
- 在
preInstantiateSingletons()
中,如果发现为isFactoryBean(beanName)
,那么在 beanName 前面加上 ‘&’ 符号,再调用getBean
- 在调用
getBean
时,如果发现为 FactoryBean 对象,那么会调用FactoryBean.getObject()
方法返回 bean - 可以用来创建比较复杂的 bean | 第三方 bean 难以修改的情形
public interface FactoryBean<T> {
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true; // 默认为单例,支持 单例 & prototype
}
}
3) ApplicationContext
- 继承了 BeanFactory,实现了其功能
- 扩展了其他功能,例如国际化访问、事件传播等
- 一次性创建所有 Bean 实例,占用内存空间,启动较慢
4) ObjectFactory
- 用于 延迟查找,只有在执行
getObject()
时才会 实例化 bean
@FunctionalInterface
public interface ObjectFactory<T> {
/**
* 返回一个 新实例对象
*/
T getObject() throws BeansException;
}