|
|
|
@ -30,3 +30,133 @@ xxbean.method();
|
|
|
|
|
* 实例化
|
|
|
|
|
* 放到容器中
|
|
|
|
|
* 从容器中获取
|
|
|
|
|
|
|
|
|
|
容器使用map保存bean,map的key和value内容
|
|
|
|
|
|序号| Key | Value |
|
|
|
|
|
|----| ---- | ---- |
|
|
|
|
|
|1| String | Object |
|
|
|
|
|
|2| Class | Object |
|
|
|
|
|
|3| String | ObjectFactory |
|
|
|
|
|
|4| String | BeanDefinition |
|
|
|
|
|
|
|
|
|
|
## Spring创建Bean过程中用到的主要接口
|
|
|
|
|
|
|
|
|
|
* BeanDefinitionReader
|
|
|
|
|
* BeanDefinition
|
|
|
|
|
* BeanFactory
|
|
|
|
|
* DefaultListableBeanFactory
|
|
|
|
|
* ClassPathXmlApplicationContext
|
|
|
|
|
* PostProcessor
|
|
|
|
|
* BeanPostProcessor
|
|
|
|
|
* BeanFactoryPostProcessor
|
|
|
|
|
* Aware
|
|
|
|
|
* BeanNameAware
|
|
|
|
|
* AbstractAutoProxyCreator
|
|
|
|
|
|
|
|
|
|
#### BeanDefinitionReader
|
|
|
|
|
|
|
|
|
|
指定带有Resource或者字符串参数的加载方法的bean definition的简单接口。根据定义格式(xml、properties、yaml、注解),具体的reader可以添加额外的加载和注册方法。
|
|
|
|
|
|
|
|
|
|
#### BeanDefinition
|
|
|
|
|
|
|
|
|
|
BeanDefinition描述带有属性值、构造器参数值、具体实现类的信息。
|
|
|
|
|
这是一个最小的接口,主要使BeanFactoryPostProcessor可以自省和修改属性值和其他的bean元数据。
|
|
|
|
|
|
|
|
|
|
#### BeanFactory
|
|
|
|
|
|
|
|
|
|
访问Spring Bean容器的根接口。它是bean容器的基本客户端视图,进一步的接口如ListableBeanFactory和ConfigurableBeanFactory可用于指定的目的。
|
|
|
|
|
|
|
|
|
|
这个接口被持有许多bean定义的对象实现,每一个对象都由字符串唯一确定。依据bean定义,factory将返回一个容器化对象的独立实例(原型设计模式),或者一个单例的共享对象(单例设计模式的一个更好的替代方案,该实例在factory内部是单例的)。那种类型的实例会被返回依赖于factory的配置,API是相同的。从Spring2.0开始,根据具体应用上下文,更多的范围可以被使用(比如web环境中的request和session)。
|
|
|
|
|
|
|
|
|
|
这种方法的要点是BeanFactory是应用程序组件的中央注册表,并且集中了应用程序组件的配置(例如单个对象不再需要读取属性文件)。可以通过<Expert One-on-One J2EE Design and Development>的第4章和11章了解这种方式的优点。(到底是啥优点?)
|
|
|
|
|
|
|
|
|
|
一般来讲,依靠DI(push配置)通过set或者构造方法配置应用对象是比使用任何形式,比如查找BeanFactory拉取配置要好的。Spring的依赖注入功能是使用BeanFactory接口和它的子接口实现的。
|
|
|
|
|
|
|
|
|
|
通常一个BeanFactory将会加载保存在配置源(比如xml文档)中的bean定义,使用org.springframework.beans包配置bean。但是,实现可以简单地返回它根据需要直接在 Java 代码中创建的 Java 对象。bean定时可以被怎样储存是没有任何限制的,可以使用LDAP、RDBMS、XML、properties文件等。鼓励实现支持 bean 之间的引用(依赖注入)。
|
|
|
|
|
|
|
|
|
|
与ListableBeanFactory中的方法相比,如果它是一个HierarchicalBeanFactory,这个接口的所有操作也会检查父工厂。如果一个bean没有在这个工厂实例中找到,会在直接父工厂中查找。这个工厂实例中的 bean 应该覆盖任何父工厂中的同名 bean。
|
|
|
|
|
|
|
|
|
|
BeanFactory的实现类应该尽可能支持标准的bean生命周期接口。所有的初始化方法和顺序为
|
|
|
|
|
|
|
|
|
|
* BeanNameAware's {@code setBeanName}
|
|
|
|
|
* BeanClassLoaderAware's {@code setBeanClassLoader}
|
|
|
|
|
* BeanFactoryAware's {@code setBeanFactory}
|
|
|
|
|
* EnvironmentAware's {@code setEnvironment}
|
|
|
|
|
* EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
|
|
|
|
|
* ResourceLoaderAware's {@code setResourceLoader}
|
|
|
|
|
* ApplicationEventPublisherAware's {@code setApplicationEventPublisher} (only applicable when running in an application context)
|
|
|
|
|
* MessageSourceAware's {@code setMessageSource} (only applicable when running in an application context)
|
|
|
|
|
* ApplicationContextAware's {@code setApplicationContext} (only applicable when running in an application context)
|
|
|
|
|
* ServletContextAware's {@code setServletContext} (only applicable when running in an application context)
|
|
|
|
|
* {@code postProcessBeforeInitialization} methods of BeanPostProcessors (only applicable when running in a web application context)
|
|
|
|
|
* InitializingBean's {@code afterPropertiesSet}
|
|
|
|
|
* a custom {@code init-method} definition
|
|
|
|
|
* {@code postProcessAfterInitialization} methods of BeanPostProcessors
|
|
|
|
|
|
|
|
|
|
bean工厂关闭的时候,会调用DestructionAwareBeanPostProcessors的postProcessBeforeDestruction()方法,DisposableBean的destroy()方法,自定义的destroy-method方法
|
|
|
|
|
|
|
|
|
|
#### DefaultListableBeanFactory
|
|
|
|
|
|
|
|
|
|
Spring对ConfigurableListableBeanFactory和BeanDefinitionRegistry接口的默认实现,基于 bean 定义元数据的成熟的 bean 工厂,可通过后处理器进行扩展。
|
|
|
|
|
|
|
|
|
|
典型用法是在访问bean前先注册所有 bean 定义(很可能是从一个bean定义文件中读取的)。在本地bean定义表中,在预先解析的bean定义元数据上操作,按照名称查找bean是一项廉价操作。
|
|
|
|
|
|
|
|
|
|
特定bean定义格式的reader都是被分开实现的,而不是作为bean工厂的子类,可以参考XmlBeanDefinitionReader。
|
|
|
|
|
|
|
|
|
|
对于ListableBeanFactory接口的替代实现,可以参考StaticListableBeanFactory,它管理已经存在的bean实例,而不是根据bean定义创建新的bean。
|
|
|
|
|
|
|
|
|
|
#### ClassPathXmlApplicationContext
|
|
|
|
|
|
|
|
|
|
独立的 XML 应用程序上下文,从类路径中获取上下文定义文件,将普通路径解释为包含包路径的类路径资源名称(比如"mypackage/myresource.txt")。对于测试工具以及嵌入在 JAR 中的应用程序上下文很有用。
|
|
|
|
|
|
|
|
|
|
配置位置默认值可以通过 {@link #getConfigLocations} 覆盖,配置位置可以表示为具体文件,比如"myfiles/context.xml",或者Ant风格类型,比如"myfiles/*-context.xml"(参考AntPathMatcher的java文档)。
|
|
|
|
|
|
|
|
|
|
注意:在多个配置位置的情况下,后面的 bean 定义将覆盖前面加载文件中定义的那些。 这可以用来通过额外的 XML 文件故意覆盖某些 bean 定义。
|
|
|
|
|
|
|
|
|
|
这是一个简单的、一站式便利的 ApplicationContext。考虑使用GenericApplicationContext类结合XmlBeanDefinitionReader进行更灵活的上下文设置。
|
|
|
|
|
|
|
|
|
|
#### PostProcessor
|
|
|
|
|
|
|
|
|
|
#### BeanPostProcessor
|
|
|
|
|
|
|
|
|
|
允许自定义修改新 bean 实例的工厂钩子——例如,检查标记接口或使用代理包装 bean。
|
|
|
|
|
|
|
|
|
|
通常,后处理器通过标记接口填充bean或类似的将实现{@link #postProcessBeforeInitialization},而用代理包装 bean 的后处理器通常会实现{@link #postProcessAfterInitialization}。
|
|
|
|
|
|
|
|
|
|
ApplicationContext可以在其 bean 定义中自动检测 BeanPostProcessor bean,并将这些后处理器应用于随后创建的任何 bean。普通的 BeanFactory 允许后处理器的编程注册,将它们应用于通过 bean 工厂创建的所有 bean。
|
|
|
|
|
|
|
|
|
|
在 {@code ApplicationContext} 中自动检测到的 {@code BeanPostProcessor} bean 将根据 {@link org.springframework.core.PriorityOrdered} 和 {@link org.springframework.core.Ordered} 语义进行排序。相反,使用 {@code BeanFactory} 以编程方式注册的 {@code BeanPostProcessor} bean 将按注册顺序应用;对于以编程方式注册的后处理器,将忽略通过实现 {@code PriorityOrdered} 或 {@code Ordered} 接口表达的任何排序语义。此外,{@link org.springframework.core.annotation.Order @Order} 注解没有被考虑用于 {@code BeanPostProcessor} bean。
|
|
|
|
|
|
|
|
|
|
#### BeanFactoryPostProcessor
|
|
|
|
|
|
|
|
|
|
允许自定义修改应用程序上下文的 bean 定义的工厂钩子,调整上下文底层 bean 工厂的 bean 属性值。
|
|
|
|
|
|
|
|
|
|
对于针对系统管理员的自定义配置文件很有用,这些配置文件会覆盖在应用程序上下文中配置的 bean 属性。 请参阅 {@link PropertyResourceConfigurer} 及其具体实现,以了解满足此类配置需求的现成解决方案。
|
|
|
|
|
|
|
|
|
|
{@code BeanFactoryPostProcessor} 可以与 bean 定义交互并修改 bean 定义,但绝不能与 bean 实例交互。 这样做可能会导致 bean 过早实例化,违反容器并导致意外的副作用。 如果需要 bean 实例交互,请考虑改为实施 {@link BeanPostProcessor}。
|
|
|
|
|
|
|
|
|
|
{@code ApplicationContext} 自动检测其 bean 定义中的 {@code BeanFactoryPostProcessor} bean,并在创建任何其他 bean 之前应用它们。 {@code BeanFactoryPostProcessor} 也可以通过 {@code ConfigurableApplicationContext} 以编程方式注册。
|
|
|
|
|
|
|
|
|
|
在 {@code ApplicationContext} 中自动检测到的 {@code BeanFactoryPostProcessor} bean 将根据 {@link org.springframework.core.PriorityOrdered} 和 {@link org.springframework.core.Ordered} 语义进行排序。 相反,使用 {@code ConfigurableApplicationContext} 以编程方式注册的 {@code BeanFactoryPostProcessor} beans 将按注册顺序应用; 对于以编程方式注册的后处理器,将忽略通过实现 {@code PriorityOrdered} 或 {@code Ordered} 接口表达的任何排序语义。 此外,{@link org.springframework.core.annotation.Order @Order} 注释未被考虑用于 {@code BeanFactoryPostProcessor} beans。
|
|
|
|
|
|
|
|
|
|
#### Aware
|
|
|
|
|
|
|
|
|
|
一个标记父接口,指示一个 bean 有资格通过回调样式的方法被特定框架对象的 Spring 容器通知。 实际的方法签名由各个子接口确定,但通常应该只包含一个接受单个参数的返回 void 的方法。
|
|
|
|
|
|
|
|
|
|
请注意,仅实现 {@link Aware} 不提供默认功能。相反,处理必须显式完成,例如在 {@link org.springframework.beans.factory.config.BeanPostProcessor} 中。 有关处理特定 {@code *Aware} 接口回调的示例,请参阅 {@link org.springframework.context.support.ApplicationContextAwareProcessor}。
|
|
|
|
|
|
|
|
|
|
#### BeanNameAware
|
|
|
|
|
|
|
|
|
|
由想要在 bean 工厂中了解其 bean 名称的 bean 实现的接口。 请注意,通常不建议对象依赖于其 bean 名称,因为这表示对外部配置的潜在脆弱依赖,以及对 Spring API 的可能不必要的依赖。
|
|
|
|
|
|
|
|
|
|
#### AbstractAutoProxyCreator
|
|
|
|
|
|
|
|
|
|
{@link org.springframework.beans.factory.config.BeanPostProcessor} 的实现,用 AOP 代理包装每个符合条件的 bean,在调用 bean 本身之前委托给指定的拦截器。
|
|
|
|
|
|
|
|
|
|
这个类区分“通用”拦截器:为它创建的所有代理共享,以及“特定”拦截器:每个 bean 实例唯一。不需要任何公共拦截器。如果有,则使用 interceptorNames 属性设置它们。 与 {@link org.springframework.aop.framework.ProxyFactoryBean} 一样,使用当前工厂中的拦截器名称而不是 bean 引用来允许正确处理原型顾问程序和拦截器:例如,支持有状态混合。 {@link #setInterceptorNames "interceptorNames"} 条目支持任何建议类型。
|
|
|
|
|
|
|
|
|
|
如果有大量的 beans 需要用类似的代理包装,即委托给相同的拦截器,那么这种自动代理特别有用。 您可以向 bean 工厂注册一个这样的后处理器,而不是为 x 个目标 bean 重复定义 x 个代理,以达到相同的效果。
|
|
|
|
|
|
|
|
|
|
子类可以应用任何策略来决定是否要代理一个 bean,例如 按类型、按名称、按定义详细信息等。它们还可以返回应仅应用于特定 bean 实例的其他拦截器。 一个简单的具体实现是 {@link BeanNameAutoProxyCreator},通过给定名称识别要代理的 bean。
|
|
|
|
|
|
|
|
|
|
可以使用任意数量的 {@link TargetSourceCreator} 实现来创建自定义目标源:例如,池化原型对象。 即使没有建议,自动代理也会发生,只要 TargetSourceCreator 指定自定义 {@link org.springframework.aop.TargetSource}。 如果没有设置 TargetSourceCreators,或者没有匹配项,默认情况下将使用 {@link org.springframework.aop.target.SingletonTargetSource} 来包装目标 bean 实例。
|
|
|
|
|