我的文章-Spring程序员

Spring-核心 2.bean加载过程分析

2018-03-01  本文已影响40人  飞翔的鲲

参考文章
https://www.cnblogs.com/fyx158497308/p/3977391.html
配置文件载入过程
http://www.iteye.com/topic/743997


Snipaste_2018-01-09_10-53-36.png
image.png

处理FactoryBean和普通bean

if(this.isFactoryBean(beanName)) {
                    final FactoryBean<?> factory = (FactoryBean)this.getBean("&" + beanName);
                    boolean isEagerInit;
                    if(System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = ((Boolean)AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                            public Boolean run() {
                                return Boolean.valueOf(((SmartFactoryBean)factory).isEagerInit());
                            }
                        }, this.getAccessControlContext())).booleanValue();
                    } else {
                        isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
                    }

                    if(isEagerInit) {
                        this.getBean(beanName);
                    }
                } else {
                    this.getBean(beanName);
                }

doGetBean()过程


20180113-162828.png
  1. 先试着从单例缓存对象里获取。

  2. 从父容器里取定义,有则由父容器创建。

  3. 如果是单例,则走单例对象的创建过程:在 spring 容器里单例对象和非单例对象的创建过程是一样的。都会调用父 类 AbstractAutowireCapableBeanFactory 的 createBean 方法。 不同的是单例对象只创建一次并且需要缓 存起来。 DefaultListableBeanFactory 的父类 DefaultSingletonBeanRegistry 提供了对单例对 象缓存等支持工作。所以是单例对象的话会调用 DefaultSingletonBeanRegistry 的 getSingleton 方法,它会间 接调用AbstractAutowireCapableBeanFactory 的 createBean 方法。

如果是 Prototype 多例则直接调用父类 AbstractAutowireCapableBeanFactory 的 createBean 方法。

  1. 先从缓存中拿bean,如果有再判断bean类型是否有FactoryBean,如果是则通过faxtorybean.getObject()方法获取普通bean。
  2. 如果没有就先创建bean,再处理获取bean

参考
http://blog.csdn.net/dlf123321/article/details/48155669

20180112-234444.png
20180113-012711.png
 public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
        if(bd.getMethodOverrides().isEmpty()) {
            Object var5 = bd.constructorArgumentLock;
            Constructor constructorToUse;
            synchronized(bd.constructorArgumentLock) {
                constructorToUse = (Constructor)bd.resolvedConstructorOrFactoryMethod;
                if(constructorToUse == null) {
                    final Class<?> clazz = bd.getBeanClass();
                    if(clazz.isInterface()) {
                        throw new BeanInstantiationException(clazz, "Specified class is an interface");
                    }

                    try {
                        if(System.getSecurityManager() != null) {
                            constructorToUse = (Constructor)AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
                                public Constructor<?> run() throws Exception {
                                    return clazz.getDeclaredConstructor((Class[])null);
                                }
                            });
                        } else {
                            constructorToUse = clazz.getDeclaredConstructor((Class[])null);
                        }

                        bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                    } catch (Exception var9) {
                        throw new BeanInstantiationException(clazz, "No default constructor found", var9);
                    }
                }
            }

            return BeanUtils.instantiateClass(constructorToUse, new Object[0]);
        } else {
            return this.instantiateWithMethodInjection(bd, beanName, owner);
        }
    }

三种生成实例化bean方式

  1. 构造方法
return clazz.getDeclaredConstructor((Class[])null);
  1. 反射生成bean
return BeanUtils.instantiateClass(constructorToUse, new Object[0]);
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
        Assert.notNull(ctor, "Constructor must not be null");

        try {
            ReflectionUtils.makeAccessible(actor)
            return ctor.newInstance(args);
        } catch (InstantiationException var3) {
            throw new BeanInstantiationException(ctor, "Is it an abstract class?", var3);
        } catch (IllegalAccessException var4) {
            throw new BeanInstantiationException(ctor, "Is the constructor accessible?", var4);
        } catch (IllegalArgumentException var5) {
            throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", var5);
        } catch (InvocationTargetException var6) {
            throw new BeanInstantiationException(ctor, "Constructor threw exception", var6.getTargetException());
        }
    }
  1. glib实现,动态代理
    instantiateWithMethodInjection()
public Object instantiate(Constructor<?> ctor, Object... args) {
            Class<?> subclass = this.createEnhancedSubclass(this.beanDefinition);
            Object instance;
            if(ctor == null) {
                instance = BeanUtils.instantiate(subclass);
            } else {
                try {
                    Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
                    instance = enhancedSubclassConstructor.newInstance(args);
                } catch (Exception var6) {
                    throw new BeanInstantiationException(this.beanDefinition.getBeanClass(), "Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", var6);
                }
            }

            Factory factory = (Factory)instance;
            factory.setCallbacks(new Callback[]{NoOp.INSTANCE, new CglibSubclassingInstantiationStrategy.LookupOverrideMethodInterceptor(this.beanDefinition, this.owner), new CglibSubclassingInstantiationStrategy.ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
            return instance;
        }

  1. bean创建完调用初始化方法

参考
http://blog.csdn.net/maclaren001/article/details/37039749

上一篇 下一篇

猜你喜欢

热点阅读