`

spring beans源码解读

 
阅读更多
spring Ioc容器的实现,从根源上是beanfactory,但真正可以作为一个可以独立使用的ioc容器还是DefaultListableBeanFactory,因此可以这么说,
DefaultListableBeanFactory 是整个spring ioc的始祖,研究透它的前生今世对我们理解spring ioc的概念有着重要的作用。

1. DefaultListableBeanFactory的作用:

默认实现了ListableBeanFactory和BeanDefinitionRegistry接口,基于bean definition对象,是一个成熟的bean factroy。

最典型的应用是:在访问bean前,先注册所有的definition(可能从bean definition配置文件中)。使用预先建立的bean定义元数据对象,从本地的bean definition表中查询bean definition因而将不会花费太多成本。

DefaultListableBeanFactory既可以作为一个单独的beanFactory,也可以作为自定义beanFactory的父类。

注意:特定格式bean definition的解析器可以自己实现,也可以使用原有的解析器,如:

PropertiesBeanDefinitionReader和XmLBeanDefinitionReader。

2. DefaultListableBeanFactory的继承关系

       (图片来源:http://www.myexception.cn/software-architecture-design/925888.html)

3. 好了,开始进入DefaultListableBeanFactory的大千世界

   直接继承关系:

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

   3.1 静态方法

复制代码
    private static Class<?> javaxInjectProviderClass = null;

    static {
        try {
            javaxInjectProviderClass =
                    ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
        }
        catch (ClassNotFoundException ex) {
            // JSR-330 API not available - Provider interface simply not supported then.
        }
    }
复制代码

spring提供一些实用的综合工具类如ClassUtils,ClassUtils提供了对类的实用方法,主要用在框架内部,想要了解更全面的类的工具方法可以参考apache commons lang。

Commons Lang
The standard Java libraries fail to provide enough methods for manipulation of its core classes. Apache Commons Lang provides these extra methods.

Lang provides a host of helper utilities for the java.lang API, notably String manipulation methods, basic numerical methods, object reflection, concurrency, creation and serialization and System properties. Additionally it contains basic enhancements to java.util.Date and a series of utilities dedicated to help with building methods, such as hashCode, toString and equals
ClassUtils.forName方法是class.forname的重写,返回一个类的实例,区别请参考源码。

上述静态方法中返回了javax.inject.Provider的一个实例,那么我们揭开javax.inject.Provider的面纱看看它到底起了什么作用。

语法:public interface Provider<T>

提供了一个 T的实例. 通常作为一个依赖注入容器器的父接口. 可以注入任何类型的 T, 当然也可以注入 Provider<T>. 相对于直接注入 T,注入 Provider<T>有如下作用:

  • 检索多个实例.
  • 延迟或者选择性的检索一个实例.
  • 打破循环依赖.
  • 抽象的scope,可以从一个包含scope的更小的scope中检索一个实例。

实例代码:

复制代码
   class Car {
     @Inject Car(Provider<Seat> seatProvider) {
       Seat driver = seatProvider.get();
       Seat passenger = seatProvider.get();
       ...
     }
   }
复制代码

3.2 继承自AbstractAutowireCapableBeanFactory的方法:

AbstractAutowireCapableBeanFactory的作用:

提供bean的创建 (有construct方法), 属性注值, 绑定 (包括自动绑定)和初始化.

处理运行时bean引用, 解析管理的集合, 调用初始化方法。

最主要的子类要实现的模板方法是 AutowireCapableBeanFactory.resolveDependency(DependencyDescriptor, String, Set, TypeConverter), 这个方法用来实现类型的自动绑定.

在DefaultListableBeanFactory中实现了AbstractAutowireCapableBeanFactory.copyConfigurationFrom

复制代码
    @Override
    public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
        super.copyConfigurationFrom(otherFactory);
        if (otherFactory instanceof DefaultListableBeanFactory) {
            DefaultListableBeanFactory otherListableFactory = (DefaultListableBeanFactory) otherFactory;
            this.allowBeanDefinitionOverriding = otherListableFactory.allowBeanDefinitionOverriding;
            this.allowEagerClassLoading = otherListableFactory.allowEagerClassLoading;
            this.autowireCandidateResolver = otherListableFactory.autowireCandidateResolver;
            this.resolvableDependencies.putAll(otherListableFactory.resolvableDependencies);
        }
    }
复制代码

其中:

allowBeanDefinitionOverriding定义了是否允许同名的不同bean definition再次进行注册;

allowEagerClassLoading 定义了是否允许eager类(相对于lazy)的加载,甚至延迟初始化的bean的加载。

autowireCandidateResolver是一个策略接口,用来决定一个特定的bean definition 是否满足做一个特定依赖的自动绑定的候选项,方法如下所示:

复制代码

//SimpleAutowireCandidateResolver implements AutowireCandidateResolver
@Override 
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) { 
return bdHolder.getBeanDefinition().isAutowireCandidate();
    }
//GenericTypeAwareAutowireCandidateResolver implements AutowireCandidateResolver
@Override 
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
if (!bdHolder.getBeanDefinition().isAutowireCandidate()) {
            // if explicitly false, do not proceed with any other checks
            return false;
        }
        return (descriptor == null || checkGenericTypeMatch(bdHolder, descriptor));
    }
复制代码

resolvableDependencies:定义了依赖类型和其对应的自动绑定值的键值对集合。

AbstractAutowireCapableBeanFactory的copyConfigurationFrom方法:

复制代码
    @Override
    public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
        super.copyConfigurationFrom(otherFactory);
        if (otherFactory instanceof AbstractAutowireCapableBeanFactory) {
            AbstractAutowireCapableBeanFactory otherAutowireFactory =
                    (AbstractAutowireCapableBeanFactory) otherFactory;
            this.instantiationStrategy = otherAutowireFactory.instantiationStrategy;
            this.allowCircularReferences = otherAutowireFactory.allowCircularReferences;
            this.ignoredDependencyTypes.addAll(otherAutowireFactory.ignoredDependencyTypes);
            this.ignoredDependencyInterfaces.addAll(otherAutowireFactory.ignoredDependencyInterfaces);
        }
    }
复制代码

其中,instantiationStrategy 为创建bean 实例的策略,默认值:

private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

allowCircularReferences 确定是否自动尝试去解析循环引用的bean。

ignoredDependencyTypes 定义了在依赖检查和自动绑定时要忽略的依赖类型,是一组类对象,例如string,默认为没有。

ignoredDependencyInterfaces  定义了在依赖检查和自动绑定时要忽略的依赖接口,是一组类对象,默认情况下,只有beanFactory接口被忽略。

父类AbstractBeanFactory的copyConfigurationFrom的实现如下:

复制代码
    @Override
    public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
        Assert.notNull(otherFactory, "BeanFactory must not be null");
        setBeanClassLoader(otherFactory.getBeanClassLoader());
        setCacheBeanMetadata(otherFactory.isCacheBeanMetadata());
        setBeanExpressionResolver(otherFactory.getBeanExpressionResolver());
        if (otherFactory instanceof AbstractBeanFactory) {
            AbstractBeanFactory otherAbstractFactory = (AbstractBeanFactory) otherFactory;
            this.customEditors.putAll(otherAbstractFactory.customEditors);
            this.propertyEditorRegistrars.addAll(otherAbstractFactory.propertyEditorRegistrars);
            this.beanPostProcessors.addAll(otherAbstractFactory.beanPostProcessors);
            this.hasInstantiationAwareBeanPostProcessors = this.hasInstantiationAwareBeanPostProcessors ||
                    otherAbstractFactory.hasInstantiationAwareBeanPostProcessors;
            this.hasDestructionAwareBeanPostProcessors = this.hasDestructionAwareBeanPostProcessors ||
                    otherAbstractFactory.hasDestructionAwareBeanPostProcessors;
            this.scopes.putAll(otherAbstractFactory.scopes);
            this.securityContextProvider = otherAbstractFactory.securityContextProvider;
        }
        else {
            setTypeConverter(otherFactory.getTypeConverter());
        }
    }
复制代码

其中

customEditors 是自定义的属性编辑器,适用于该beanFactory的所有bean。
propertyEditorRegistrars属性编辑器的注册器,使用于该beanFactory的所有bean。
beanPostProcessors 创建bean时应用的beanPostProcessors。
hasInstantiationAwareBeanPostProcessors 表明是否注册有任何的InstantiationAwareBeanPostProcessors。
hasDestructionAwareBeanPostProcessors表明是否注册有任何的DestructionAwareBeanPostProcessors
scopes:域标识符和对应域的键值对集合。

securityContextProvider 运行SecurityManager时使用的security context。

3.3 继承自ListableBeanFactory接口的方法
ListableBeanFactory是beanFactory接口的扩展接口,它可以枚举所有的bean实例,而不是客户端通过名称一个一个的查询得出所有的实例。要预加载所有的bean定义的beanfactory可以实现这个接口来。该 接口定义了访问容器中Bean基本信息的若干方法,如查看Bean的个数、获取某一类型Bean的配置名、查看容器中是否包括某一Bean等方法;
复制代码
containsBeanDefinition(String beanName) 
Check if this bean factory contains a bean definition with the given name. 

findAnnotationOnBean(String beanName, Class<A> annotationType) 
Find a Annotation of annotationType on the specified bean, traversing its interfaces and super classes if no annotation can be found on the given class itself. 

getBeanDefinitionCount() 
Return the number of beans defined in the factory. 

getBeanDefinitionNames() 
Return the names of all beans defined in this factory. 

getBeanNamesForType(Class<?> type) 
Return the names of beans matching the given type (including subclasses), judging from either bean definitions or the value of getObjectType in the case of FactoryBeans. 

getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) 
Return the names of beans matching the given type (including subclasses), judging from either bean definitions or the value of getObjectType in the case of FactoryBeans. 

getBeansOfType(Class<T> type) 
Return the bean instances that match the given object type (including subclasses), judging from either bean definitions or the value of getObjectType in the case of FactoryBeans. 

getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) 
Return the bean instances that match the given object type (including subclasses), judging from either bean definitions or the value of getObjectType in the case of FactoryBeans. 

getBeansWithAnnotation(Class<? extends Annotation> annotationType) 
Find all beans whose Class has the supplied Annotation type.
复制代码

3.4 继承自ConfigurableListableBeanFactory接口的方法
ConfigurableListableBeanFactory 它同时继承了ListableBeanFactory,AutowireCapableBeanFactory和ConfigurableBeanFactory,提供了对bean定义的分析和修改的便利方法,同时也提供了对单例的预实例化。
复制代码
void freezeConfiguration() 
Freeze all bean definitions, signalling that the registered bean definitions will not be modified or post-processed any further. 

BeanDefinition getBeanDefinition(String beanName) 
Return the registered BeanDefinition for the specified bean, allowing access to its property values and constructor argument value (which can be modified during bean factory post-processing). 

void ignoreDependencyInterface(Class<?> ifc) 
Ignore the given dependency interface for autowiring. 

void ignoreDependencyType(Class<?> type) 
Ignore the given dependency type for autowiring: for example, String. 

boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) 
Determine whether the specified bean qualifies as an autowire candidate, to be injected into other beans which declare a dependency of matching type. 

boolean isConfigurationFrozen() 
Return whether this factory's bean definitions are frozen, i.e. 

void preInstantiateSingletons() 
Ensure that all non-lazy-init singletons are instantiated, also considering FactoryBeans. 

void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue) 
Register a special dependency type with corresponding autowired value. 
复制代码
3.5 继承自BeanDefinitionRegistry接口的方法
BeanDefinitionRegistry:Spring配置文件中每一个<bean>节点元素在Spring容器里都通过一个BeanDefinition对象表示,它描述了Bean的配置信息。而BeanDefinition Registry接口提供了向容器手工注册BeanDefinition对象的方法。
复制代码
boolean containsBeanDefinition(String beanName) 
Check if this registry contains a bean definition with the given name. 

BeanDefinition getBeanDefinition(String beanName) 
Return the BeanDefinition for the given bean name. 

int getBeanDefinitionCount() 
Return the number of beans defined in the registry. 

String[] getBeanDefinitionNames() 
Return the names of all beans defined in this registry. 

boolean isBeanNameInUse(String beanName) 
Determine whether the given bean name is already in use within this registry, i.e. 

void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 
Register a new bean definition with this registry. 

void removeBeanDefinition(String beanName) 
Remove the BeanDefinition for the given name. 
复制代码

3.6 序列化支持
 private void writeObject(java.io.ObjectOutputStream out)throws IOException
 private void readObject(java.io.ObjectInputStream in)throws IOException, ClassNotFoundException;
 private void readObjectNoData()throws ObjectStreamException;

4 小结:
spring Ioc容器的实现,从根源上是beanfactory,但真正可以作为一个可以独立使用的ioc容器还是DefaultListableBeanFactory,因此可以这么说,
DefaultListableBeanFactory 是整个spring ioc的始祖,研究透它的前生今世对我们理解spring ioc的概念有着重要的作用。
DefaultListableBeanFactory功能的实现是通过实现特定功能的接口来完成。
AbstractAutowireCapableBeanFactory 实现属性的自动绑定功能。
ConfigurableListableBeanFactory提供了对bean定义的分析和修改的便利方法,同时也提供了对单例的预实例化。

  ListableBeanFactory提供枚举所有的bean实例,而不是客户端通过名称一个一个的查询得出所有的实例。

BeanDefinitionRegistry 提供了beanDefinition的管理。
分享到:
评论

相关推荐

    Spring ioc源码解读

    ### Spring IoC源码解读 #### 一、Spring IoC 容器概述 Spring框架的核心功能之一便是依赖注入(Dependency Injection, DI),而这一功能主要通过IoC容器来实现。在Spring框架中,IoC容器负责管理应用对象的生命...

    Spring框架核心源代码的分析及其感受-6

    在源代码中,`org.springframework.beans.factory.BeanFactory` 和 `org.springframework.context.ApplicationContext` 是IoC容器的两个主要接口,它们提供了加载配置、获取Bean和处理依赖注入等功能。通过阅读这些...

    spring3.x源码

    源码分析是深入理解Spring工作原理的关键,以下将对Spring 3.x的源码进行详细的解读。 首先,让我们从核心概念“依赖注入”开始。依赖注入(DI)是Spring框架的基础,它允许组件之间解耦,提高代码的可测试性和可...

    Spring Src

    在压缩包文件“Spring src”中,我们通常会找到Spring框架各模块的源代码,这些代码可能是按照模块划分的,如spring-core、spring-beans、spring-context、spring-web等。通过阅读源码,我们可以了解: 1. **依赖...

    spring 源码

    DI 可以通过构造器注入、设值注入或接口注入实现,源码中可以看到`org.springframework.beans`和`org.springframework.context`包下相关的类和接口,如`BeanFactory`、`ApplicationContext`等。 2. **面向切面编程...

    spring源码(1),可直接导入eclipse

    1. **spring-expression**: 这是Spring表达式语言(Spring Expression Language, SpEL)的源代码。SpEL是一个强大且灵活的内嵌表达式语言,用于在运行时查询和操作对象图。它支持属性导航、方法调用、条件和逻辑运算...

    spring-framework-4.3.12.RELEASE--编译好的源码.rar

    本文将针对该版本的源码进行深入解读,帮助读者理解Spring的核心机制,提升对框架的运用能力。 1. **模块结构** Spring Framework主要分为五个核心模块:Core Container(核心容器)、Data Access/Integration...

    spring-framework-3.2.10.RELEASE 源码

    通过阅读Spring 3.2.10.RELEASE的源码,开发者可以更深入理解其设计思想,掌握核心功能的实现细节,这对于优化代码、排查问题、扩展功能具有重要意义。 总结,Spring Framework 3.2.10.RELEASE是一个功能强大的框架...

    spring-framework-4.2.3.RELEASE 源码

    总结,Spring Framework 4.2.3.RELEASE的源码深度解读,能让我们更深入地理解其内部机制,从而更好地利用Spring构建高效、稳定的Java应用程序。无论是IoC容器的实现,还是AOP、MVC的原理,都是开发者在日常工作中不...

    Spring系列面试题129道(附答案解析)

    - Beans:在Spring IoC容器中运行的Java对象。 - Services:定义业务逻辑的组件。 - Data Access Objects (DAO):用于访问数据的组件。 - Enterprise JavaBeans (EJB):封装应用程序业务逻辑的组件。 - Controllers...

    spring-boot-examples-master.zip

    它默认配置了很多常见的功能,如嵌入式Tomcat服务器、自动配置的Spring beans等,极大地提高了开发效率。 二、MyBatis简介 MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了...

    Spring源码分析

    ### Spring源码分析:IOC容器深入解读 #### 一、Spring框架及IOC容器的重要性 Spring框架作为Java领域中最重要的企业级应用开发框架之一,自2004年发布以来一直备受开发者们的青睐。Spring框架的核心功能包括:...

    Sping基础jar包

    3. **spring-context.jar**:构建在spring-core和spring-beans之上,提供了一个更高级的应用程序上下文,它扩展了BeanFactory,增加了对消息源、事件、国际化等功能的支持。ApplicationContext接口是这个模块的核心...

    图解Spring框架的设计理念与设计模式

    IoC通过将对象的创建和管理交给容器(在Spring中是IoC容器)来实现,使得开发者不再需要在代码中直接创建和管理对象,而是通过配置文件或注解来声明对象及其依赖关系。这有助于降低对象间的耦合度,提高代码的可测试...

    ssh(structs,spring,hibernate)框架中的上传下载

     第3~9行定义了一个数据源,其实现类是apache的BasicDataSource,第11~25行定义了Hibernate的会话工厂,会话工厂类用Spring提供的LocalSessionFactoryBean维护,它注入了数据源和资源映射文件,此外还通过一些键值...

    springmvc+mybatis+oracle

    - `src/main/java`: 存放所有的Java源代码,包括控制器(Controller)、服务层(Service)、数据访问层(DAO)等。 - `src/main/resources`: 存放所有的配置文件,如`application.properties`、`mybatis-config.xml`、`....

    SSM框架模板-可直接使用

    4. **配置文件解读**:SSM框架模板中的配置文件十分重要,通常包括Spring的beans.xml、SpringMVC的servlet-context.xml以及MyBatis的mybatis-config.xml。这些文件详细配置了各个组件的行为,例如数据源设置、Mapper...

    无污染 纯净的 springmvc+mybatis 架构

    2. `src/main/resources`: 存放配置文件,如Spring的beans.xml、MyBatis的mybatis-config.xml和mapper.xml等。 3. `src/main/webapp`: Web应用的根目录,包括WEB-INF目录下的web.xml(Web应用配置)、jsp页面、静态...

    【中文】【EJB基础】

    尽管随着微服务架构和轻量级框架(如Spring和Hibernate)的兴起,EJB在现代企业级开发中的地位有所下降,但它仍然是理解Java企业级应用开发的重要一环。掌握EJB的基础知识,不仅能够帮助开发者更好地理解企业级应用...

Global site tag (gtag.js) - Google Analytics