【spring源码】bean的实例化(转载)

首先来看一段代码,看过上一节的朋友肯定对这段代码并不陌生。这一段代码诠释了Spring加载bean的完整过程,包括读取配置文件,扫描包,加载类,实例化bean,注入bean属性依赖。

 
public void refresh() throws BeansException, IllegalStateException {  
    synchronized (this.startupShutdownMonitor) {  
        // Prepare this context for refreshing.  
        prepareRefresh();  
  
        // Tell the subclass to refresh the internal bean factory.  
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  
  
        // Prepare the bean factory for use in this context.  
        prepareBeanFactory(beanFactory);  
  
        try {  
            // Allows post-processing of the bean factory in context subclasses.  
            postProcessBeanFactory(beanFactory);  
  
            // Invoke factory processors registered as beans in the context.  
            invokeBeanFactoryPostProcessors(beanFactory);  
  
            // Register bean processors that intercept bean creation.  
            registerBeanPostProcessors(beanFactory);  
  
            // Initialize message source for this context.  
            initMessageSource();  
  
            // Initialize event multicaster for this context.  
            initApplicationEventMulticaster();  
  
            // Initialize other special beans in specific context subclasses.  
            onRefresh();  
  
            // Check for listener beans and register them.  
            registerListeners();  
  
            // Instantiate all remaining (non-lazy-init) singletons.  
            finishBeanFactoryInitialization(beanFactory);  
  
            // Last step: publish corresponding event.  
            finishRefresh();  
        }  
    }  
}  
 

 

上一节介绍了Spring是如何加载class文件的,本节主要围绕finishBeanFactoryInitialization(beanFactory)方法,聊聊Spring是如何实例化bean的,从上面代码片段中的注解不难看出,此方法主要的任务就是实例化非懒加载的单例bean。闲话少叙,看代码。

 

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {  
    // Initialize conversion service for this context.  
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&  
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {  
        beanFactory.setConversionService(  
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));  
    }  
  
    // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.  
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);  
    for (String weaverAwareName : weaverAwareNames) {  
        getBean(weaverAwareName);  
    }  
  
    // Stop using the temporary ClassLoader for type matching.  
    beanFactory.setTempClassLoader(null);  
  
    // Allow for caching all bean definition metadata, not expecting further changes.  
    beanFactory.freezeConfiguration();  
  
    // Instantiate all remaining (non-lazy-init) singletons.  
    beanFactory.preInstantiateSingletons();  
}  
 

 

 

上面代码主要看最后一句beanFactory.preInstantiateSingletons()

 
public void preInstantiateSingletons() throws BeansException {  
    if (this.logger.isDebugEnabled()) {  
        this.logger.debug("Pre-instantiating singletons in " + this);  
    }  
    List<String> beanNames;  
    synchronized (this.beanDefinitionMap) {  
        // Iterate over a copy to allow for init methods which in turn register new bean definitions.  
        // While this may not be part of the regular factory bootstrap, it does otherwise work fine.  
        beanNames = new ArrayList<String>(this.beanDefinitionNames);  
    }  
    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 {  
                getBean(beanName);  
            }  
        }  
    }  
}  
 

 

此方法首先将加载进来的beanDefinitionNames循环分析,如果是我们自己配置的bean就会走else中的getBean(beanName),接着看。

 

@Override  
public Object getBean(String name) throws BeansException {  
    return doGetBean(name, null, null, false);  
}  
 

 

doGetBean方法内容太多,一段一段看。

 

 
protected <T> T doGetBean(  
        final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)  
        throws BeansException {  
  
    final String beanName = transformedBeanName(name);  
    Object bean;  
  
    // Eagerly check singleton cache for manually registered singletons.  
    Object sharedInstance = getSingleton(beanName);  
    if (sharedInstance != null && args == null) {  
        if (logger.isDebugEnabled()) {  
            if (isSingletonCurrentlyInCreation(beanName)) {  
                logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +  
                        "' that is not fully initialized yet - a consequence of a circular reference");  
            }  
            else {  
                logger.debug("Returning cached instance of singleton bean '" + beanName + "'");  
            }  
        }  
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);  
    }  

 

 

这里主要看Object sharedInstance = getSingleton(beanName)

 

protected Object getSingleton(String beanName, boolean allowEarlyReference) {  
    Object singletonObject = this.singletonObjects.get(beanName);  
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {  
        synchronized (this.singletonObjects) {  
            singletonObject = this.earlySingletonObjects.get(beanName);  
            if (singletonObject == null && allowEarlyReference) {  
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);  
                if (singletonFactory != null) {  
                    singletonObject = singletonFactory.getObject();  
                    this.earlySingletonObjects.put(beanName, singletonObject);  
                    this.singletonFactories.remove(beanName);  
                }  
            }  
        }  
    }  
    return (singletonObject != NULL_OBJECT ? singletonObject : null);  
}  
 

 

这里能看到,Spring会把实例化好的bean存入singletonObjects,这是一个ConcurrentHashMap, 

private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);  

 

 

当然这里我们bean并未实例化过,所以这里应该也不能get出什么东西来,也就是返回null了。if子句也就不会执行了。那么接着看else子句的内容。

 

 
else {  
    // Fail if we're already creating this bean instance:  
    // We're assumably within a circular reference.  
    if (isPrototypeCurrentlyInCreation(beanName)) {  
        throw new BeanCurrentlyInCreationException(beanName);  
    }  
  
    // Check if bean definition exists in this factory.  
    BeanFactory parentBeanFactory = getParentBeanFactory();  
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {  
        // Not found -> check parent.  
        String nameToLookup = originalBeanName(name);  
        if (args != null) {  
            // Delegation to parent with explicit args.  
            return (T) parentBeanFactory.getBean(nameToLookup, args);  
        }  
        else {  
            // No args -> delegate to standard getBean method.  
            return parentBeanFactory.getBean(nameToLookup, requiredType);  
        }  
    }  
 

 

这两条验证也都不会实现,接写来就是重点了。

 

 
try {  
    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);  
    checkMergedBeanDefinition(mbd, beanName, args);  
  
    // Guarantee initialization of beans that the current bean depends on.  
    String[] dependsOn = mbd.getDependsOn();  
    if (dependsOn != null) {  
        for (String dependsOnBean : dependsOn) {  
            if (isDependent(beanName, dependsOnBean)) {  
                throw new BeanCreationException("Circular depends-on relationship between '" +  
                        beanName + "' and '" + dependsOnBean + "'");  
            }  
            registerDependentBean(dependsOnBean, beanName);  
            getBean(dependsOnBean);  
        }  
    }  
  
    // Create bean instance.  
    if (mbd.isSingleton()) {  
        sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {  
            @Override  
            public Object getObject() throws BeansException {  
                try {  
                    return createBean(beanName, mbd, args);  
                }  
                catch (BeansException ex) {  
                    // Explicitly remove instance from singleton cache: It might have been put there  
                    // eagerly by the creation process, to allow for circular reference resolution.  
                    // Also remove any beans that received a temporary reference to the bean.  
                    destroySingleton(beanName);  
                    throw ex;  
                }  
            }  
        });  
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);  
    }  
  
    else if (mbd.isPrototype()) {  
        // It's a prototype -> create a new instance.  
        Object prototypeInstance = null;  
        try {  
            beforePrototypeCreation(beanName);  
            prototypeInstance = createBean(beanName, mbd, args);  
        }  
        finally {  
            afterPrototypeCreation(beanName);  
        }  
        bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);  
    }  
  
    else {  
        String scopeName = mbd.getScope();  
        final Scope scope = this.scopes.get(scopeName);  
        if (scope == null) {  
            throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");  
        }  
        try {  
            Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {  
                @Override  
                public Object getObject() throws BeansException {  
                    beforePrototypeCreation(beanName);  
                    try {  
                        return createBean(beanName, mbd, args);  
                    }  
                    finally {  
                        afterPrototypeCreation(beanName);  
                    }  
                }  
            });  
            bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);  
        }  
        catch (IllegalStateException ex) {  
            throw new BeanCreationException(beanName,  
                    "Scope '" + scopeName + "' is not active for the current thread; " +  
                    "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",  
                    ex);  
        }  
    }  
}  
 

 

在这里拿到RootBeanDefinition并check,并获得bean的依赖,并循环迭代实例化bean。例如class A依赖于class B,就会先实例化B。下面的if ... else ...就是真正实例化bean的地方。其实真正实例化bean的方法是createBean(beanName, mbd, args),只是区分了isSingletonisPrototype,两者的区别在于,单例的(Singleton)被缓存起来,而Prototype是不用缓存的。首先看一下createBean(beanName, mbd, args)createBean方法中除了做了一些实例化bean前的检查准备工作外,最核心的方法就是

 

 
Object beanInstance = doCreateBean(beanName, mbd, args);  
 

 

由于这个过程涉及到的代码都是一大坨,就不贴出所有代码了。

 
BeanWrapper instanceWrapper = null;  
if (mbd.isSingleton()) {  
    instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);  
}  
if (instanceWrapper == null) {  
    instanceWrapper = createBeanInstance(beanName, mbd, args);  
}  
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);  
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);  
 

 

首先就是创建一个bean的实例且封装到BeanWrapper中,在这里bean已经实例化了。具体的实现方法是在org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner)中。

 
@Override  
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {  
    // Don't override the class with CGLIB if no overrides.  
    if (beanDefinition.getMethodOverrides().isEmpty()) {  
        Constructor<?> constructorToUse;  
        synchronized (beanDefinition.constructorArgumentLock) {  
            constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;  
            if (constructorToUse == null) {  
                final Class<?> clazz = beanDefinition.getBeanClass();  
                if (clazz.isInterface()) {  
                    throw new BeanInstantiationException(clazz, "Specified class is an interface");  
                }  
                try {  
                    if (System.getSecurityManager() != null) {  
                        constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {  
                            @Override  
                            public Constructor<?> run() throws Exception {  
                                return clazz.getDeclaredConstructor((Class[]) null);  
                            }  
                        });  
                    }  
                    else {  
                        constructorToUse =  clazz.getDeclaredConstructor((Class[]) null);  
                    }  
                    beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;  
                }  
                catch (Exception ex) {  
                    throw new BeanInstantiationException(clazz, "No default constructor found", ex);  
                }  
            }  
        }  
        return BeanUtils.instantiateClass(constructorToUse);  
    }  
    else {  
        // Must generate CGLIB subclass.  
        return instantiateWithMethodInjection(beanDefinition, beanName, owner);  
    }  
}  
 

 

在这里不难看出实例化分两种情况,如果没有无参构造器是就生成CGLIB子类,否则就直接反射成实例。

 
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {  
    Assert.notNull(ctor, "Constructor must not be null");  
    try {  
        ReflectionUtils.makeAccessible(ctor);  
        return ctor.newInstance(args);  
    }  

 

 

既然已经有了实例对象了,那么,Spring是如何将bean的属性注入到bean的呢?返回到上面的doCreateBean方法中。往下看找到populateBean(beanName, mbd, instanceWrapper);,内幕就在这里。只贴部分代码:

 
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();  
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);  
  
if (hasInstAwareBpps || needsDepCheck) {  
    PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);  
    if (hasInstAwareBpps) {  
        for (BeanPostProcessor bp : getBeanPostProcessors()) {  
            if (bp instanceof InstantiationAwareBeanPostProcessor) {  
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;  
                pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);  
                if (pvs == null) {  
                    return;  
                }  
            }  
        }  
    }  
    if (needsDepCheck) {  
        checkDependencies(beanName, mbd, filteredPds, pvs);  
    }  
}  
 

 

这里是调用InstantiationAwareBeanPostProcessor的具体子类的ibp.postProcessPropertyValues方法注入属性。当我们使用@Resource注解的时候,具体的子类是CommonAnnotationBeanPostProcessor;如果使用的是@Autowired注解,则具体的子类是AutowiredAnnotationBeanPostProcessor。此方法内是委托InjectionMetadata对象来完成属性注入。

 
@Override  
public PropertyValues postProcessPropertyValues(  
        PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {  
  
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass());  
    try {  
        metadata.inject(bean, beanName, pvs);  
    }  
    catch (Throwable ex) {  
        throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);  
    }  
    return pvs;  
}  
 

 

findAutowiringMetadata方法能拿到使用了特定注解的属性(Field)、方法(Method)及依赖的关系保存到checkedElements集合<Set>里,然后再执行自己的inject方法。

 
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {  
    Collection<InjectedElement> elementsToIterate =  
            (this.checkedElements != null ? this.checkedElements : this.injectedElements);  
    if (!elementsToIterate.isEmpty()) {  
        boolean debug = logger.isDebugEnabled();  
        for (InjectedElement element : elementsToIterate) {  
            if (debug) {  
                logger.debug("Processing injected method of bean '" + beanName + "': " + element);  
            }  
            element.inject(target, beanName, pvs);  
        }  
    }  
}  
 

 

真正干事的还是InjectedElementinject方法。

 
@Override  
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {  
    Field field = (Field) this.member;  
    try {  
        Object value;  
        if (this.cached) {  
            value = resolvedCachedArgument(beanName, this.cachedFieldValue);  
        }  
        else {  
            DependencyDescriptor desc = new DependencyDescriptor(field, this.required);  
            desc.setContainingClass(bean.getClass());  
            Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);  
            TypeConverter typeConverter = beanFactory.getTypeConverter();  
            value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);  
            synchronized (this) {  
                if (!this.cached) {  
                    if (value != null || this.required) {  
                        this.cachedFieldValue = desc;  
                        registerDependentBeans(beanName, autowiredBeanNames);  
                        if (autowiredBeanNames.size() == 1) {  
                            String autowiredBeanName = autowiredBeanNames.iterator().next();  
                            if (beanFactory.containsBean(autowiredBeanName)) {  
                                if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {  
                                    this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName);  
                                }  
                            }  
                        }  
                    }  
                    else {  
                        this.cachedFieldValue = null;  
                    }  
                    this.cached = true;  
                }  
            }  
        }  
        if (value != null) {  
            ReflectionUtils.makeAccessible(field);  
            field.set(bean, value);  
        }  
    }  
    catch (Throwable ex) {  
        throw new BeanCreationException("Could not autowire field: " + field, ex);  
        }  
    }  
}  
 

 

其实别看代码这么多,最关键的部分就是:

 
if (value != null) {  
    ReflectionUtils.makeAccessible(field);  
    field.set(bean, value);  
}  
 

 

在这里也就真相大白了,就是通过JDK反射特性,直接set值的。

posted @ 2017-09-10 15:43  码农阿当lodor  阅读(231)  评论(0编辑  收藏  举报