前言
本来想一次性分析整个流程的,想了想还是单小结小结的分析~,主要还是代码来演示结果
所需知识点
- 了解 BeanDefinition
- 了解 注解 Bean 什么时候转换成 BeanDefinition ,我所说的 Bean 可以简单的理解成 被标注了 @Component的一个类,也就说 这个类什么时候注册成 BeanDefinition
本文演示内容
- 工厂 Bean
- 合并 Bean
- 方法回调
preInstantiateSingletons
- 单从方法名来看,就是 实例化单例Bean
public 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) {
// 去合并Bean
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//非抽象、单例、懒加载才会进行注册
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//判断是不是 FactoryBean,简单说是我们这个 Bean 实现了
if (isFactoryBean(beanName)) {
// 是不是 FactoryBean,获取 FactoryBean 的方式就是 前缀+beanName
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
// 判断是否 FactoryBean
if (bean instanceof FactoryBean) {
// 强转
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
} else {
// 判断 是不是 这个类的,如果是就去创建 SmartFactoryBean 属于 FactoryBean 子接口,拥有更加细粒度操作原数据的方式,
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
} else {
//获取具体的Bean
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
// 执行所有 单例Bean 的回调,当然Bean 需要实现这个接口~~~
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
isFactoryBean
因为当我们的Bean 实现了 这个 FactoryBean 接口后就会走这里,通过 实现 getObject(); 去创建对象
getMergedLocalBeanDefinition
这里是去合并Bean去了,这里其实有两个动作
- 将取出来的 BeanDefinition 进行合并
- 将BeanDefinition 转换成 RottBeanDefinition 也就说顶级的 Bean ,此处的顶级Bean 指的就是
User extends SuperUser
,可以认为是是 User,也可以认为是 SuperUser,如果是 User 就代表了已经进行了合并,如果 SuperUser 由于其本身就是顶级类,所以不需要合并,这里会排除掉 Object - 需要注意的是第一次 从 mergedBeanDefinitions 是从 当前的 BeanFactory 中查找
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
//从当前 BeanFactory 中的缓存中获取
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
// 不是NUll 并且 没有过期的话,如果过期了或者修改了 会重新去查找
if (mbd != null && !mbd.stale) {
//返回当前的
return mbd;
}
// 先去 beanDefinitionMap 中去获取
BeanDefinition thisBeanDefinition= getBeanDefinition(beanName);
// 缓存中未找到,就到 BeanFactory 中寻找
return getMergedBeanDefinition(beanName, thisBeanDefinition);
}
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
//传递Name 和BeanDefinition
return getMergedBeanDefinition(beanName, bd, null);
}
- 具体的逻辑
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
// 将 mergedBeanDefinitions 防止线程安全,为什么?
// 虽然 ConcurrentHashMap 是线程安全的,但是下面的业务并不一定是线程安全的,所以要加锁
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
RootBeanDefinition previous = null;
// 这里为空,代表的是 当前的 BeanDefinition 是顶层的 Bean 不存在 嵌套Bean
if (containingBd == null) {
// 获取当前Bean,为什么又一次获取了呢?因为如果在多线程操作下 可能 这个Bean已经被修改了,所以重新获取一次
mbd = this.mergedBeanDefinitions.get(beanName);
}
//如果缓存中没有,或者过期了,则会重新创建一个
if (mbd == null || mbd.stale) {
previous = mbd;
//如果 父 parentName 为空
if (bd.getParentName() == null) {
// 如果当前类型就是 RootBeanDefinition
if (bd instanceof RootBeanDefinition) {
// 进行克隆~~~
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
} else {
// 如果不是就会将 其他 BeanDefinition 转换成 RootBeanDefinition 代表的是当前 BeanDefinition 为顶级 Bean
mbd = new RootBeanDefinition(bd);
}
}
// 如果父 BeanDefinition 不为 空,也就代表了 当前类存在继承,如果不理解这段的话,可以看一下<bean parent=""> bean标签中的 paretn 属性,
else {
// 子bean定义:需要与父bean合并。
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
// 当前的 BeanName 不是 parentBeanName,会去获取 父BeanDefinition,否则则会去父工厂去获取
if (!beanName.equals(parentBeanName)) {
// 获取 parent BeanDefinition这里会进行一个递归操作,
pbd = getMergedBeanDefinition(parentBeanName);
} else {
// 如果当前的BeanName 和传递的 parentName 一模一样 则会去父 ParentBeanFactory 查找
BeanFactory parent = getParentBeanFactory();
// 如果当前是层次 BeanFactory 转换查找,如果不是 抛出异常
if (parent instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
} else {
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
"': cannot be resolved without a ConfigurableBeanFactory parent");
}
}
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// 进行合并
// 进行合并,这里的合并是指将 父级的Bean 合并到子 中,例如 user extends superUser
// 也就说讲 super中的 属性 合并到 user 中
// Deep copy with overridden values.
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
//设置成单例,如果之前没设置的话~~~~
if (!StringUtils.hasLength(mbd.getScope())) {
// 默认为单例
mbd.setScope(SCOPE_SINGLETON);
}
// A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
// Cache the merged bean definition for the time being
// (it might still get re-merged later on in order to pick up metadata changes)
// 是否缓存Bean的元数据
if (containingBd == null && isCacheBeanMetadata()) {
// 将当前的 BeanDefinitions 放入到map中,进行缓存
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
if (previous != null) {
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
return mbd;
}
}
说明
其实这一块还是比较绕的涉及到2个知识点
- 双 工厂 也就是说当前 工厂 和父类工厂, 当然这里这里的双工厂有点 双亲委派的味道
- 还有一个操作就是,会去递归的去获取 父BeanDefinition
getBean
- 这里暂时不说明,因为这里面的逻辑太复杂了… 后续会有文章进行分析
循环
当所有的单实例 Bean 都创建完成后会重新循环一次 执行 实现了
SmartInitializingSingleton.afterSingletonsInstantiated()
接口的回调,
这里~~本来不想贴代码的…
先说一下这个里的作用:主要是所有单例 bean 创建完成之后,可以在该回调中做一些事情。
需要说明的是 该Demo仅仅是演示了SmartInitializingSingleton
回调…
@ComponentScan()
public class SmartlnitializingSingletonContext {
public static void main(String[] args) {
AnnotationConfigApplicationContext ax = new AnnotationConfigApplicationContext();
ax.register(SmartlnitializingSingletonContext.class);
ax.refresh();
}
}
/**
* 拥有完整 Bean 生命周期的回调
*/
@Component
@Data
@ToString
class User implements SmartInitializingSingleton {
@Autowired
private Adder adder;
@Override
public void afterSingletonsInstantiated() {
}
}
@Data
@ToString
@Component
class Adder {
private String adder;
}