SpringFramework程序员首页投稿(暂停使用,暂停投稿)

【Spring】Ioc容器的实现(一)-- BeanFactor

2017-10-07  本文已影响177人  eejron

前言

Ioc容器作为spring的核心部分,希望通过学习其源码来了解Ioc运作机制。为了学习的方便,在此去掉那些复杂的xml和注解解析,而是全部使用Java代码的方式来学习它的运作机制。

使用Ioc时,我们一般有两种方式:

  1. BeanFactory
  2. ApplicationContext

两者的区别在前者更多是使用在懒加载的场景下,而后者则是非懒加载的方式,在这里我们先学习第一种的实现方式。

Example

public class BeanFactoryIoc {

    public static void main(String[] args) {
        
        //1、创建个bean工厂
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //2、创建一个bean的定义
        GenericBeanDefinition bd = new GenericBeanDefinition();
        //定义属性
        MutablePropertyValues mpvs = new MutablePropertyValues();
        PropertyValue pv = new PropertyValue("name","Cat");
        mpvs.addPropertyValue(pv);
        //设置bean的类型和属性
        bd.setPropertyValues(mpvs);
        bd.setBeanClass(Animal.class);
        //3、将定义好bean注册到容器
        beanFactory.registerBeanDefinition("animal", bd);
        beanFactory.preInstantiateSingletons();
        //4、使用bean
        Animal animal = (Animal) beanFactory.getBean("animal");
        animal.say();
    }

    public static class Animal {

        private String name;

        public Animal() {
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void say(){
            System.out.println("Hello " + name);
        }
    }
}

BeanDefinition

BeanDefinition与Bean区别:前者是用来定义Bean的(Bean是什么类型的,属性有哪些,属性值又是什么),而后者则是Bean本身。

从第2步看起,GenericBeanDefinition是bean的基本定义,如下是它的主要结构(省略了部分的继承关系及实现的接口),看下AbstractBeanDefinition,beanClass是bean是 属于哪种类型,propertyValuess是bean的属性集,里面定义了bean的属性名称及其值。通过知道一个bean是什么类型及bean的属性就可以确定定义下bean了。源码如下:

public class GenericBeanDefinition extends AbstractBeanDefinition{

}

public abstract class AbstractBeanDefinition implements BeanDefinition{
    private volatile Object beanClass;
    private MutablePropertyValues propertyValues;           
}

public class MutablePropertyValues {
    private final List<PropertyValue> propertyValueList;
}

public class PropertyValue {
    private final String name;
    private final Object value;
}

BeanDefinition的注册

第3步则时将BeanDefinition注册到bean工厂中,由bean工厂来管理bean。来看下DefaultListableBeanFactory的继承关系,registerBeanDefinition方法是在接口BeanDefinitionRegistry里面声明的。源码如下:

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {


    //key为bean的名称,value为bean的具体定义,仅仅是定义,而非实例化好的对象
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);


    //bean的名称列表
    private volatile List<String> beanDefinitionNames = new ArrayList<>(256);


    //根据类型获取bean实例,在单例模式下,该bean实例已经创建过则获取已经创建的,否则重新创建一个bean
    public <T> T getBean(Class<T> requiredType) throws BeansException {
        return getBean(requiredType, (Object[]) null);
    }

    @Override
    public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {
        NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);
        if (namedBean != null) {
            return namedBean.getBeanInstance();
        }
        BeanFactory parent = getParentBeanFactory();
        if (parent != null) {
            return (args != null ? parent.getBean(requiredType, args) : parent.getBean(requiredType));
        }
        throw new NoSuchBeanDefinitionException(requiredType);
    }



    //注册bean的定义
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {

        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");
         
         //校验BeanDefinition是否合法
        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {
                ((AbstractBeanDefinition) beanDefinition).validate();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                        "Validation of bean definition failed", ex);
            }
        }

        BeanDefinition oldBeanDefinition;

        oldBeanDefinition = this.beanDefinitionMap.get(beanName);
        //判断BeanDefinition是否注册过
        if (oldBeanDefinition != null) {//已注册过,则输出一些日志,并覆盖原有的BeanDefinition
            if (!isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                        "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
                        "': There is already [" + oldBeanDefinition + "] bound.");
            }
            else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
                // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
                            "' with a framework-generated bean definition: replacing [" +
                            oldBeanDefinition + "] with [" + beanDefinition + "]");
                }
            }
            else if (!beanDefinition.equals(oldBeanDefinition)) {
                if (this.logger.isInfoEnabled()) {
                    this.logger.info("Overriding bean definition for bean '" + beanName +
                            "' with a different definition: replacing [" + oldBeanDefinition +
                            "] with [" + beanDefinition + "]");
                }
            }
            else {
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Overriding bean definition for bean '" + beanName +
                            "' with an equivalent definition: replacing [" + oldBeanDefinition +
                            "] with [" + beanDefinition + "]");
                }
            }
            
            //覆盖已注册的BeanDefinition
            this.beanDefinitionMap.put(beanName, beanDefinition);
        }
        else {//没有注册过,则将新的BeanDefinition添加进去
            if (hasBeanCreationStarted()) {//已启动状态,使用CopyAndWrite思想注册新的BeanDefinition
                synchronized (this.beanDefinitionMap) {
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    updatedDefinitions.add(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                    if (this.manualSingletonNames.contains(beanName)) {
                        Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
                        updatedSingletons.remove(beanName);
                        this.manualSingletonNames = updatedSingletons;
                    }
                }
            }
            else {//如果还是开始状态,则直接注册,不需要锁
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                this.manualSingletonNames.remove(beanName);
            }
            this.frozenBeanDefinitionNames = null;
        }

    }
    
    //非懒加载方式实例化bean
    @Override
    public void preInstantiateSingletons() throws BeansException {
    
        List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

        //遍历BeanDefinition,将符合条件的bean全部实例化
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                            @Override
                            public Boolean run() {
                                return ((SmartFactoryBean<?>) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
                else {
                    //非懒加载的方式实例化bean同样也是调用getBean方法
                    getBean(beanName);
                }
            }
        }
    }
    
}

注册时整个代码重点其实就是this.beanDefinitionMap.put(beanName, beanDefinition);这一行代码。因为注册时只是把bean的信息注册,而不是把bean实例注册,所以,在这个代码段里,BeanFactory的注册BeanDefinition是一种懒加载的方式,因为此时并没有实例化bean,只有需要到bean具体实例的时候才实例化bean,并提供给外部使用。

当然,BeanFactory也有非懒加载的方式,当使用非懒加载方式时,需要我们在获取bean之前先调用preInstantiateSingletons()方法,它跟懒加载方式获取bean都是调用getBean()方法,该方法调用时会将bean实例化并缓存一起来,只不过它是预先调用而已。

总结

整个流程其实就两步:

  1. BeanDefinition注册
  2. 根据BeanDefinition生成Bean实例

引用BeanDefinition的注册,而不是注册Bean实例,Ioc容器可以根据Bean的作用域灵活地生成单例Bean,还是非单例的。同时还能灵活的的解决了是否使用懒加载的方式。

ApplicationContext也是Ioc容器的实现,只不过它实现了更多更强大的功能,且是非懒加载的方式而已,它的底层实现其实还是BeanFactory,后文再做分析。

上一篇 下一篇

猜你喜欢

热点阅读