springbean实例化源码解析
2021-01-11 11:46:38 0 举报
springbean实例化源码解析
作者其他创作
大纲/内容
方法实现
获取父工厂这个大多数情况下都不会有父类构造方法,大多数情况都不会有父工厂,除非设置父工厂,所以这个为null
实例化所有的单例对象
doCreateBean
获取这个后置处理器返回的bean是否为空不为空则返回bean在一个类中有很多spring属性,比如 xx1 xx2 xx3 如果这些spring属性不需要交给spring来处理的话,你可以实现一个后置处理器 这个后置处理器就是在这个方法上执行的 如果获取的后置处理器返回的bean不为空的话就直接返回bean 就不会进行下面的处理了 实现这个InstantiationAwareBeanPostProcessor后置处理器
当返回的ctors有值时
判断class是否是一个接口,如果是接口则报异常
constructorToUse这个就是用哪个构造方法来实例化对象argsToUse就是参数的值有了构造方法有了参数值是不是就可以把对象实例化出来了constructorToUse.newInstance(argsToUse)但是现在关键具体要哪个构造方法来实例化对象,继续往下看
添加到alreadyCreated set集合中 表示已经创建过了 防止重复创建
当返回的ctors无值时
Object[] argsToUse
getBean
调用doCreateBean,spring开始创建bean
这里完成了bean的实例化
使用默认的无参构造方法进行初始化
开始创建bean实例
markBeanAsCreated
把beanName添加到singletonsCurrently这个set集合中表示beanName对应的这个bean正在创建中
finishBeanFactoryInitialization
构造方法的值 注意不是参数 全世界的人民都知道构造方法通过反射来实例化一个对象 在调用反射实例化对象的时候,需要把具体的值 这个标量就是记录这些值的 后面有证明 但是需要注意的是 argsHolderToUse是一个数据结构 argsToUse[]才是具体的值
判断这个对象是否被实例化好了,一般都为null
hasMethodOverrides
if (constructorToUse == null)
determineConstructorsFromBeanPostProcessors
constructorToUse = clazz.getDeclaredConstructor()
由后置处理器决定返回哪些构造方法 如果你这个构造方法是一个无参的构造方法,就返回null 如果只有一个构造方法并且这个构造方法是一个无参的,spring认为你是没有特殊构造方法的,就会执行instantiateBean构造实例
candidates = (mbd.isNonPublicAccessAllowed() ?\t\t\t\t\t\t\tbeanClass.getDeclaredConstructors() : beanClass.getConstructors());
Constructor<?>[] candidates = chosenCtors
得到默认的构造方法,即使类中没有写也能得到默认的 通过反射的技术 constructorToUse这个表示spring中使用哪个构造方法实例化对象
boolean autowiring
isPrototypeCurrentlyInCreation
反射创建对象
是否指定使用哪个构造方法 因为使用的是默认的所以为null
doGetBean
constructorToUse
this.singletonObjects.get(beanName)
resolveBeforeInstantiation
得到一个反射的实例化策略
getParentBeanFactory
定义了最小长度个数 如果你给定构造方法参数列表具体的值 那么这些值的个数就是构造方法参数的个数为什么要这样做呢因为有多个构造方法,那么spring就要判断我到底使用哪个构造方法怎么判断?判断第一步这个构造方法至少需要几个参数
instantiate
验证bd 不重要
为null执行下一步
AutowireUtils.sortConstructors(candidates)
if (clazz.isInterface())
获取所有的构造方法
createBean
判断是否是原型,如果是原型,不应该在初始化的时候创建上面已经判断是否是单例了,这个主要是多重判断,谨慎的态度
spring采用哪种构造方法来实例化bean 代码执行到这里spring已经决定采用特殊的构造方法来实例化bean 但是到底用哪个?可能类提供了很多构造方法 采用哪个,spring有自己的一套规则 当他找到一个之后,spring就会把这个构造方法赋值给constructorToUse
getSingleton
设置构造方法可访问
beforeSingletonCreation(beanName)
和上面的是不同的
createBeanInstance
instantiateBean
chosenCtors这个是外部传过来的,就是spring找出来的,刚刚说spring遇到麻烦了,因为在找构造方法的时候他找到两个,所以他说算了吧不找了吧,两个就给一个null吧,所以这个就给一个null如果找到一个就带进来了,spring就把它给它判断它是否为空,如果不为null,它就直接用它了如果没有找到怎么办没有找到spring就认为这个构造方法是有问题的,所以spring需要重新找一遍没有找到,spring这样认为的,没有找到,但是又进入这个方法来了,证明你需要用构造方法来构造实例,但是前面又没有找到,spring认为可能我判断有误,所以spring来一个严谨的判断怎么做一个严谨的判断它把所有的构造方法拿出来,依次匹配,看看哪个更符合怎么匹配
instantiateClass(constructorToUse)
getFactoryMethodName
checkMergedBeanDefinition
通过构造方法反射创建对象
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod
ArgumentsHolder argsHolderToUse
makeAccessible(ctor)
minNrOfArgs
根据构造方法的访问级别和参数数据排序 怎么排序呢 有限访问权限继而参数个数 先根据访问权限进行排序然后根据参数个数 访问权限越高越放在前面,参数个数越大越放在上面
检测bean配置中lookup-method replace-method 如果配置了就需要cglib构建bean对象
preInstantiateSingletons
收藏
收藏
0 条评论
下一页