★
接着上一节,如果在缓冲中找不到bean,那么要不就是循环依赖出问题了,要不就需要找到beanDefinitioin 进行实例化,我们这里来介绍后者。
1.获取beanDefinitioin。
2.创建bean(单例,原型,自定义)
3.对创建的bean实例对象进行类型检查
正文:
一,bean准备工作
第一个:找到beanDefinition
//对IOC容器中 是否存在指定名称的beanDefinition 进行检测,如果当前容器不存在, 就去父容器中查找。
BeanFactory parentBeanFactory = getParentBeanFactory(); //dubug显示,为null
//父类存在,子类中第六层(最底层实现的该方法),找不到beanDefinition,则需要去父类中查找,
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name); //获得原名字
if (parentBeanFactory instanceof AbstractBeanFactory) { //这个应该是子类
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly); //使用父类直接doGet创建。
}
else if (args != null) { //父类只有getBean方法。
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
如果本类容器没有,就去父类的容器中找,而且直接是return 所以不会走if下面的代码代码了,我们的测试demo,dubug到这里显示parentBeanFactory为null,所以并没有进入该代码块。
第二个:获取BeanDefinition并且依赖准备
//根据指定Bean名称 获取其父级bean的定义。 主要解决bean继承时 子类和父类 公共属性问题。
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//获取当前bean所有依赖 bean的名称。
String[] dependsOn = mbd.getDependsOn();
//【说明】如果要创建的bean有需要依赖的(比如controller依赖service)那么这里要先创建service所有这里是递归,递归完, 还要继续执行的(而上面的递归是直接返回结果了)
if (dependsOn != null) {
for (String dep : dependsOn) {
registerDependentBean(dep, beanName);//把被依赖的bean注册给当前依赖的bean.
getBean(dep);//递归调用获取当前bean的依赖。
}
}
第一步:获得RootBeanDefinition 这个以前没有见过,这里查了一下:https://blog.csdn.net/andy_zhang2007/article/details/86514320
内容:基础接口是:beanDefinition,它的变种有:RootBeanDefinition
,ChildBeanDefinition
,还有GenericBeanDefinition
,AnnotatedGenericBeanDefinition
,ScannedGenericBeanDefinition
等等,这些概念抽象了不同的关注点。此处的getMerged...它是一个map,k-v=name-RootBean...
简单点,这个RootBean...就是封装了BeanDefinition,反正我们就是拿到了beanDefinition了,可以开始实例化了。!
第二步:获取bean的所以依赖,放在一个字符串组中,应该返回的是依赖bean的name。通过它的父类AbstractBeanDefinition 的属性dependsOn直接获取。
第三步:将依赖注册到第二层类:DefaultSingletonBeanRegistry类中,所以我们得到结论:自动注入(@Autowired)产生的bean都是单例的!
存放容器:
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
注册代码:
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = canonicalName(beanName); //获得原名
//将依赖的beanName 添加到两个容器中
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8)); //获得value
if (!dependentBeans.add(dependentBeanName)) { //添加失败,直接返回
return;
}
}
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
第四步:获取依赖的bean (这里就相当于递归了) 来到了核心的地方,doGetBean(也就是我们的第一次使用getBean ,从缓冲判断,然后自己创建bean 的那个函数)
递归,将自动注入的bean,缓存到单例的容器中。!
二,实例化Bean
2.1 单例bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args); //【入】具体方法
}...
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
内容重点是:createBean(),跳转到:AbstractAutowireCapableBeanFactory类。它是AbstractBeanFactory的直接子类。也就是第五层类,createbean() 传入的参数,第一个是beanName 第二个是beanDefinition的封装,第三个是构造参数。
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
RootBeanDefinition mbdToUse = mbd;
//判断该bean,是否可以被当前加载器修改。
Class<?> resolvedClass = resolveBeanClass(mbd, beanName); //【1】
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd); //复制一份
mbdToUse.setBeanClass(resolvedClass);
}
mbdToUse.prepareMethodOverrides(); //【2】
Object bean = resolveBeforeInstantiation(beanName, mbdToUse); //【3】
if (bean != null) {
return bean;
}
Object beanInstance = doCreateBean(beanName, mbdToUse, args); //【4】
return beanInstance;
}
第一个方法,返回bean的class对象(调用的是AbstractBeanFactory实现的方法)
第二个方法,效验mbdTOUse,(这里是把传入的容器中的beanDefinition复制了一份起来作为mdbToUse)
第三个方法,如果bean配置了初始化前后处理器,则返回一个代理对象。(这里涉及到了处理器,之后再讨论重点看下一个方法)
第四个方法,根据name和beanDefintion创建bean。(重点)
【重点】 doCreateBean() 很长 ,位于第五层类:AbstractAutowireCapableBeanFactory类中:
那么长的方法,大致分为五个流程:
第一流程:创建bean对象
把bean封装到BeanWrapper类中。【注意】第一个流程很长,注意什么时候回来!
// Instantiate the bean. 创建bean实例对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) { //单例,用过已经存在与缓存中,获取
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) { //临时创建
instanceWrapper = createBeanInstance(beanName, mbd, args); //【重点】
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
详细学习BeanWrapper参考链接:https://my.oschina.net/thinwonton/blog/1492224
概述:它的作用:bean的包裹类,提供了访问bean的属性值,属性编辑注册,类型转换等功能。(这里重点:属性赋值)
重点是createBeanInstance()方法,直接创建,(本类中,又是一个很长的方法)返回类型就是一个BeanWrapper.
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point. 确认bean可解析
Class<?> beanClass = resolveBeanClass(mbd, beanName);
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) { //demo显示为Null
return obtainFromSupplier(instanceSupplier, beanName);
}
if (mbd.getFactoryMethodName() != null) {//demo显示为Null 工厂方法进行实例化
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) { //false
if (autowireNecessary) {//配置了自动装配属性,使用容器的自动装配进行实例化
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring? 使用构造方法进行实例化
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
//默认的 无参构造方法实例化bean对象
return instantiateBean(beanName, mbd);// 走这里
}
这里直接进行了bean的实例化 ,整个方法分为三个块,注意观察return的位置。
第一个 使用工厂方法对bean 实例化:Supplier接口,只有一个方法T get()。每次调用get() 都会调用构造方法创建一个新对象。
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
String outerBean = this.currentlyCreatedBean.get();
this.currentlyCreatedBean.set(beanName);
Object instance;
try {
instance = instanceSupplier.get(); //重点
}
finally {... }
BeanWrapper bw = new BeanWrapperImpl(instance);
initBeanWrapper(bw);
return bw;
}
第二个 使用容器的自动装配方法 进行实例化
这里的关键是resolved 标识符,args要确保是null,才能进行自动装配。这里也是一个入口而已,
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
注意,又是ConstructorResolver 的方法。
第三个:使用默认的无参构造方法进行实例化。也是demo测试例子 所走的路线
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else { //demo 走这里
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
}
重点是getInstantiationStrategy().instantiate(mbd, beanName, parent) 实现初始化。instantiate()方法位于SimpleInstantiationStratey类中
protected InstantiationStrategy getInstantiationStrategy() {
return this.instantiationStrategy;
}
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
//获取对象的构造方法or 工厂方法
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else { //获取构造方法
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
}
} //调用工具类,传入构造方法,继续实例化 【入】
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
如果bean的方法被覆盖了,则使用cglib进行实例化,我们先看简单的jdk反射机制实例化:
第一个return 直接使用BeanUtils 得到了bean的实例化对象了。使用的是jdk 的反射,
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
}
....
}
第二个return 使用的是cglib代理模式,方法跟踪:来到CglibSubcalssInstantiationStrategy类中:
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
return instantiateWithMethodInjection(bd, beanName, owner, null);
}
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Constructor<?> ctor, @Nullable Object... args) {
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}
创建了一个CglibSubclassCreator类,它是一个内部类 ,重点是instantiate()方法,不同于第一个return 代码的地方就是,class对象的获取,第一个方法是直接获取,第二个是通过cglib代理创建Class对象,最后同样通过BeanUtils进行实例化。
public Object instantiate(@Nullable Constructor<?> ctor, @Nullable Object... args) {
//创建代理子类 【入】
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
if (ctor == null) {
instance = BeanUtils.instantiateClass(subclass);
}
else {
try {
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
instance = enhancedSubclassConstructor.newInstance(args);
}
}
Factory factory = (Factory) instance;
...
return instance;
}
//------------------------------
private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
//cglib中的类
Enhancer enhancer = new Enhancer();
//将bean本身作为基类
enhancer.setSuperclass(beanDefinition.getBeanClass());
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
if (this.owner instanceof ConfigurableBeanFactory) {
ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
}
enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
enhancer.setCallbackTypes(CALLBACK_TYPES);
//使用cglib的..方法生成实例对象。
return enhancer.createClass();
}
分析:我们先从最下面的方法开始分析,Enhancer这是cglib的标准类,把beanDefinition的class对象传给他,作为父类,然后它创建一个新的字节码,返回一个新的class对象了。然后使用BeanUtils返回实例化对象。
在这里就成功实例化了bean。现在回到AbstractAutowireCapableBeanFactory类的doCreateBean()方法:
第二流程:调用后置处理器:
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
第三流程:缓存到第二层:DefaultSingletonBeanRegistry类中
//向容器中缓存单例模式的 bean ,防止死循环
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); //【入】
}
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory); //【放入】
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
第四流程:bean对象的初始化,依赖注入。
Object exposedObject = bean;
try { //对Bean属性进行依赖注入 【入】
populateBean(beanName, mbd, instanceWrapper);
//对Bean实例对象进行初始化,使用后置处理器
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
第一个方法,populateBean() 这个方法也是比较长。位于第五层:AbstractAutowireCapableBeanFactory类中
可以参考:https://blog.csdn.net/qwe6112071/article/details/85225507 同时也可以看我下一篇博文,这里就不叙述了!
然后进行bean实例的 初始化,initializeBean()方法,这个方法里面调用后置处理器,和AOP有关,所以我们在AOP章节再分析。
第五流程:获取bean对象
if (earlySingletonExposure) {
//获取指定名称的 已注册的 单列模式的 bean对象
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) { //demo走这里
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);
}
}
....
}
到这里,我们就成功的通过单例模式,创建获得了bean实例对象,并且完成了依赖注入,下一节,我们将继续分析原型模式的bean对象如何实例化!