文章作者:Tyan
博客:noahsnail.com | CSDN | 简书
3.6 Customizing the nature of a bean
3.6.1 Lifecycle callbacks
To interact with the container’s management of the bean lifecycle, you can implement the Spring InitializingBean
and DisposableBean
interfaces. The container calls afterPropertiesSet()
for the former and destroy()
for the latter to allow the bean to perform certain actions upon initialization and destruction of your beans.
为了与容器中bean生命周期的管理进行交互,你可以实现Spring的InitializingBean
和DisposableBean
接口。当初始化beans时容器会调用InitializingBean
中的afterPropertiesSet()
方法,当销毁beans时容器会调用DisposableBean
中的destroy()
方法,在这两个方法中bean可以执行特定的行为。
The JSR-250
@PostConstruct
and@PreDestroy
annotations are generally considered best practice for receiving lifecycle callbacks in a modern Spring application. Using these annotations means that your beans are not coupled to Spring specific interfaces. For details see Section 3.9.8, “@PostConstruct and @PreDestroy”.
If you don’t want to use the JSR-250 annotations but you are still looking to remove coupling consider the use of init-method and destroy-method object definition metadata.
在现代Spring应用中,通常认为JSR-250的
@PostConstruct
和@PreDestroy
注解是最佳实践接收生命周期回调函数的方法。使用这些注解意味着你的bean没有耦合Spring特定的接口。更多细节请看3.9.8小节,"@PostConstruct和@PreDestroy"。
如果你不想使用JSR-250注解,但你仍要注意解耦,可以考虑使用对象定义元数据中的初始化方法和方法。
Internally, the Spring Framework uses BeanPostProcessor
implementations to process any callback interfaces it can find and call the appropriate methods. If you need custom features or other lifecycle behavior Spring does not offer out-of-the-box, you can implement a BeanPostProcessor
yourself. For more information, see Section 3.8, “Container Extension Points”.
在Spring内部,Spring框架使用BeanPostProcessor
实现来处理任何它能发现的回调接口并调用合适的方法。如果你需要定制Spring不能提供的开箱即用的功能或其它生命周期行为,你可以自己实现BeanPostProcessor
。更多信息请看3.8小节,"容器扩展点"。
In addition to the initialization and destruction callbacks, Spring-managed objects may also implement the Lifecycle
interface so that those objects can participate in the startup and shutdown process as driven by the container’s own lifecycle.
除了初始化回调函数和析构回调函数之外,Spring管理的对象也可以实现Lifecycle
接口,这些对象可以参与容器自身生命周期驱动的启动和关闭过程。
The lifecycle callback interfaces are described in this section.
本节描述了生命周期回调接口。
Initialization callbacks
The org.springframework.beans.factory.InitializingBean
interface allows a bean to perform initialization work after all necessary properties on the bean have been set by the container. The InitializingBean
interface specifies a single method:
org.springframework.beans.factory.InitializingBean
接口在容器设置了bean所有的必须属性之后,允许bean执行初始化工作。InitializingBean
接口指定了一个方法:
void afterPropertiesSet() throws Exception;
It is recommended that you do not use the InitializingBean
interface because it unnecessarily couples the code to Spring. Alternatively, use the @PostConstruct
annotation or specify a POJO initialization method. In the case of XML-based configuration metadata, you use the init-method
attribute to specify the name of the method that has a void no-argument signature. With Java config, you use the initMethod
attribute of @Bean
, see the section called “Receiving lifecycle callbacks”. For example, the following:
建议你不使用InitializingBean
接口,因为它对代码与Spring进行了不必要的耦合。作为一种替代方法,你可以使用@PostConstruct
注解或指定一个POPJO的初始化方法。在基于XML配置元数据的情况下,你可以使用init-method
特性来指定方法的名称,方法是没有返回值和参数的。如果使用Java配置,你可以使用@Bean
的initMethod
特性,请看"接收生命周期回调"小节。例如,下面的代码:
<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
public class ExampleBean {
public void init() {
// do some initialization work
}
}
…is exactly the same as…
等价于:
<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>
public class AnotherExampleBean implements InitializingBean {
public void afterPropertiesSet() {
// do some initialization work
}
}
but does not couple the code to Spring.
但没有与Spring代码耦合。
Destruction callbacks
Implementing the org.springframework.beans.factory.DisposableBean
interface allows a bean to get a callback when the container containing it is destroyed. The DisposableBean
interface specifies a single method:
实现org.springframework.beans.factory.DisposableBean
接口允许容器包含的bean销毁时调用回调函数。DisposableBean
接口指定了一个方法:
void destroy() throws Exception;
It is recommended that you do not use the DisposableBean
callback interface because it unnecessarily couples the code to Spring. Alternatively, use the @PreDestroy
annotation or specify a generic method that is supported by bean definitions. With XML-based configuration metadata, you use the destroy-method
attribute on the <bean/>
. With Java config, you use the destroyMethod
attribute of @Bean
, see the section called “Receiving lifecycle callbacks”. For example, the following definition:
建议你不使用DisposableBean
回调接口,因为它对代码与Spring进行了不必要的耦合。作为一种替代方法,你可以使用@PreDestroy
注解或指定一个bean定义支持的通用方法。在基于XML配置元数据的情况下,你可以使用<bean/>
的destroy-method
特性。如果使用Java配置,你可以使用@Bean
的destroyMethod
特性,请看"接收生命周期回调"小节。例如,下面的定义:
<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/>
public class ExampleBean {
public void cleanup() {
// do some destruction work (like releasing pooled connections)
}
}
is exactly the same as:
等价于:
<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>
public class AnotherExampleBean implements DisposableBean {
public void destroy() {
// do some destruction work (like releasing pooled connections)
}
}
but does not couple the code to Spring.
但没有与Spring代码耦合。
The
destroy-method
attribute of a<bean>
element can be assigned a special(inferred)
value which instructs Spring to automatically detect a publicclose
orshutdown
method on the specific bean class (any class that implementsjava.lang.AutoCloseable
orjava.io.Closeable
would therefore match). This special(inferred)
value can also be set on thedefault-destroy-method
attribute of a<beans>
element to apply this behavior to an entire set of beans (see the section called “Default initialization and destroy methods”). Note that this is the default behavior with Java config.
<bean>
元素的destroy-method
特性可以分配一个特殊值(inferred)
,它会指导Spring自动检测指定的bean类的公有close
方法或shutdown
方法(可以匹配任何实现java.lang.AutoCloseable
或java.io.Closeable
的类)。为了将这种行为应用到beans的全部集合中,特殊值(inferred)
可以设置在<beans>
元素中的default-destroy-method
特性上(请看"默认初始化方法和销毁方法"小节)。注意Java配置的默认行为。
Default initialization and destroy methods
When you write initialization and destroy method callbacks that do not use the Spring-specific InitializingBean
and DisposableBean
callback interfaces, you typically write methods with names such as init()
, initialize()
, dispose()
, and so on. Ideally, the names of such lifecycle callback methods are standardized across a project so that all developers use the same method names and ensure consistency.
当你编写初始化回调函数和析构回调函数时,不要使用Spring特定的InitializingBean
和DisposableBean
回调接口,自己编写方法,方法名通常为init()
,initialize()
,dispose()
等等。理想情况下,这种生命周期回调方法的名称在整个工程中是标准化的,以便所有开发人员使用同样的方法名称,保证一致性。
You can configure the Spring container to look
for named initialization and destroy callback method names on every bean. This means that you, as an application developer, can write your application classes and use an initialization callback called init()
, without having to configure an init-method="init"
attribute with each bean definition. The Spring IoC container calls that method when the bean is created (and in accordance with the standard lifecycle callback contract described previously). This feature also enforces a consistent naming convention for initialization and destroy method callbacks.
你可以配置Spring容器查找每个bean的初始化方法和析构方法时的名字。这意味着,作为一个应用开发者,你可以编写应用程序类并使用名为init()
的初始化回调方法,而不必在每个bean定义中配置init-method="init"
特性。当bean创建时,Spring Ioc容器调用这个方法(按照前面描述的标准生命周期回调约定)。这个功能也强制了初始化方法和析构方法命名规范的一致性。
Suppose that your initialization callback methods are named init()
and destroy callback methods are named destroy()
. Your class will resemble the class in the following example.
假设你的初始化回调方法名为init()
,析构回调方法名为destroy()
。你的类应该与下面例子中的类类似。
public class DefaultBlogService implements BlogService {
private BlogDao blogDao;
public void setBlogDao(BlogDao blogDao) {
this.blogDao = blogDao;
}
// this is (unsurprisingly) the initialization callback method
public void init() {
if (this.blogDao == null) {
throw new IllegalStateException("The [blogDao] property must be set.");
}
}
}
<beans default-init-method="init">
<bean id="blogService" class="com.foo.DefaultBlogService">
<property name="blogDao" ref="blogDao" />
</bean>
</beans>
The presence of the default-init-method
attribute on the top-level <beans/>
element attribute causes the Spring IoC container to recognize a method called init
on beans as the initialization method callback. When a bean is created and assembled, if the bean class has such a method, it is invoked at the appropriate time.
位于顶层<beans/>
元素中的default-init-method
特性,会让Spring IoC容器将beans中的名为init
的方法识别为初始化回调方法。当一个bean创建和组装时,如果bean类有这样一个方法,它会在恰当的时间被调用。
You configure destroy method callbacks similarly (in XML, that is) by using the default-destroy-method
attribute on the top-level <beans/>
element.
类似的,你可以在顶层元素<beans/>
中设置default-destroy-method
特性来配置析构回调方法的名字。
Where existing bean classes already have callback methods that are named at variance with the convention, you can override the default by specifying (in XML, that is) the method name using the init-method
and destroy-method
attributes of the <bean/>
itself.
在现有的bean类已经有不符合命名规范的回调方法的情况下,你也可以通过在<bean/>
本身的init-method
和destroy-method
特性(在XML中)中指定方法名称来覆盖<beans/>
中的默认名称。
The Spring container guarantees that a configured initialization callback is called immediately after a bean is supplied with all dependencies. Thus the initialization callback is called on the raw bean reference, which means that AOP interceptors and so forth are not yet applied to the bean. A target bean is fully created first, then an AOP proxy (for example) with its interceptor chain is applied. If the target bean and the proxy are defined separately, your code can even interact with the raw target bean, bypassing the proxy. Hence, it would be inconsistent to apply the interceptors to the init method, because doing so would couple the lifecycle of the target bean with its proxy/interceptors and leave strange semantics when your code interacts directly to the raw target bean.
在bean被提供了所有依赖之后,Spring容器确保会立刻调用配置的初始化回调方法。因此初始化回调会在原生bean引用上调用,这意味着AOP拦截器等仍不能应用到bean中。首先要完整的创建目标bean,然后才会应用AOP代理(例如)等拦截器链。如果分别定义了目标bean和代理,你的代码甚至能绕过代理直接与原生的目标bean进行交互。将拦截器应用到初始化方法上可能会产生不一致性,因为这样做会使目标bean的生命周期与它的代理/拦截器相耦合,当你的代码与原生目标bean直接进行交互时,语义会变的很奇怪。
Combining lifecycle mechanisms
As of Spring 2.5, you have three options for controlling bean lifecycle behavior: the InitializingBean
and DisposableBean
callback interfaces; custom init()
and destroy()
methods; and the @PostConstruct
and @PreDestroy
annotations. You can combine these mechanisms to control a given bean.
从Spring 2.5开始,在控制bean的生命周期行为时,你有三中选择:InitializingBean和
DisposableBean回调接口;定制
init()和
destroy()方法;
@PostConstruct和
@PreDestroy`注解。在控制一个给定bean时你可以组合这些机制。
If multiple lifecycle mechanisms are configured for a bean, and each mechanism is configured with a different method name, then each configured method is executed in the order listed below. However, if the same method name is configured - for example,
init()
for an initialization method - for more than one of these lifecycle mechanisms, that method is executed once, as explained in the preceding section.
如果一个bean配置了多生命周期机制,每种机制配置了一个不同的方法名,那么每一个配置的方法会按照下面的顺序列表来执行。但是如果配置了相同的名字——例如,
init()
初始化方法——不止在一个生命周期机制中配置,那么这个方法只能执行一次,像之前所说的那样。
Multiple lifecycle mechanisms configured for the same bean, with different initialization methods, are called as follows:
Methods annotated with
@PostConstruct
afterPropertiesSet()
as defined by theInitializingBean
callback interfaceA custom configured
init()
method
同一个bean配置了多生命周期机制,并有不同的初始化方法,那么调用顺序如下:
先调用有注解
@PostConstruct
的方法然后调用
InitializingBean
回调接口定义的afterPropertiesSet()
方法最好调用定制配置的
init()
方法
Destroy methods are called in the same order:
Methods annotated with
@PreDestroy
destroy()
as defined by theDisposableBean
callback interfaceA custom configured
destroy()
method
析构方法按同样的顺序调用:
先调用有
@PreDestroy
注解的方法再调用
DisposableBean
回调接口定义的destroy()
方法最好调用定制配置的
destroy()
方法
Startup and shutdown callbacks
The Lifecycle
interface defines the essential methods for any object that has its own lifecycle requirements (e.g. starts and stops some background process):
Lifecycle
接口定义了任何对象生命周期都需要的基本方法(例如启动和停止一些背景处理):
public interface Lifecycle {
void start();
void stop();
boolean isRunning();
}
Any Spring-managed object may implement that interface. Then, when the ApplicationContext
itself receives start and stop signals, e.g. for a stop/restart scenario at runtime, it will cascade those calls to all Lifecycle
implementations defined within that context. It does this by delegating to a LifecycleProcessor
:
任何Spring管理的对象都可以实现那个接口。当ApplicationContext
本身收到启动启动和关闭信号时,例如运行时关闭/再启动场景,它将级联调用所有的上下文定义的Lifecycle
实现。它通过委托LifecycleProcessor
来完成这个功能:
public interface LifecycleProcessor extends Lifecycle {
void onRefresh();
void onClose();
}
Notice that the LifecycleProcessor
is itself an extension of the Lifecycle
interface. It also adds two other methods for reacting to the context being refreshed and closed.
注意LifecycleProcessor
本身是Lifecycle
接口的一个扩展。它也添加了两个其它的方法来响应上下文的再刷新和关闭的。
Note that the regular
org.springframework.context.Lifecycle
interface is just a plain contract for explicit start/stop notifications and does NOT imply auto-startup at context refresh time. Consider implementingorg.springframework.context.SmartLifecycle
instead for fine-grained control over auto-startup of a specific bean (including startup phases). Also, please note that stop notifications are not guaranteed to come before destruction: On regular shutdown, allLifecycle
beans will first receive a stop notification before the general destruction callbacks are being propagated; however, on hot refresh during a context’s lifetime or on aborted refresh attempts, only destroy methods will be called.
注意正规的
org.springframework.context.Lifecycle
接口只是一个显式启动/关闭通知的协议,并不意味着在上下文刷新时自动启动。考虑实现org.springframework.context.SmartLifecycle
接口来实现对指定bean自动启动的细粒度控制(包括启动时期)。请注意停止通知不能保证在销毁之前到来:在正式关闭时,所有的Lifecycle
beans在通常的析构回调传播之前首先会收到停止通知;但是,在上下文使用期间进行热刷新或尝试取消再刷新,只会调用析构方法。
The order of startup and shutdown invocations can be important. If a "depends-on" relationship exists between any two objects, the dependent side will start after its dependency, and it will stop before its dependency. However, at times the direct dependencies are unknown. You may only know that objects of a certain type should start prior to objects of another type. In those cases, the SmartLifecycle
interface defines another option, namely the getPhase()
method as defined on its super-interface, Phased
.
启动和关闭的调用顺序是很重要的。如果任何两个对象间存在一个"depends-on"关系,那么依赖关系将在它的依赖之后开始,在它的依赖之前停止。然而有时直接的依赖关系是未知的。你可能只知道某个类型的对象应该在另一个类型的对象之前启动。在那种情况下,SmartLifecycle
接口定义了另一种选择,也就是说getPhase()
定义在它的父接口Phased
中。
public interface Phased {
int getPhase();
}
public interface SmartLifecycle extends Lifecycle, Phased {
boolean isAutoStartup();
void stop(Runnable callback);
}
When starting, the objects with the lowest phase start first, and when stopping, the reverse order is followed. Therefore, an object that implements SmartLifecycle
and whose getPhase()
method returns Integer.MIN_VALUE
would be among the first to start and the last to stop. At the other end of the spectrum, a phase value of Integer.MAX_VALUE
would indicate that the object should be started last and stopped first (likely because it depends on other processes to be running). When considering the phase value, it’s also important to know that the default phase for any "normal" Lifecycle
object that does not implement SmartLifecycle
would be 0. Therefore, any negative phase value would indicate that an object should start before those standard components (and stop after them), and vice versa for any positive phase value.
当开始时,最低相位的对象先启动,当停止时,最高相位的对象先停止。因此,实现了SmartLifecycle
接口,getPhase()
方法返回值为Integer.MIN_VALUE
的对象将最先启动并最后停止。另一方面,相位值Integer.MAX_VALUE
表明对象应该最后启动,最先停止(可能是因为它依赖其它运行的进程)。当考虑相位值时,知道任何没有实现SmartLifecycle
接口的Lifecycle
对象的默认值为0是很重要的。因此,任何负相位值表示对象应该在那么标准组件之前启动(在它们之后停止),反之为任何正相位值。
As you can see the stop method defined by SmartLifecycle
accepts a callback. Any implementation must invoke that callback’s run()
method after that implementation’s shutdown process is complete. That enables asynchronous shutdown where necessary since the default implementation of the LifecycleProcessor
interface, DefaultLifecycleProcessor
, will wait up to its timeout value for the group of objects within each phase to invoke that callback. The default per-phase timeout is 30 seconds. You can override the default lifecycle processor instance by defining a bean named "lifecycleProcessor" within the context. If you only want to modify the timeout, then defining the following would be sufficient:
正如你看到的,在SmartLifecycle
中定义的停止方法接收一个回调函数。任何实现在关闭进程完成之后都必须调用回调的run()
方法。当需要时这可以进行异步关闭,因为LifecycleProcessor
接口、DefaultLifecycleProcessor
接口的默认实现会等待每个阶段的对象组直到达到超时值,然后调用回调函数。默认每个时期的超时值为30秒。你可以在上下文中通过定义名为"lifecycleProcessor"的bean来覆盖默认的生命周期处理器实例。如果你只想修改超时值,如下定义是足够的:
<bean id="lifecycleProcessor" class="org.springframework.context.support.DefaultLifecycleProcessor">
<!-- timeout value in milliseconds -->
<property name="timeoutPerShutdownPhase" value="10000"/>
</bean>
As mentioned, the LifecycleProcessor
interface defines callback methods for the refreshing and closing of the context as well. The latter will simply drive the shutdown process as if stop()
had been called explicitly, but it will happen when the context is closing. The refresh
callback on the other hand enables another feature of SmartLifecycle
beans. When the context is refreshed (after all objects have been instantiated and initialized), that callback will be invoked, and at that point the default lifecycle processor will check the boolean value returned by each SmartLifecycle
object’s isAutoStartup()
method. If "true", then that object will be started at that point rather than waiting for an explicit invocation of the context’s or its own start()
method (unlike the context refresh, the context start does not happen automatically for a standard context implementation). The "phase" value as well as any "depends-on" relationships will determine the startup order in the same way as described above.
像上面提到的那样,LifecycleProcessor
接口为再刷新和上下文的关闭也定义了回调方法。后者会简单的驱动关闭进程就像显式的调用了stop()
方法一样,但当上下文关闭时它才会发生。另一方面refresh
回调能使SmartLifecycle
beans的另一个功能可用。当上下文再刷新时(所有对象已经实例化并初始化),回调函数将被调用,那时默认的生命周期处理器将会检查每个SmartLifecycle
对象的isAutoStartup()
方法返回的布尔值。如果为true
,对象将会在那时启动而不是等待上下文的显式调用或它自己的start()
方法(不像上下文再刷新,对于一个标准的上下文实现上下启动不会自动发生)。"phase"值以及"depends-on"关系将决定启动顺序,像上面描述的一样。
Shutting down the Spring IoC container gracefully in non-web applications
This section applies only to non-web applications. Spring’s web-based
ApplicationContext
implementations already have code in place to shut down the Spring IoC container gracefully when the relevant web application is shut down.
这一节只应用于非web应用。Spring的基于web的
ApplicationContext
实现已经有代码来处理当相关的web应用关闭时,妥善关闭Spring IoC容器的问题。
If you are using Spring’s IoC container in a non-web application environment; for example, in a rich client desktop environment; you register a shutdown hook with the JVM. Doing so ensures a graceful shutdown and calls the relevant destroy methods on your singleton beans so that all resources are released. Of course, you must still configure and implement these destroy callbacks correctly.
如果你在非web应用环境使用Spring的IoC容器;例如,在一个富桌面客户端环境中,你在JVM中注册一个关闭钩子。这样做确保了妥善的关闭,为了释放所有资源需要调用与单例beans相关的析构方法。当然,你仍然必须正确的配置和实现这些销毁回调函数。
To register a shutdown hook, you call the registerShutdownHook()
method that is declared on the ConfigurableApplicationContext
interface:
为了注册一个关闭钩子,你可以调用ConfigurableApplicationContext
接口中声明的registerShutdownHook()
方法:
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public final class Boot {
public static void main(final String[] args) throws Exception {
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext(
new String []{"beans.xml"});
// add a shutdown hook for the above context...
ctx.registerShutdownHook();
// app runs here...
// main method exits, hook is called prior to the app shutting down...
}
}
3.6.2 ApplicationContextAware and BeanNameAware
When an ApplicationContext
creates an object instance that implements the org.springframework.context.ApplicationContextAware
interface, the instance is provided with a reference to that ApplicationContext
.
当ApplicationContext
创建一个实现org.springframework.context.ApplicationContextAware
接口的对象实例时,这个实例会提供一个ApplicationContext
的引用。
public interface ApplicationContextAware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
Thus beans can manipulate programmatically the ApplicationContext
that created them, through the ApplicationContext
interface, or by casting the reference to a known subclass of this interface, such as ConfigurableApplicationContext
, which exposes additional functionality. One use would be the programmatic retrieval of other beans. Sometimes this capability is useful; however, in general you should avoid it, because it couples the code to Spring and does not follow the Inversion of Control style, where collaborators are provided to beans as properties. Other methods of the ApplicationContext
provide access to file resources, publishing application events, and accessing a MessageSource
. These additional features are described in Section 3.15, “Additional Capabilities of the ApplicationContext”.
因此beans可以以编程方式操纵创建它们的ApplicationContext
,通过ApplicationContext
接口,或通过将引用抛给这个接口的一个已知子类,例如ConfigurableApplicationContext
,它暴露了额外的功能。一个方法是编程式检索其他的bean。有时这个能力是很有用的,但是通常你应该避免使用它,因为它耦合了代码和Spring,不能遵循控制反转的风格,在控制反转中协作者是作为属性提供给beans的。ApplicationContext
的其它方法提供了对文件资源的访问,发布应用事件,访问MessageSource
的功能。这些额外的特性将在3.15小节『ApplicationContext”的额外能力』中描述。
As of Spring 2.5, autowiring is another alternative to obtain reference to the ApplicationContext
. The "traditional" constructor
and byType
autowiring modes (as described in Section 3.4.5, “Autowiring collaborators”) can provide a dependency of type ApplicationContext
for a constructor argument or setter method parameter, respectively. For more flexibility, including the ability to autowire fields and multiple parameter methods, use the new annotation-based autowiring features. If you do, the ApplicationContext
is autowired into a field, constructor argument, or method parameter that is expecting the ApplicationContext
type if the field, constructor, or method in question carries the @Autowired
annotation. For more information, see Section 3.9.2, “@Autowired”.
从Spring 2.5起,自动装配是另一种可替代的获得ApplicationContext
引用的方法。『传统的』constructor
和byType
自动装配模式(如3.4.5小节所述,『自动装配协作者』)可以分别为构造函数参数或setter方法参数提供ApplicationContext
类型的依赖。更多的灵活性包括自动装配变量的能力和多参数方法,使用新的基于注解的自动装配特性。如果你这一做的话,ApplicationContext
可以被自动装配到变量中,构造函数参数中或方法参数中,如果讨论的变量,构造函数或方法有@Autowired
注解,那么可以期望它是ApplicationContext
类型。更多信息请看3.9.2小节,@autowired
。
When an ApplicationContext
creates a class that implements the org.springframework.beans.factory.BeanNameAware
interface, the class is provided with a reference to the name defined in its associated object definition.
当ApplicationContext
创建一个实现了org.springframework.beans.factory.BeanNameAware
接口的类时,类中有相关的对象定义中定义的名称的引用。
public interface BeanNameAware {
void setBeanName(String name) throws BeansException;
}
The callback is invoked after population of normal bean properties but before an initialization callback such as InitializingBean
afterPropertiesSet or a custom init-method.
在正常的bean属性填入之后,回调方法调用,但在初始化回调方法之前,例如InitializingBean
的afterPropertiesSet或一个定制的初始化方法。
3.6.3 Other Aware interfaces
Besides ApplicationContextAware
and BeanNameAware
discussed above, Spring offers a range of Aware
interfaces that allow beans to indicate to the container that they require a certain infrastructure dependency. The most important Aware
interfaces are summarized below - as a general rule, the name is a good indication of the dependency type:
除了上面讨论的ApplicationContextAware
和BeanNameAware
之外,Spring给予了一系列Aware
接口来允许beans向容器表明它们需要一个确定的基础结构依赖。最重要的Aware
接口总结如下——作为一个通用规则,名字是依赖类型的一个很好暗示:
Table 3.4. Aware interfaces
Name | Injected Dependency | Explained in |
---|---|---|
ApplicationContextAware | Declaring ApplicationContext | Section 3.6.2, “ApplicationContextAware and BeanNameAware” |
ApplicationEventPublisherAware | Event publisher of the enclosing ApplicationContext | Section 3.15, “Additional Capabilities of the ApplicationContext” |
BeanClassLoaderAware | Class loader used to load the bean classes. | Section 3.3.2, “Instantiating beans” |
BeanFactoryAware | Declaring BeanFactory | Section 3.6.2, “ApplicationContextAware and BeanNameAware” |
BeanNameAware | Name of the declaring bean | Section 3.6.2, “ApplicationContextAware and BeanNameAware” |
BootstrapContextAware | Resource adapter BootstrapContext the container runs in. Typically available only in JCA aware ApplicationContexts | Chapter 28, JCA CCI |
LoadTimeWeaverAware | Defined weaver for processing class definition at load time | Section 7.8.4, “Load-time weaving with AspectJ in the Spring Framework” |
MessageSourceAware | Configured strategy for resolving messages (with support for parametrization and internationalization) | Section 3.15, “Additional Capabilities of the ApplicationContext” |
NotificationPublisherAware | Spring JMX notification publisher | Section 27.7, “Notifications” |
ResourceLoaderAware | Configured loader for low-level access to resources | Chapter 4, Resources |
ServletConfigAware | Current ServletConfig the container runs in. Valid only in a web-aware Spring ApplicationContext | Chapter 18, Web MVC framework |
ServletContextAware | Current ServletContext the container runs in. Valid only in a web-aware Spring ApplicationContext | Chapter 18, Web MVC framework |
表3.4. Aware接口
Name | Injected Dependency | Explained in |
---|---|---|
ApplicationContextAware | 声明ApplicationContext
|
Section 3.6.2, “ApplicationContextAware and BeanNameAware” |
ApplicationEventPublisherAware | 封装事件发布的ApplicationContext
|
Section 3.15, “Additional Capabilities of the ApplicationContext” |
BeanClassLoaderAware | 用来加载bean的类加载器 | Section 3.3.2, “Instantiating beans” |
BeanFactoryAware | 声明BeanFactory
|
Section 3.6.2, “ApplicationContextAware and BeanNameAware” |
BeanNameAware | 声明的bean的名字 | Section 3.6.2, “ApplicationContextAware and BeanNameAware” |
BootstrapContextAware | 容器运行的资源自适应BootstrapContext . 通常只在JCA aware ApplicationContexts 可获得 |
Chapter 28, JCA CCI |
LoadTimeWeaverAware | 加载时为处理类定义定义的weaver | Section 7.8.4, “Load-time weaving with AspectJ in the Spring Framework” |
MessageSourceAware | 解析消息配置策略 (支持参数化和国际化) | Section 3.15, “Additional Capabilities of the ApplicationContext” |
NotificationPublisherAware | Spring JMX通知发布器 | Section 27.7, “Notifications” |
ResourceLoaderAware | 为底层访问资源配置的加载器 | Chapter 4, Resources |
ServletConfigAware | 容器运行的当前ServletConfig 。 仅在web感知的Spring ApplicationContext 中有效 |
Chapter 18, Web MVC framework |
ServletContextAware | 容器运行的当前ServletContext 。 仅在web感知的Spring ApplicationContext 中有效 |
Chapter 18, Web MVC framework |
Note again that usage of these interfaces ties your code to the Spring API and does not follow the Inversion of Control style. As such, they are recommended for infrastructure beans that require programmatic access to the container.
注意这些接口的用法将你的代码与Spring进行了捆绑,不符合控制反转的风格。因此,它们是为那么需要以编程方式访问容器的基础结构beans推荐的。