Spring源码-getBean获取bean实例

实例化Bean

单例bean,并且lazy-init为false(默认是false),则 ApplicationContext在刷新的时候就实例化该Bean,并且将实例化的Bean放到缓存中,下次再使用该Bean的时候, 直接从这个缓存中获取;如果单例bean是懒加载的,即lazy-init为true,则在第一次getBean获取该Bean的时候进行实例化,并放入缓存;scope是prototype的多例bean,每次使用获取Bean的时候都会进行实例化

<bean id="" class="" scope="作用域"/>

1. singleton: 单例 ,在Spring IoC容器中仅存在一个Bean实例 (默认的scope)
2. prototype: 多例 ,每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()
3. request: 用于web开发,将Bean放入request范围 , 在同一个request 获得同一个Bean
4. session: 用于web开发,将Bean 放入Session范围,在同一个Session 获得同一个Bean 

spring容器默认加载bean为非延迟加载,在容器刷新阶段就会实例化bean对象,设置为延迟加载则当类首次被加载时才会初始化实例,所有bean的实例化都是通过getBean去实现

<!--当前xml中所有的bean-->
<beans default-lazy-init="default | false | true">
<!--指定的bean-->
<bean lazy-init="default | false | true">

使用注解方式

@Lazy
public class Bean {}

总结所有bean的生命周期:单例且非延迟加载的bean跟随容器刷新完成实例初始化,之后访问实例从缓存中获取;单例延迟加载的bean在首次访问时通过getBean完成实例化,之后访问从缓存中获取;

Bean实例化的方式

无参数构造器实例化

<bean id="super" name="a1,a2,a3" class="cn.mywork.spring.Super" lazy-init="true"/>

静态工厂方法实例化

//factory-method找到工厂类的静态方法
<bean id="student" class="cn.mywork.spring.StaticFactory" factory-method="getStu"/>

//配置静态工厂类
public class StaticFactory {
    //通过配置文件找到静态方法,返回对象为创建的bean
    public static Student getStu(){
        return new Student();
    }
}

ApplicationContext context;
Student student = context.getBean("student", Student.class);

实例工厂

//先将工厂bean交给容器管理
<bean id="instanceFactory" name="fc" class="cn.mywork.wms.spring.InstanceFactory"/>
//factory-bean只能是初始化好的bean对象,通过bean工厂对象,获取实例方法初始化bean
<bean id="student" factory-bean="fc" factory-method="getStu"/>

实现FactoryBean接口,通过getObject方法返回目标实例

//实现getObject方法
public class InstanceFactory implements FactoryBean<Student>{
    @Override
    public Student getObject() throws Exception {
        return new Student();
    }
    @Override
    public Class<?> getObjectType() {
        return null;
    }
    @Override
    public boolean isSingleton() {
        return false;
    }
}

<bean id="student" class="cn.mywork.spring.InstanceFactory"/>

注解的方式

//注解对应的配置解析
<bean id="super" class="cn.mywork.wms.spring.Super" init-method="init" destroy-method="destory" scope="prototype">
    <!--注入的属性-->
    <property name="sub" ref="sub"/>
</bean>
<bean id="sub" class="cn.mywork.wms.spring.Sub"/>

//默认的为简化的类名,Xml里也同于bean标签的id值
@Component("super")
//作用域:非单例
@Scope("prototype")
public class Super {
    private String name;
    //注入Sub初始化的实例
    @Autowired
    private Sub sub;
    //初始化的方法,init-method="init"
    @PostConstruct
    public void init(){
    }
    //销毁的方法,destroy-method="destory"
    @PreDestroy
    public void destory(){
    }
}

自定义BeanFactory工厂

public class BeanFactoryDemo {
    //key为id,value为全限定名
    private static Map<String,String> beanMap = new HashMap<>();
    //bean缓存,延迟加载bean时,genBean之后将bean放入缓存
    private static Map<String,Object> cacheMap = new HashMap<>();

    //解析xml配置文件
    static {
        try {
            //getClassLoader().getResourceAsStream是加载resources资源路径下的配置文件
            InputStream resource = BeanFactoryDemo.class.getClassLoader().getResourceAsStream("spring.xml");
            initBeanMap(resource);
        }catch (Exception e){}
    }

    private static void initBeanMap(InputStream resource) throws Exception {
        SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
        saxParser.parse(resource,new DefaultHandler(){
            //解析后的标签名
            private String tagName;
            @Override
            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
                this.tagName = qName;
                //获取标签内容
                if ("bean".equals(tagName)){
                    //获取id的值
                    String id = attributes.getValue("id");
                    //获取bean的全限定名
                    String beanClassName = attributes.getValue("class");
                    beanMap.put(id,beanClassName);
                }
            }
            @Override
            public void endElement(String uri, String localName, String qName) throws SAXException {
                tagName = null;
            }
        });
    }

    //获取bean实例的方法,延迟加载方式
    public static  <T> T getBean(String id,Class<T> beanClass) throws Exception{
        //只有map中存在的key值才会继续处理
        if (beanMap.containsKey(id)){
            //再判断缓存中是否有该bean
            if (cacheMap.containsKey(id)){
                return (T) cacheMap.get(id);
            }
            String beanClassName = beanMap.get(id);
            //加载全限定名,通过反射机制创建bean
            Object instance = Class.forName(beanClassName).newInstance();
            //判断是否为beanClass类型的实例
            if (beanClass.isInstance(instance)){
                cacheMap.put(id,instance);
                return (T) instance;
            }
        }
        return null;
    }
}

Student student = BeanFactoryDemo.getBean("student", Student.class);

getBean

refresh执行到finishBeanFactoryInitialization时才开始实例化非延迟加载的bean,主要看其中的preInstantiateSingletons方法

public void preInstantiateSingletons() throws BeansException {
    //所有的需要实例化的beanName都在beanDefinitionNames,包括 Aspectj的, 通过注解标识的
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    for (String beanName : beanNames) {
        //合并父类BeanDefinition
        //MergedBeanDefinition合并bean定义,XML 配置来注册 bean,会被封装成GenericBeanDefinition;使用注解的方式来注册 bean,会被封装成 ScannedGenericBeanDefinition,最终统一转换成 RootBeanDefinition处理
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        //非抽象,单例,非懒加载三个条件
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            //是 FactoryBean 类型的对象则加上&
            //判断是factoryBean还是普通bean,实现FactoryBean接口的getObject()方法可以定义创建实例对象,比如很多中间件的就是通过这种方式实现
            if (isFactoryBean(beanName)) {
                bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                ...
            }
            else {
                // 进入到doGetBean执行实例化bean
                bean = getBean(beanName);
            }
        }
    }
}    

容器初始化完成还是在初始化之后动态获取bean都会访问beanFacroty.getBean()方法,进入这个方法发现有很多分支去获取bean,如果不是首次获取bean则直接getSingleton()先从缓存中获取

protected <T> T doGetBean(String name, Class<T> requiredType,Object[] args, boolean typeCheckOnly) throws BeansException {
    //去掉FactoryBean的前缀“&”,解析别名返回namespace的beanName
    String beanName = this.transformedBeanName(name);
    //获取缓存中的bean,不涉及创建新的bean实例和解决循环依赖
    Object sharedInstance = this.getSingleton(beanName);
    Object bean;
    //缓存中如果能获取到
    if (sharedInstance != null && args == null) {
        //普通bean直接返回实例,factoryBean继续处理
        bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
    } else {
        //和singletonsCurrentlyInCreation类似存放正在创建的Prototype实例
        //循环依赖校验:当前原型实例池中有正在创建的对象了,说明这个对象是个原型对象,并且当前线程中这个对象已经处于创建中了,会造成循环依赖
        if (this.isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }	
        BeanFactory parentBeanFactory = this.getParentBeanFactory();
        //当前BeanFactory中的beanDefinitionMap找不到当前Bean,则从parentBeanFactory获取
        if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
            //解析别名和去掉FactoryBean的前缀
            String nameToLookup = this.originalBeanName(name);
            //使用父类的doGetBean方法实例化bean
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
            }
            ...
        }
        //类型检测默认为false,将beanName添加到alreadyCreated缓存
        if (!typeCheckOnly) {
            this.markBeanAsCreated(beanName);
        }
        //RootBeanDefinition可以理解为一个没有parent的独立BeanDefinition
        //Map<String, RootBeanDefinition> mergedBeanDefinitions
        //如果mergedBeanDefinitions没有父类定义就是BeanDefinition本身
        RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
        //检查是抽象类则抛异常
        this.checkMergedBeanDefinition(mbd, beanName, args);
        //获取所有当前bean的依赖,需要在依赖创建之后才能进行实例创建
        //@DependsOn这个熟悉的注解:需要依赖另一个bean的实例创建
        String[] dependsOn = mbd.getDependsOn();
        if (dependsOn != null) {
            for (String dep : dependsOn) {
                // 检查是否依赖于beanName,即存在循环依赖
                if (isDependent(beanName, dep)) {
                    throw new BeanCreationException();
                }
                //将dep和beanName的依赖关系注册到dependentBeanMap中
                registerDependentBean(dep, beanName);
                //先实例化依赖的Bean
                getBean(dep);
            }
            //实例化不同的scope域的Bean
            if (mbd.isSingleton()) {
                //重载方法
                //getSingleton(String beanName, ObjectFactory<?> singletonFactory)
                sharedInstance = this.getSingleton(beanName, () -> {
                    //singletonFactory.getObject()方法最终执行的是createBean()方法
                    try {
                        return this.createBean(beanName, mbd, args);
                    } catch (BeansException var5) {
                        this.destroySingleton(beanName);
                        throw var5;
                    }
                });
                //跟上面一样不是factoryBean则返回普通的实例对象
                bean = this.getObjectForBeanInstance(sharedInstance,name,beanName, mbd);
            } else if (mbd.isPrototype()) {
                //scope为prototype的bean创建
                var11 = null;
                Object prototypeInstance;
                try {
                    //添加到缓存prototypesCurrentlyInCreation中
                    this.beforePrototypeCreation(beanName);
                    //创建实例
                    prototypeInstance = this.createBean(beanName, mbd, args);
                } finally {
                    //移除prototypesCurrentlyInCreation中的缓存
                    this.afterPrototypeCreation(beanName);
                }
                //普通Bean直接返回
                bean=this.getObjectForBeanInstance(prototypeInstance,name,beanName, mbd);
            } else {
                //其他scope的bean创建
                String scopeName = mbd.getScope();
                Scope scope = (Scope)this.scopes.get(scopeName);
                //实现的也是ObjectFactory
                Object scopedInstance = scope.get(beanName, () -> {
                    //通过getObject方法调用,和prototype创建bean实例一致
                    this.beforePrototypeCreation(beanName);
                    Object var4;
                    try {
                        var4 = this.createBean(beanName, mbd, args);
                    } finally {
                        this.afterPrototypeCreation(beanName);
                    }
                    return var4;
                });
                bean=this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
            }
        }
    }
}...

factoryBean

回到doGetBean()方法,如果获取到缓存则继续进入getObjectForBeanInstance()交给factoryBean处理

//bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
    //表示name以“&”为前缀但不是factoryBean则抛异常
    if (BeanFactoryUtils.isFactoryDereference(name)) {
        ...
    //不是factoryBean则直接返回
    } else if (!(beanInstance instanceof FactoryBean)) {
        return beanInstance;
    } else {
        //缓存中拿到的是一个factoryBean
        Object object = null;
        if (mbd != null) {
            //标注这个beanDefinition为factoryBean
            mbd.isFactoryBean = true;
        } else {
            //入参mbd为null,所以需要从factoryBeanObjectCache缓存拿到实例
            //Map<String, Object> factoryBeanObjectCache 用于缓存factoryBean
            object = this.getCachedObjectForFactoryBean(beanName);
        }
		//缓存中也没有
        if (object == null) {
            FactoryBean<?> factory = (FactoryBean)beanInstance;
            //从beanDefinitionMap注册的缓存中找到beanDefinition
            if (mbd == null && this.containsBeanDefinition(beanName)) {
                //获取合并(父容器)后的RootBeanDefinition
                mbd = this.getMergedLocalBeanDefinition(beanName);
            }
			//mbd是否是合成的,一般为false
            boolean synthetic = mbd != null && mbd.isSynthetic();
            //使用factory去实例化bean
            object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
        }
        return object;
    }
}

factoryBean是一个特殊的bean,实现FactoryBean接口,factoryBean在被初始化时会调用其getObject()方法创建应用的bean

//注入一个factoryBean
@Component
public class MyFactoryBean implements FactoryBean<HahaBean> {
    @Override
    public HahaBean getObject() throws Exception {
        //比如通过getBean(MyFactoryBean.class)则会返回hahaBean实例
        return new HahaBean();
    }

    @Override
    public Class<?> getObjectType() {
        return HahaBean.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

//getBean()会通过doGetBean方法获取bean实例
public class SingleManApp {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(StartUp.class);
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        HahaBean myFactoryBean = (HahaBean) beanFactory.getBean("myFactoryBean");
        myFactoryBean.test();
    }
}
@SpringBootApplication
public class StartUp {
}

//最终返回的实例
public class HahaBean {
    public void test(){
        System.out.println("hahabean");
    }
}

dependsOn

Spring提供比如@DependsOn/depends-on用于控制bean初始化顺序,为了便于理解就不以’依赖’表示bean的关系,而是从逻辑上出发,A depends-on B,A的实例化需要B,则B优先于A进行实例化

// 检查是否存在类似于A depondson B,而B depends-on A 的情况
if (isDependent(beanName, dep)) {
    throw new BeanCreationException();
}
//将dep和beanName的depends-on关系注册到dependentBeanMap中
registerDependentBean(dep, beanName);
//先实例化当前bean depends-on的Bean
getBean(dep);


首先判断是否存在循环depends-on,保证不存在死循环问题,比如A dep B,B dep C,C dep A

//dependentBeanMap存放的是depends-on当前bean的实例集合
Map<String, Set<String>> dependentBeanMap;
//dependenciesForBeanMap存放当前优先于当前bean初始化的
Map<String, Set<String>> dependenciesForBeanMap;

//alreadySeen默认为null表示还没有检查过
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
    //表示已经检查过了
    if (alreadySeen != null && ((Set)alreadySeen).contains(beanName)) {
        return false;
    } else {
        //如果是别名则解析别名
        String canonicalName = this.canonicalName(beanName);
        //dependentBeanMap这个集合存放的bean应该是在当前bean实例化之后才进行初始化
        Set<String> dependentBeans = (Set)this.dependentBeanMap.get(canonicalName);
        if (dependentBeans == null) {
            return false;
            //但是dependentBeanName应该优先实例化的bean却在dependentBeans中这就会造成死循环
        } else if (dependentBeans.contains(dependentBeanName)) {
            return true;
        //这一步就是彻底找到 A - B,B - C,C - D,D - A 这种隔层 depends-on
        } else {
            Iterator var6 = dependentBeans.iterator();
            String transitiveDependency;
            do {
                if (!var6.hasNext()) {
                    return false;
                }
                transitiveDependency = (String)var6.next();
                if (alreadySeen == null) {
                    alreadySeen = new HashSet();
                }
                ((Set)alreadySeen).add(beanName);
            } while(!this.isDependent(transitiveDependency, dependentBeanName, (Set)alreadySeen));
            return true;
        }
    }
}


registerDependentBean:在实例化优先的bean实例之前还需要将相互顺序关系进行维护

//注意入参registerDependentBean(dep, beanName),实际deponds-on的bean位置换成了beanName
//为了方便理解还是按照依赖顺序将首先实例化的称为A(beanName),dependentBeanName称为B
public void registerDependentBean(String beanName, String dependentBeanName) {
    String canonicalName = this.canonicalName(beanName);
    // depends-on Bean的映射集合
    Map var4 = this.dependentBeanMap;
    //depends-on A的集合(顺序在A之后)
    Set dependenciesForBean;
    synchronized(this.dependentBeanMap) {
    	//java8新方法computeIfAbsent方法用来计算给定key,返回value映射值。如果,key并没有映射到一个值,或者映射到null,那么,就用这个value值放到这个hashmap中
    	//获取deponds-on A的集合
        dependenciesForBean = (Set)this.dependentBeanMap
        	.computeIfAbsent(canonicalName, (k) -> {
            	return new LinkedHashSet(8);
        });
        //将B维护到deponds-on A的集合
        if (!dependenciesForBean.add(dependentBeanName)) {
            return;
        }
    }
    //Bean depends-on的集合映射
    var4 = this.dependenciesForBeanMap;
    synchronized(this.dependenciesForBeanMap) {
    	//获取B depends-on的集合,并将A维护进去
        dependenciesForBean = (Set)this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, (k) -> {
            return new LinkedHashSet(8);
        });
        dependenciesForBean.add(canonicalName);
    }
}


getSingleton

单例bean的实例化流程

1.解析别名(如果有)获取bean的名字
2.如果scope为sigleton则从缓存中查询是否有这个bean,否则跳过
3.首次获取bean通过getSingleton创建bean的实例
4.标记这个bean已经被创建了(允许循环依赖则Spring通过三级缓存解决,提前将bean曝光)
5.递归获取依赖的bean并完成实例化
6.当前bean进行属性注入

在非懒加载bean随容器启动时,载单例bean首次访问时进行实例化,通过调用getBean访问getSingleton

if (mbd.isSingleton()) {
    //入参ObjectFactory通过getObject获取最终的实例
    sharedInstance = this.getSingleton(beanName, () -> {
        try {
            //实现ObjectFactory接口的getObject()方法
            return this.createBean(beanName, mbd, args);
        } catch (BeansException var5) {
            this.destroySingleton(beanName);
            throw var5;
        }
    });
    //判断创建的bean是否为factoryBean,如果是则通过factoryBean去创建实例
    bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}


Spring三级缓存解决循环依赖

只有单例bean且在earlySingletonExposure为true时(默认为true)才允许循环依赖的情况下才有二三级缓存

Spring 能解决的循环依赖有:通过 setter 注入的循环依赖、通过属性注入的循环依赖,当构造器出现循环依赖则无法解决,所以需要先用构造函数创建一个 “不完整” 的 bean 实例

//singletonObjects 一级缓存:实例化保存的单例 bean 对象
private final Map<String, Object> singletonObjects;
//earlySingletonObjects 二级缓存:还未进行属性填充 
private final Map<String, Object> earlySingletonObjects;
//singletonFactories 三级缓存:存放BeanName与bean工厂
private final Map<String, ObjectFactory<?>> singletonFactories;
//在Bean开始实例化时将bean存放,创建完成时会将其移出
private final Set<String> singletonsCurrentlyInCreation;
//Bean被创建完成后添加
private final Set<String> alreadyCreated;
//已经注册的单例bean,三级缓存中任意添加了都会同步添加到这里
private final Set<String> registeredSingletons

解决循环依赖的原理

1.满足条件下,比如有两个bean A和B循环依赖,在A实例化getBean时会暴露到三级缓存中,进行属性注入populate时发现依赖B,则先去实例化B;

2.B实例化过程中也会暴露到三级缓存中,在注入属性时又发现依赖于A;

3.此时再次访问getBean(A),由于A已经存在三级缓存,所以在获取A缓存时通过三级缓存获取A的原始bean添加到二级缓存中,并返回缓存的A实例,A注入到B;

4.B完成属性注入之后放入一级缓存中,然后A完成了属性的注入并获取了二级缓存,清除二级缓存放入一级缓存

singleton实例由实现ObjectFactory接口getObject方法返回createBean()实现

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Map var3 = this.singletonObjects;
    synchronized(this.singletonObjects) {
        //还是先从缓存中拿
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
            //当前bean是正在destruction状态,默认false
            if (this.singletonsCurrentlyInDestruction) {
                throw new BeanCreationNotAllowedException();
            }
            //创建实例前的验证
            //先校验beanName不是要在创建检查排除掉的(inCreationCheckExclusions缓存)
            //且添加到正在创建bean的缓存singletonsCurrentlyInCreation中,添加失败就表示已存在
            this.beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            try {
                //执行creatBean()方法,由入参singletonFactory中getObject方法返回
                //如果运行循环依赖则返回的是二级缓存
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            } finally {
                //从singletonsCurrentlyInCreation移除beanName
                this.afterSingletonCreation(beanName);
            }
            if (newSingleton) {
                /**创建新的Bean成功添加到一级缓存中,并移除二三级缓存
                    this.singletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                    this.earlySingletonObjects.remove(beanName);
                    this.registeredSingletons.add(beanName); //已注册的bean
                **/
                this.addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}


当earlySingletonExposure为true表示允许循环依赖从而添加一个三级缓存ObjectFactory

protected Object createBean(String beanName, RootBeanDefinition mbd,  Object[] args)  {
    RootBeanDefinition mbdToUse = mbd;
    //...
    //当存在InstantiationAwareBeanPostProcessor时执行处理器的applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitialization
    Object beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
    if (beanInstance != null) {
        return beanInstance;
    }
    //返回完整的Bean实例
    beanInstance = this.doCreateBean(beanName, mbdToUse, args);
    return beanInstance;
}

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
    //bean包装类
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        //如果是factoryBean则清除缓存
        instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        //创建Bean实例,进行包装,实现构造器依赖注入
        instanceWrapper = this.createBeanInstance(beanName, mbd, args);
    }
    //获取原始对象和其类型
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }
    //MergedBeanDefinitionPostProcessor,处理RootBeanDefinition
    //@Autowired通过子类AutowiredAnnotationBeanPostProcessor实现将标有注解的字段和方法放入缓存
    this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    //满足单例,允许循环依赖,正在实例创建中三个条件
    boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
    if (earlySingletonExposure) {
        //解决循环依赖,添加三级缓存singletonFactory,移出二级缓存
        //this.singletonFactories.put(beanName, singletonFactory);
        //this.earlySingletonObjects.remove(beanName);
        //this.registeredSingletons.add(beanName);
        this.addSingletonFactory(beanName, () -> {
            //实现SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法
            //可以实现AOP的逻辑,如果没有增强处理则三级缓存就是原始的bean
            return this.getEarlyBeanReference(beanName, mbd, bean);
        });
    }
    Object exposedObject = bean;
    //完成属性和方法的依赖注入
    this.populateBean(beanName, mbd, instanceWrapper);
    //bean增强,@PostConstruct>InitializingBean>init()
    //依次:处理aware接口,执行BeanPostProcessors中postProcessBeforeInitialization方法,调用初始化方法init-Methods,执行BeanPostProcessor的postProcessAfterInitialization方法
    exposedObject = this.initializeBean(beanName, exposedObject, mbd);
    //解决循环依赖
    if (earlySingletonExposure) {
        //调用重载的方法,在获取缓存时也访问的是这个方法,用于获取二级缓存
        Object earlySingletonReference = this.getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            //initializeBean没有处理bean则将二级缓存进行进行暴露
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
                //initializeBean处理之后会产生一个代理对象且有被依赖的bean
            } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                //将这些依赖exposedObject的bean数组移除,因为Bean已经不是原来的bean了
                String[] dependentBeans = this.getDependentBeans(beanName);
                ...
            }
        }
    }
    //注册用于销毁的bean,执行销毁操作的有三种:自定义destroy方法、DisposableBean接口、DestructionAwareBeanPostProcessor
    registerDisposableBeanIfNecessary(beanName, bean, mbd);
    return exposedObject;
}


通过三级缓存singletonObject获取二级缓存的重载的方法

---DefaultSingletonBeanRegistry
//allowEarlyReference表示是否允许从singletonFactories中通过getObject拿到对象,默认true
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	//从一级缓存中获取
    Object singletonObject = this.singletonObjects.get(beanName);
    //isSingletonCurrentlyInCreation表示正在进行创建中,且从一级缓存中未获取到实例
    if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
        Map var4 = this.singletonObjects;
        synchronized(this.singletonObjects) {
            singletonObject = this.earlySingletonObjects.get(beanName);
            //二级缓存也不存在且允许循环依赖
            if (singletonObject == null && allowEarlyReference) {
            	//获取ObjectFactory,从实例工厂获取实例
                ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                //允许循环依赖则会存在一个三级缓存
                if (singletonFactory != null) {
                	//通过这个三级缓存的getObject()方法实现,如果没有增强处理则是原始bean
                    singletonObject = singletonFactory.getObject();
                    //获取到了则添加到二级缓存中,并移除三级缓存的对象
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
	//这个getSingleton方法的重载就是从缓存获取bean实例,没有则去创建新的实例
    return singletonObject;
}

prototypes实例的创建

多例的缓存放在ThreadLocal缓存中,每个线程获取的都是通过getBean实例化的新对象,将 beanName 添加到 prototypesCurrentlyInCreation 缓存

private final ThreadLocal<Object> prototypesCurrentlyInCreation;

try {
    //实例化之前先添加缓存到当前线程中
    this.beforePrototypeCreation(beanName);
    prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
    //清除当前线程的缓存
    this.afterPrototypeCreation(beanName);
}

protected void beforePrototypeCreation(String beanName) {
    //prototype的bean的beanName集合
    Object curVal = this.prototypesCurrentlyInCreation.get();
    // 将ThreadLocal设置成当前的beanName
    if (curVal == null) {
        this.prototypesCurrentlyInCreation.set(beanName);
    }
    // 如果缓存不为空且为String类型,则表示只有一个beanName
    else if (curVal instanceof String) {
        Set<String> beanNameSet = new HashSet<String>(2);
        beanNameSet.add((String) curVal);
        beanNameSet.add(beanName);
        this.prototypesCurrentlyInCreation.set(beanNameSet);
    }
    // 如果存在多个beanName,将当前的beanName添加到Set
    else {
        Set<String> beanNameSet = (Set<String>) curVal;
        beanNameSet.add(beanName);
    }
}

initializeBean的顺序

完成属性注入之后执行initializeBean,先说结论,先通过处理器执行@PostConstruct注解标注的方法,通过invokeInitMethods先执行InitializingBean接口的afterPropertiesSet()方法,最后才执行init-method方法

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    //如果bean是aware实现类,则将beanName,beanFactory分别添加到BeanNameAware和BeanFactoryAware
    this.invokeAwareMethods(beanName, bean);
    Object wrappedBean; 
    //执行BeanPostProcessor的applyBeanPostProcessorsBeforeInitialization方法
    //InitDestroyAnnotationBeanPostProcessor在这一步会执行@PostConstruct标注的方法
    wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
	// 处理InitializingBean和init-method
    this.invokeInitMethods(beanName, wrappedBean, mbd);
    wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    return wrappedBean;
}

执行InitDestroyAnnotationBeanPostProcessor处理器时找到并invoke被标注的方法

//在方法上通过注解@PostConstruct标注为初始化的方法
//标注为初始化的方法
@PostConstruct
public void init(){
    System.out.println("init");
}
//销毁的方法
@PreDestroy
public void destroy(){
    System.out.println("destroy");
}

进入invokeInitMethods方法,首先会判断bean是否实现了InitializingBean,如果是则执行afterPropertiesSet()方法.下一步从initMethods获取init的方法,init-method是在xml解析时封装在beanDefinition的initMethods

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {
    //InitializingBean实现类完成初始化方法
    boolean isInitializingBean = bean instanceof InitializingBean;
    ((InitializingBean)bean).afterPropertiesSet();
	//init-method指定的初始化方法
    String initMethodName = mbd.getInitMethodName();
    this.invokeCustomInitMethod(beanName, bean, mbd);
}

//实现InitializingBean接口的afterPropertiesSet方法
@Service
public class TxService implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean");
    }
}

也可以通过@Bean指定init-method方法:

@Bean(initMethod = "init")
public InitService getInit(){
    return new InitService();
}
public class InitService {
    public void init(){
        System.out.println("init");
    }
}

属性注入

DI目的是在初始化对象时,根据对象中的属性依赖, 动态将容器中bean按需注入进去,无需手动维护依赖关系,比如两个交给spring管理的bean,其中A依赖B,这时就需要先实例化B并注入到A中,实现属性填充;

构造器注入

首先要回到doCreateBean方法中有一个createBeanInstance就是用于构造器注入

//构造器实例化
Object instance = constructor.newInstance();


根据beanName、mbd创建Bean实例,args是bean的构造函数参数,根据args选择不同的构造函数

//进入doCreateBean方法,通过createBeanInstance创建beanDefinition对应的包装实例
instanceWrapper = this.createBeanInstance(beanName, mbd, args);

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    //ClassUtils.forName(className, dynamicLoader);
    Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
    //理解为提供一个静态方法回调创建实例,比如static MyBean createMyBean(){new MyBean();}
    //beanDefinition.setInstanceSupplier(SupplierBean::createUser);
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return this.obtainFromSupplier(instanceSupplier, beanName);
    } else if (mbd.getFactoryMethodName() != null) {
        //使用工厂方法去创建实例
        return this.instantiateUsingFactoryMethod(beanName, mbd, args);
    } else {
        boolean resolved = false;
        boolean autowireNecessary = false;
        if (args == null) {
            //不为null,则表示缓存有被解析的构造器
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                //判断是否需要自动注入,默认是false
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
        //args为null
        if (resolved) {
            //true构造函数自动注入,false选择使用默认的构造函数
            return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
        } 
		//SmartInstantiationAwareBeanPostProcessor选择候选的构造函数
        //@Autowired就是通过子类AutowiredAnnotationBeanPostProcessor实现注入
        Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        //ctors不为空 || mbd的注入方式为AUTOWIRE_CONSTRUCTOR || mdb定义了构造函数的参数值 || args不为空,执行构造函数自动注入
        if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
            //理解为public的构造器
            ctors = mbd.getPreferredConstructors();
            //autowireConstructor自动注入的选举流程:优先public方法,根据入参的args参数个数(做解析返回最终的参数个数)找到符合参数大于或等于的候选构造器,instantiateBean没有args参数当然默认使用无参构造器;和autowireConstructor一样最后通过BeanUtils.instantiateClass(ctor, args)构建原始实例;
            return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
        } else {
            return this.autowireConstructor(beanName, mbd, ctors, args);
        }
    }
}

determineConstructorsFromBeanPostProcessors方法用于执行determineCandidateConstructors方法,主要的实现类有AutowiredAnnotationBeanPostProcessor,看处理器名字就知道是处理@Autowired,主要作用也是用于给定 bean 的候选构造函数,因为源码很长,包括处理器是如何加载到容器中,暂时留个坑,大致理解一下处理器determineCandidateConstructors方法的作用

1.处理@Lookup注解,如果一个单例BeanA依赖多例的BeanB,因为BeanA是单例,在初始化一次之后就放入缓存,所以BeanB也是beanA首次初始化依赖的beanB时所创建的实例;使用@Lookup注解标注在构造器方法或者普通方法用于生成子类去重写这个方法,每次调用时会去调子类则形成依赖的更新;将@Lookup方法添加到lookupMethodsChecked缓存

2.从candidateConstructorsCache.get(beanClass)缓存中获取已存在解析的构造器,否则继续通过放射方法getDeclaredConstructors获取类的所有构造器放入rawCandidates缓存

3.遍历所有构造器并进行分类缓存:
// 存放@Autowire注解的构造函数
List<Constructor<?>> candidates = new ArrayList<Constructor<?>>(rawCandidates.length);
// 存放@Autowire注解,并且require=true的构造函数
Constructor<?> requiredConstructor = null;
// 存放默认的构造函数
Constructor<?> defaultConstructor = null;

4.如果不存在required=true则将默认构造器放入candidates,然后将集合转为Constructor<?>[]数组,如果只有构造器且非默认则单独放入候选构造器数组,其他情况返回空new Constructor<?>[0]数组,封装到构造器缓存


以一个简单的实例来理解整个构造器注入依赖的流程:constructor-arg解析封装在ConstructorArgumentValues中,所以ConstructorArgumentValues有值时通过autowireConstructor方法选择构造器进行实例化,优先选择public作为候选构造器,获取到依赖的属性通过resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues)去创建依赖的sub实例,@Autowired用在构造器上主要是获取候选构造器

public class Super {
    private String name;
    private Sub sub;
    //构造器
    public Super(String name, Sub sub) {
        this.name = name;
        this.sub = sub;
    }
}

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
//当获取getBean时开始实例化
Object aSuper = context.getBean("super");

<!--构造器方式注入constructor-arg-->
<bean id="super" class="cn.mywork.spring.Super">
    <constructor-arg name="name" value="superName"/>
    <constructor-arg name="sub" ref="sub"/>
</bean>
<!--注入的对象-->
<bean id="sub" class="cn.mywork.spring.Sub">
    <property name="age" value="30"/>
</bean>


属性自动装配

如果是byName注入模式,则通过autowireByName方法调用getBean实例化依赖的Bean并注入到当前Bean

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    //PropertyValues对bean的属性值的封装,比如依赖的bean信息
    PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
    /*AutowireMode自动装配类型
        int AUTOWIRE_NO = 0;  默认装配模式,注解注入的方式
        int AUTOWIRE_BY_NAME = 1;  通过beanName注入依赖
        int AUTOWIRE_BY_TYPE = 2;  根据bean类型注入
        int AUTOWIRE_CONSTRUCTOR = 3; 构造器注入
    */
    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
        MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
        if (resolvedAutowireMode == 1) {
            /* 自动装配byName,将sub注入到Super中,只需要保证sub的beanName和属性名一致即可
            	public class Super{
            		private Sub sub1;
            	}
            	<bean id="super" class="com.xxx.Super" autowire="byName">
            	<bean id="sub1" class="com.xxx.Sub">
            */
            //获取依赖的属性名称作为beanName去getBean,再将依赖关系注册到bean的dependy-on的缓存中
            this.autowireByName(beanName, mbd, bw, newPvs);
        }
        /* 自动装配byType,通过sub属性类型Sub.class去匹配sub的bean并进行注册
        	通过doResolveDependency方法就是@Autowired查找bean的第一个方式,找到class类型对应
        	的所有bean,再根据条件进行筛选的依赖的bean注入,并将依赖关系注册到缓存中
         */
        if (resolvedAutowireMode == 2) {
            this.autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }
    //执行存在InstantiationAwareBeanPostProcessor的postProcessProperties方法
    //处理@Autowire标注的属性注入
    while(...) {
        pvs = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
    }
    //property属性注入
    this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}


注解@Autowired注入原理

回到doCreateBean,当构造器注入完成后继续往下执行applyMergedBeanDefinitionPostProcessors(),这个方法用于处理MergedBeanDefinitionPostProcessor处理器的postProcessMergedBeanDefinition,实现该处理器会将合并的BeanDefinition作为方法的参数进行增强

这一步的主要作用就是将被@Autowired标注的set方法和字段信息封装到metadata

this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
//子类AutowiredAnnotationBeanPostProcessor的实现,处理@Autowired
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    //在指定Bean中查找使用@Autowire注解的元数据
    //获取字段和set方法上的@Autowired注解信息(不支持static修饰的字段和方法)
    //方法获取descriptor.getWriteMethod()判断是否为set方法
    //method、required、pd封装成AutowiredMethodElement添加到InjectionMetadata缓存
    InjectionMetadata metadata = this.findAutowiringMetadata(beanName, beanType, (PropertyValues)null);
    metadata.checkConfigMembers(beanDefinition);
}

回到populateBean方法,完成byName自动装配后往下执行,通过postProcessProperties方法用于完成被@Autowired标注的属性注入/方法注入,实现注入的方法inject()有两个实现类,分别用于set方法和字段属性注入

protected void inject(Object target, String beanName,  PropertyValues pvs)  {}

字段属性注入优先通过属性的name作为BeanName去找bean缓存,如果没有缓存则根据classType去获取bean,在doResolveDependency方法中会进行详细查找依赖bean的过程:根据名称快速查找缓存,没有缓存则通过findAutowireCandidates根据类型 type 查找名称 beanNames作为候选,通过@Qualifier值进行筛选,和选择候选构造器一样;如果候选者个数大于1则继续判断@Primary(表示优先)和@Priority(数字越小优先级越高),从而选出最终注入的bean

// 设置字段访问性
ReflectionUtils.makeAccessible(field);
// 通过反射为属性赋值,将解析出来的bean实例赋值给field
field.set(bean, value);


@Resource先找默认的bean id(bean注册的时候不指定beanId则默认为类的简单名),如果接口有多个实现,则使用@Resource(name = “”)去指定,当注入的实例有多个实现类时,使用Resource

方法的注入:必须是set方法,在封装metadata时就通过内省的方式判断注解标注的方法是否为writeMethod(也就是set方法)

//内省机制
BeanInfo beanInfo = Introspector.getBeanInfo(superClass);
PropertyDescriptor[] ps = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd : ps){
    if (pd.getName().equals("name")){
        //set方法
        pd.getWriteMethod();
    }
}
//设置set方法的访问性
ReflectionUtils.makeAccessible(method);
//通过反射执行方法
method.invoke(bean, value);

PropertyValues属性注入

populateBean方法最后一步applyPropertyValues将所有PropertyValues中的属性填充到bean中,比如通过xml配置属性依赖注入,在loadBeanDefinitions解析配置项时便将属性值封装在PropertyValues中

<!-- 配置setter属性注入的标签为property->
<bean id="student" class="cn.mywork.spring.Student">
    <!--直接将值用value属性填入-->
    <property name="name" value="studentName"/>
    <!--对象引入,需要ref去引入bean的id-->
    <property name="sub" ref="sub"/>
    <!--基本类型的数组注入 array标签-->
    <property name="nums">
        <array>
            <value>1</value>
            <value>2</value>
            <value>3</value>
        </array>
    </property>
    <!--对象集合的注入list标签-->
    <property name="subList">
        <list>
            <ref bean="sub"/>
            <ref bean="sub"/>
        </list>
    </property>
    <!--map集合的注入 map标签-->
    <property name="superMap">
        <map>
            <entry key="key1" value-ref="super"/>
            <entry key="key2" value-ref="super"/>
        </map>
    </property>
</bean>

<!--注入的属性-->
<bean id="sub" class="cn.mywork.spring.Sub">
    <property name="age" value="20"/>
</bean>
<bean id="super" class="cn.mywork.spring.Super">
    <property name="name" value="superName"/>
</bean>

解析配置项的property属性类型,返回对应类型的值,核心方法就是setPropertyValues在很深入的内部进行实现,有BeanPropertyHandler方法注入和FieldPropertyHandler字段注入两种实现

//set方法进行属性注入
ReflectionUtils.makeAccessible(writeMethod);
writeMethod.invoke(BeanWrapperImpl.this.getWrappedInstance(), new Object[]{value});
//字段属性注入
ReflectionUtils.makeAccessible(this.field);
this.field.set(DirectFieldAccessor.this.getWrappedInstance(), value);

版权声明:本文为vanchine原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。