Spring之Bean的获取过程
大致过程总结
创建Bean的流程
1、将传入的name,进行转化,获取到BeanName
a.传入的有可能是别名,在aliasMap中获取到真实的BeanName
b、传入的有可能携带&符号,需要将带&的name去处。
2、尝试先从单例池中获取(三七法则,绝大部分的Bean是单例的)
a、如果获取成功,判断这个Bean是否在创建中,如果是在创建中则抛出在创建中的错误。
b、没有在创建中,则需要判断是否为factoryBean,如果是FactoryBean,需要获取getObject()方法中的返回的对象。
3.如果在单例池中不存在,则需要正式开始创建Bean了。
1、从mergedBeanDefinitions获取合并后的BeanDefinition。
2、检查BeanDefinition是否为抽象的,如果为抽象的需要抛出异常。
3、获取Bean通过@DependsOn注解依赖的Bean对象。如果存在,需要判断是否存在相互依赖的关系
1、假如现在正在创建A对象,A对象依赖B对象,而B对象又通过@DependsOn依赖了A对象,此时需要抛出异常。这种相互依赖无法解决。
2、假如现在正在创建A对象,A对象依赖B对象,但B对象没有依赖A对象,则开始创建B对象。
4、将依赖关系存入到dependentBeanMap(被哪些Bean依赖)、dependenciesForBeanMap(依赖了哪些Bean)
5、单例Bean创建
1、尝试在单例池中获取,如果单例池中为空,则开始创建。
2、实例化前【Object bean = resolveBeforeInstantiation(beanName, mbdToUse)】
1、先判断是否有实现InstantiationAwareBeanPostProcessor的类,如果存在则调用【postProcessBeforeInstantiation】方法。
2、如果实例化前有返回值,不为null,则直接调用实例化后的方法【applyBeanPostProcessorsAfterInitialization】。
3、如果实例化前返回了Bean对象,不为null,则直接把结果返回。
4、初始化【Class<?> resolvedClass = resolveBeanClass(mbd, beanName)】通过ClassLoader加载类,获取类对象。
5、复制BeanDefinfition,同时设置BeanClass。
6、判断是否实现了【MergedBeanDefinitionPostProcessor】接口,如果实现了则调用【postProcessMergedBeanDefinition】方法。这个方法可以在属性填充之前,进行手动属性复制。
7、属性填充,先判断用户是否手动填充了属性的值,如果存在则会用手动填充的值。
8、判断是否实现了【Aware】接口,调用对应的方法,进行属性设置。
9、实例化前
1、调用【postProcessBeforeInitialization】方法。
10、实例化
1、判断Bean是否实现了【InitializingBean】接口,调用【afterPropertiesSet】方法,
2、判断是否制定了初始化的方法【initMethodName】,如果指定了,调用该方法。
11、实例化后
1、调用【postProcessAfterInitialization】方法
12、处理Bean销毁方法。
13、返回Bean
6、将获取到的Bean进行判断,是否为FactoryBean
1、如果是;尝试从factoryBeanObjectCache缓存中获取,将结果返回,如果获取失败,则调用【getObject()】创建Bean。
2、如果不是,则直接返回。
4、将Bean添加到单例池中。
1、获取Bean的三种方式
1、public Object getBean(String name)
2、public <T> T getBean(String name, Class<T> requiredType)
3、public Object getBean(String name, Object... args)
无论哪种获取Bean的方式,最终都是调用的protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)这个方法。
- protected String transformedBeanName(String name)
在这个方法里面,首先进行的就是根据输入的name,获取到真实的BeanName。这个发方法大致会进行两个判断
a、首先判断这个name上是否含有&符号,会循环将&符号去除。
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
b、通过public String canonicalName(String name)方法,将真实的BeanName获取到。
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
由于一个Bean可以被配置多个别名,而BeanDefinition只会对应一个BeanName,所以需要后去到这个BeanName。
由于大部分的Bean是单例的,所以会先尝试从单例池中获取。
1、如果可以获取到,就会判断是否为factoryBean,从而进行转化,获取到对应的Bean对象。
2、如果没有获取到,则开始创建需要开始创建Bean。
在创建之前,会先判断由@DependsOn依赖的Bean,之间是是否存在相互依赖问题。
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 如果存在相互依赖的情况,抛出错误
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);
}
}
}
在这个方法里面,运用了两个Map作为缓存,以下做了解释
// 被依赖的Map
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
// 依赖的Map
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
2、根据作用域,进行创建,在此我们只介绍单例Bean的创建过程。
// 创建单例Bean
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;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
- 同样的,先从单例池中尝试获取Bean。如果获取到了,则直接返回。
- 没有获取到,开始正式的创建。
- 先进性实例化前的操作
3、实例化前
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
在这个方法中,首先会调用applyBeanPostProcessorsBeforeInstantiation这个方法,此方法会调用postProcessBeforeInstantiation方法。
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
调用BeanPostProcessor.postProcessBeforeInstantiation()方法
如果如果返回值不为空,则调用完成实例化后的方法后,则直接返回对象。
4、实例化对象AbstractAutowireCapableBeanFactory.doCreateBean->createBeanInstance()
// 通过类加载器,获取类对象
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 推断构造方法,获取创建Bean的构造方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 实例化
instantiateBean(beanName, mbd)
5、属性填充 populateBean(beanName, mbd, instanceWrapper);
1、实例化后
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
调用BeanPostProcessor.postProcessAfterInstantiation()方法
2、执行属性填充 applyPropertyValues(beanName, mbd, bw, pvs);
6、初始化AbstractAutowireCapableBeanFactory.initializeBean()
1、Aware回调
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
- 如果实现了BeanNameAware接口,那么将会把BeanName返回。
- 如果实现了BeanClassLoaderAware接口,那么将会把加载Bean的类加载器返回。
- 如果实现了BeanFactoryAware接口,那么将会把创建Bean的Bean工厂返回。
2、初始化前 AbstractAutowireCapableBeanFactory.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()方法
3、初始化 AbstractAutowireCapableBeanFactory.invokeInitMethods()
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
- 判断是否实现了InitializingBean接口,如果实现了,执行afterPropertiesSet()方法。
- 判断是否设置了初始化方法发,执行初始化方法invokeCustomInitMethod(beanName, bean, mbd);
7、初始化后AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization()
public 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;
}
调用BeanPostProcessor.postProcessAfterInitialization()方法。
8、处理销毁Bean的方法 AbstractAutowireCapableBeanFactory.registerDisposableBeanIfNecessary()
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
9、将单例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);
}
}
以上就是创建Bean的完整流程,有兴趣的可以在评论区交流。