b springbean加载的机制,和自定义bean加载行为


Spring Framework 提供了一堆api,去自定义加载bean时的行为

  • Lifecycle Callbacks 周期回调
  • ApplicationContextAware and BeanNameAware 容器aware和 BeanNameAware
  • 其他 Aware Interfaces

aware指的是spring 自身框架的对外接口,提供和框架交互的

6.1 Lifecycle Callbacks

解释可以置入的点
和container的管理的bean 生命周期交互,你可以通过实现InitializingBeanDisposableBean接口。
容器调用afterPropertiesSet() 在初始化之前 和 destroy() 在摧毁之后,以让bean执行确定的动作

JSR-250的 @PostConstruct@PreDestroy是广泛使用的最佳时间。不想用 JSR-250,可以使用
init-methoddestroy-method

内部,spring框架使用BeanPostProcessor的实现类去处理回调函数–他可以找到和调用合适 的方法。
如果你需要自定义其他行为,spring 默认不会提供,你可以实现BeanPostProcessor类。

额外的,Spring 管理对象也可以通过实现Lifecyle接口以让对象加入到启动和停止进程,被容器自己的声明周期地调用。

初始化Initialization Callbacks

该接口org.springframework.beans.factory.InitializingBean让bean在设置完所有必要的properties后初始化。
接口就一个方法
b springbean加载的机制,和自定义bean加载行为
我们不推荐使用该接口,因为冗余的代码。我们推荐使用@PostConstruct。在xml 风格里 使用init-method属性。对于java configuration, 你可以使用
@BeaninitMethod属性
示例1
b springbean加载的机制,和自定义bean加载行为

示例2
示例1等于示例2,但是示例1就不会有冗余
b springbean加载的机制,和自定义bean加载行为

销毁 Destruction Callbacks

通过实现org.springframework.beans.factory.DisposableBean完成销毁前的动作。
接口有单一方法
b springbean加载的机制,和自定义bean加载行为
同初始化,不推荐使用代码而是使用@PreDestroy注解。inxml是destroy-method属性。java configuration 是用@BeandestroyMethod
示例1
b springbean加载的机制,和自定义bean加载行为
示例2
b springbean加载的机制,和自定义bean加载行为
同样1与2相同,但是1不会有多余的冗余

默认的 nitialization 和 Destroy Methods

除了像上面一样去配置,也可以约定固定方法的名称,让container去找对应方法去调用。
default-init-method
default-destroy-method
示例
b springbean加载的机制,和自定义bean加载行为
配置如下
b springbean加载的机制,和自定义bean加载行为
类中的init方法会被调用
同样在<beans>中的谁定可以在
<bean>中用同样的标签覆盖掉

联合 Lifecycle Mechanisms

首先总共有三种方式来进行置入神生命周期行为

  1. The InitializingBeanDisposableBean callback interfaces

  2. Custom init() and destroy() methods

  3. The @PostConstruct and @PreDestroy annotations.

这些方式可以混合使用,一个init只会被调用一次,以下是调用顺序

  • 初始化
    b springbean加载的机制,和自定义bean加载行为
  • 销毁
    b springbean加载的机制,和自定义bean加载行为

satrtup和shutdown回调

常规的启停

lifecle接口定义了任何对象必要的使用的方法。任何实现了该接口的类都会被容器调用
b springbean加载的机制,和自定义bean加载行为
比如ApplicationContext收到了启动和停止信号会挨个调用lifecle的实现。
实现这样的功能被委托给类LifecycleProcessor,如下
b springbean加载的机制,和自定义bean加载行为

org.springframework.context.Lifecycle是用来控制严格的启动和停止,不能被自动启停所使用。想使对bean的自动启停控制推荐org.springframework.context.SmartLifecycle

自动启停

原因:依赖位置
启动和关闭调用的顺序可能很重要。如果任何两个对象之间存在“依赖”关系,则依赖方在其依赖之后开始,而在依赖之前停止。但是,有时直接依赖项是未知的。您可能只知道某种类型的对象应该先于另一种类型的对象开始。
结果:数字标识启动顺序
在这些情况下,SmartLifecycle接口定义了另一个选项,即在其超级接口Phased上定义的getPhase()方法。以下清单显示了Phased接口的定义。
b springbean加载的机制,和自定义bean加载行为

SmartLifecycle接口
b springbean加载的机制,和自定义bean加载行为

简单来讲,启动小order先启动:Integer.MIN_VALUE最先启动,
Integer.MAX_VALUE最后启动。
停止时,刚好顺序相反。
0意味值是Lifecle接口,不是smartLifecle。负数意味着先于标准组件的启动,正数意味着后于。停止刚好相反。
延时:按照顺序的启动默认30s
顺序启动不是无限的等待有最大时长。
可以通过覆盖lifecycleProcessor来控制。
例如时长的控制如下
b springbean加载的机制,和自定义bean加载行为
开关:有些场景不需要stmart
常规的lifecycle是加载一次的,但是stmartLifecyclerefresh属性,会让容器在启动后再次刷新和加载。容器check,即phase为0的不refresh,
isAutoStartup()为false不刷新

优雅的在 非web应用启停容器

本节仅适用于非Web应用程序。 Spring的基于Web的ApplicationContext实现已经具有适当的代码,可以在相关Web应用程序关闭时正常关闭Spring IoC容器。

如果您在非Web应用程序环境中(例如,在很多客户端桌面环境中)使用Spring的IoC容器,请向JVM注册一个关闭钩子。这样做可以确保正常关机,并在您的Singleton bean上调用相关的destroy方法,以便释放所有资源。您仍然必须正确配置和实现这些destroy回调。

要注册关闭挂钩,请调用在ConfigurableApplicationContext接口上声明的registerShutdownHook()方法,如以下示例所示:
b springbean加载的机制,和自定义bean加载行为

6.2 ApplicationContextAware 和 BeanNameAware

通常用户bean是不需要和框架交互的。aware就是满足和框架交互的类

ApplicationContextAware

当一个ApplicationContext创建一个实现了org.springframework.context.ApplicationContextAware的接口的对象实例时,这个实例会保存一个对ApplicationContext的引用。
ApplicationContextAware接口的函数
b springbean加载的机制,和自定义bean加载行为

因此,bean可以通过ApplicationContext接口或通过将引用转换为该接口的已知子类(例如ConfigurableApplicationContext,它暴露了其他功能)来以编程方式操纵创建它们的ApplicationContext。一种用途是通过编程方式检索其他bean。有时,此功能很有用。但是,通常应避免使用它,因为它会将代码耦合到Spring,并且不遵循控制反转样式,在该样式中,将协作者作为属性提供给bean。 ApplicationContext的其他方法提供对
1.文件资源的访问、2.发布应用程序事件、3访问MessageSource

Autowiring是获得对ApplicationContext的引用的另一种方法。传统的构造函数和byType自动装配模式(如“自动装配协作器”中所述)可以分别为构造函数参数或setter方法参数提供ApplicationContext类型的依赖项。要获得更大的灵活性,包括能够自动连接字段和使用多个参数方法,请使用基于注解的自动装配功能。如果这样做,则将ApplicationContext自动连接到需要使用ApplicationContext类型的字段,构造函数参数或方法参数中(如果有问题的字段,构造函数或方法带有@Autowire批注)。有关更多信息,请参见使用@Autowired。

BeanNameAware

ApplicationContext创建一个实现org.springframework.beans.factory.BeanNameAware接口的类时,该类将获得对其关联对象定义中定义的名称的引用。以下清单显示了BeanNameAware接口的定义:

b springbean加载的机制,和自定义bean加载行为
和这个回调在bean初始化正常的属性之后,但是在初始化一个回调函数如InitializingBean, afterPropertiesSet之前,或者自定义的 custom init-method。

6.3 Other Aware Interface

除了其他ApplicationContextAwareBeanNameAware
,Spring也提供了其他aware接口。

我们不反对来使用Spring API,也不反对不遵从控制反转的风格。因此,我们推荐使用这些我们提供的基础设施bean,来编程化的和容器交互

Name Injected Dependency Explained in…
ApplicationContextAware 描述 ApplicationContext. ApplicationContextAware and BeanNameAware
ApplicationEventPublisherAware ApplicationContext内的事件发布者 Additional Capabilities of the ApplicationContext
BeanClassLoaderAware 类加载器用来加载bean Instantiating Beans
BeanFactoryAware 描述 BeanFactory. ApplicationContextAware and BeanNameAware
BeanNameAware Name of the declaring bean. ApplicationContextAware and BeanNameAware
BootstrapContextAware 启动资源的适配Resource adapter BootstrapContext the container runs in. Typically available only in JCA-aware ApplicationContext instances. JCA CCI
LoadTimeWeaverAware AOP置入在启动阶段Defined weaver for processing class definition at load time. Load-time Weaving with AspectJ in the Spring Framework
MessageSourceAware 配置消息接受策略Configured strategy for resolving messages (with support for parametrization and internationalization). Additional Capabilities of the ApplicationContext
NotificationPublisherAware Spring JMX notification publisher. spring的 JMX 事件发布者 Notifications
ResourceLoaderAware 资源加载器Configured loader for low-level access to resources. Resources
ServletConfigAware Servelet的加载器的配置Current ServletConfig the container runs in. Valid only in a web-aware Spring ApplicationContext. Spring MVC
ServletContextAware 当前运行的Servelet管理Current ServletContext the container runs in. Valid only in a web-aware Spring ApplicationContext. Spring MVC