本文主要介绍spring创建bean的过程概述(spring创建bean的三种),下面一起看看spring创建bean的过程概述(spring创建bean的三种)相关资讯。
创建spring bean的过程介绍了创建factorybean的方法,然后介绍了创建factorybean的方法。在创建spring bean的过程中,会分为创建单例bean和创建原型bean。一般来说,在spring中,几乎所有的对象都是由singleton创建的,除非有其他业务需要设置为其他作用域的bean,所以我们重点以创建singleton beans为例。
singleton bean的创建在创建时会调用getbean,然后是dogetbean。一般来说,在spring中,只要是以do开头的方法,基本上都是真正的工作方法,所以let 让我们看看dogetbean方法的源代码:
protected t t dogetbean(string name,@nullable classt requiredtype,@nullable object[] args,仅布尔类型检查)抛出bean异常{//解析为规范的bean名称,因为它可能是factorybean前缀bean或别名bean string bean name = transformed bean name(name);对象bean//eagle检查手动注册的单体的单体缓存。//获取bean对象共享实例=获取缓存中的singleton(bean name);if (sharedinstance!= null args = = null){ bean = getobjectforbean instance(shared instance,name,beanname,null);}//如果不在缓存中,否则{//省略代码...//检查此工厂中是否存在bean定义。//检查父类容器//省略代码...如果(!typecheckonly) {//标记已创建markbeanascreated(bean name);}试试{//合并bean定义rootbean定义mbd = getmergedlocalbeandefinition(bean name);checkm: dependenson){ if(is dependent(bean name,dep)){//省略代码...}//注册依赖bean,放入集合registerdependent bean (dep,bean name);try {//create bean get bean(dep);} catch(nosuchbeandifinitenexception ex){//省略代码...} } }/createbean instance . if(mbd . issing leton){//如果是singleton,就创建bean共享实例= get singleton (beanname,-{ try {//create bean return create bean(bean name,mbd,args);} catch (beansexception ex) {//省略代码...}});//在获取bean对象时,会检查获取的对象是否为factor bean = getobjectforbean instance(shared instance,name,beanname,mbd);}//如何创建原型函数else if (mbd.isprototype) {//省略代码...} else {//省略代码...}} catch (beansexception ex) {//省略代码...} }//省略代码...返回(t)bean;}去掉不重要的代码,可以看到是先从缓存中获取的。如果没有获得,就会进行一些列检查,最后检查是否是singleton bean。如果是,将调用getsingleton方法,还有一个beanname,objectfactory的lambda表达式,表达式中有一个createbean方法,就是创建的bean方法。
那么什么时候调用cratebean方法呢?
答案是执行lambda表达式的具体方法。让 让我们看看这个objectfactory接口是什么。
objectfactory对象工厂直接查看源代码:
@ functional interface public interface objectfactory t {/* * *返回此工厂管理的对象的实例(可能是共享的或独立的)*。* @返回结果实例* @创建错误时抛出beans exception */t getobject抛出beans exception;}这个接口是一个函数接口,可以直接用于lambda表达式。当调用getobject方法时,实际执行的是lambda表达式中的方法。
看看getsingleton方法的源代码:
公共对象getsingleton(string beanname,objectfactory?singleton factory){ assert . not null(bean name, bean名称不能为空);synchronized(this . singleton objects){ object singleton object = this . singleton objects . get(bean name);if(singleton object = = null){ if(this。singleton currently industration){//省略代码...}//省略。密码...//在创建singleton(bean name)之前,检查正在创建的singleton对象并将其添加到集合中;//设置为新的singleton对象标识符boolean newsingleton = false//设置异常集合,发生异常时将异常添加到集合中。布尔recordsupressedexceptions =(this。隐藏的异常= = null);if(recordsuppressedexceptions){ this . suppressedexceptions = new linked hashset;} try {//执行特定方法并调用cratebean方法singleton object = singleton factory。getobject;//singleton = true作为新的singleton对象;} catch(illegalstateexception ex){//省略代码...} catch(beancreateexception ex){/省略代码...} finally { if(recordsupressedexceptions){ this . suppressed exceptions = null;}//在创建singleton creation (beanname)后检查并移除singleton对象;} if (newsingleton) {//将singleton (beanname,singleton object)添加到缓存中;} }返回singletonobject}此处执行后,将执行lambda表达式中的createbean方法:
受保护对象创建bean (string beanname,rootbean definition mbd,@ nullableobject [] args)抛出beancreation异常{//省略代码...rootbean definition mbd toose = mbd;//确保bean类实际上在t处被解析他的观点,并且//在动态解析的类//不能存储在共享的合并bean定义中的情况下,克隆bean定义。//解析bean的类用来反映和创建对象类?resolved class = resolvebean class(mbd,bean name);if (resolvedclass!= null!mbd . hasbean classmbd . getbean class name!= null){ mbd toose = new root bean definition(mbd);mbd tuse . setbean class(resolved class);}//preparemethodoverrides。try {//方法重写准备要使用的lookup-methodreplace-methodmbd。preparethodoverrides;} catch(beadefinitionvalidationexception ex){//省略代码...} try {//给beanpostprocessors一个返回代理而不是目标bean实例的机会。//提前解析实例化,用instantiationawarebeanpostprocessor实现object bean = resolvebeforeinstantiation(bean name,mbd to use);如果(豆!= null) {返回bean}} catch (throwable ex) {//省略代码...} try {//实例化初始化bean //真正创建bean对象bean instance = docreatebean (bean,mbd要用,args);//省略代码...返回beaninstance} catch (beancreationexception | implicitlyappearedsingletonexception ex){//省略代码...} catch (throwable ex) {//省略代码...}}首先解析bean的类型,主要用于后期反射创建对象,在rootbeandefinition中设置,然后覆盖方法。
spring方法覆盖实际方法覆盖意味着当使用lookup-method和replacred winter/a * @自1.0 * */公共抽象类myhouse {公共抽象my car park;}定义我的车
/* * * * @作者a redwinter/a * @自1.0 * */公共接口mycar {/* *买车* @还车*/mycar buy;}定义实现类:
宝马:
/* * * * @作者a red winter/a * @自1.0 **/public class宝马实现mycar { @ override public mycar buy{ rred winter/a * @自1.0 **/public类ben实现mycar { @ override public mycar buy{ return this;}}xml配置:
?xml版本= 1.0 encoding = utf-8 ?bxmlns : xsi = http://www.w3.org/2001/ xml schema-实例和xmlns : cont cho 13-@ . com schema location = http://www.springframework.org/sc://www.springframework.org/schema/cont id = 我的房子 class = com . red winter . test . method override . lookup method . my house 查找方法名称= 公园 bean = 宝马汽车公司//bean bean id = 我的房子 class = com . red winter . test . method override . lookup method . my house 查找方法名称= 公园 bean = 本 //bean!设置为原型bean id = 宝马汽车公司class = com . red winter . test . method override . lookup method . bmw scope = 原型和/bean id = 本 class = com . r * @自1.0 * */public class lookup test {/* * lookup-method用于求解单实例对象和多实例对象的*/@testpublic void lookuptest。{ classpathmlaplicationcontext = new classpathmlaplicationcontext( class path : method-override . xml );my house my house =(my house)context . get bean( 我的房子 );my house my house 1 =(my house)context . get bean( 我的房子 );system . out . println(my house . park);system . out . println(my house 1 . park);}}输出:
com . red winter . test . method override . lookup method . bmw @ 4a 765 com . red winter . test . method override . lookup method . bmw @ 3e 6358这里myhouse是singleton对象,myhouse1调用的方法每次都是不同的对象。
spring是如何实现方法覆盖的?源代码太复杂,太复杂。这里,直接看执行过程:
只要设置了lookup-method标记,spring将创建一个lookupoverride类,并在加载beandefinition和执行方法parselookupoverridesubelements时将其放入beandefinition的methodoverrides属性中。在创建bean时,我们会判断这个属性值是否有值。如果是,我们在实例化对象时会得到一个实例化策略,然后调用simpleinstationstrategy # instantiate方法,然后用cglib实例化,创建一个enhancer增强类,设置回调类型如下:
私有静态最终类。[] callback_types =新类?[]{noop.class,lookupoverridemethodinterceptor . class,replaceoverridemethodinterceptor . class };最后,当方法被执行时,它将被调用到回调类lookupoverridemethodinterceptor,然后bean将被创建:
@ override public object intercept(object obj,method method,object[] args,method proxy mp)throwable {//cast是安全的,因为callbackfilter筛选器是有选择地使用的。lookup override lo =(lookup override)getbean definition。getmethodoverrides。getoverride(方法);assert.state(lo!= null, 找不到lookup override );object[]args tous: null);//如果没有-arg,则不要 t in siston args at all if(string utils。hast: this . own:豆);} : this . owner . get bean(method . get returntype);}}那个 本文就到这里,下一篇继续。
标签:
方法代码
了解更多spring创建bean的过程概述(spring创建bean的三种)相关内容请关注本站点。