20191225 Spring official documents (Core 1.6-1.8)

1.6. Custom nature of Bean

Spring Framework provides a number of interfaces, can be used to customize properties of the Bean.

1.6.1. Lifecycle callbacks

In order to interact with the management of the lifecycle of a bean container can be achieved in the Spring InitializingBeanand DisposableBeaninterfaces. Container calls afterPropertiesSet()and destroy()the bean to perform certain actions upon initialization and destruction of bean.

Usually, JSR-250 @PostConstructand @PreDestroynotes are considered best practice to receive the life cycle in modern Spring application callback. Use these comments mean that your bean is not coupled to Spring-specific interfaces.

If you do not want to use the JSR-250 annotations, but you still want to remove the coupling, consider <bean/>labels init-methodand destroy-methodor @Beanannotations initMethodand destroyMethodattributes.

In the interior, Spring Framework using BeanPostProcessorimplementations to process any callback interface it can find and call the appropriate method. If you need custom features or other lifecycle behavior, Spring does not provide a default, you can own to achieve the BeanPostProcessor .

In addition to initialization and destruction callbacks outside, Spring managed objects can also implement Lifecyclean interface, so that these objects can participate in the startup and shutdown process driven by the vessel's own life cycle.

Use @PostConstructand InitializingBeanwhen to call the @PostConstructannotated method, @PostConstructusing a post-processor, InitializingBeanit is not. @PreDestroyFirst call DisposableBeanafter call.

It recommends the use of annotations @PostConstructand @PreDestroy.

Destruction callbacks

org.springframework.beans.factory.DisposableBeaninterface

@PreDestroy

<bean/>Label destroy-methodattribute

@BeanAnnotation destroyMethodproperties

You can <bean>elements destroy-methodassigned a special value (attribute inferred) indicating that the specific common Spring bean class automatically detected closeor shutdownmethod. (Implemented java.lang.AutoCloseableor java.io.Closeablematching any class.) You can also <beans>elements default-destroy-methodprovided on this particular attribute value ( inferred) to set the behavior to the entire bean. Please note that this is the default behavior of Java configuration.

The default initialization and destruction methods

When you write initialization and destruction callbacks are not using Spring InitializingBeanand DisposableBeanname callback interface, the usual method of writing, such as init(), , initialize(), dispose()and so on. Ideally, such names lifecycle callback methods should be standardized throughout the project, so that all developers are using the same method name and ensure consistency.

<beans default-init-method="init" default-destroy-method="destroy">

    <bean id="blogService" class="com.something.DefaultBlogService">
        <property name="blogDao" ref="blogDao" />
    </bean>

</beans>

By using <bean/>its own init-methodand destroy-methodto override the default value for the attribute (in XML) method name.

After the Spring container to ensure that all dependencies as bean immediately calls the configured initialization callback. Therefore, in reference to the original bean initialization callback is called, which means that AOP interceptors and so have not been applied bean. First, create a completely objective bean, and then apply the AOP proxy with its interceptor chain (for example). If the target Bean and agents are defined, your code can even bypass the proxy to interact with the original target Bean. Therefore, the interceptor will be applied to the init method is inconsistent, because doing so would target Bean's life cycle is coupled to its agent, or interceptors, and when your code to interact directly with the original target Bean will leave strange semantics.

A combination of life-cycle mechanism

Starting Spring 2.5, you can use three options to control the behavior of Bean Lifecycle:

  • InitializingBeanAnd DisposableBeancallback interface
  • Customized init()and destroy()methods
  • @PostConstructAnd @PreDestroycomments.

If a bean is configured with multiple lifecycle mechanisms, and configure a different name for each method mechanism, will be in the order listed after this annotation method of execution for each configuration. However, if a plurality of lifecycle mechanisms more lifecycle mechanisms (e.g., init (), for the initialization method) configured with the same name of the method, the method will be executed once.

Lifecycle mechanisms for a variety of different configurations of the same method for initializing a bean follows:

  1. With @PostConstructannotated method
  2. By the InitializingBeancallback interface definedafterPropertiesSet()
  3. Customized configuration init()method

The same call to order the destruction method:

  1. With @PreDestroyannotated method
  2. By the DisposableBeancallback interface defineddestroy()
  3. Customized configuration destroy()method

Starting and closing the container callback

org.springframework.context.Lifecycle Interface has its own life cycle requirements (such as start and stop some background processes) of any object defines the basic method.

Any Spring managed objects can implement Lifecycleinterfaces. Then, when the ApplicationContext itself receives the start and stop signals (e.g., for stopping the Java Runtime / restart scenes), it will realize that all cascaded calls Lifecycle defined in this context. By delegating it to one org.springframework.context.LifecycleProcessor, in order to achieve this purpose.

Spring will automatically register an org.springframework.context.support.DefaultLifecycleProcessorobject.

LifecycleProcessorIt is Lifecyclethe expansion interface. It also adds two other ways to respond to the context of being refreshed and closed.

General org.springframework.context.LifecycleInterface is a general agreement explicitly start and stop notice, does not mean that automatically start when the context refresh. For fine control (including start-up phase) for automatically launching a particular bean, consider achieved org.springframework.context.SmartLifecycle.

Also, please note that the guarantee will not issue a stop notice before destroying. When conventional closed before the spread of conventional destroy callback, all LifecycleBean first stop will receive a notification. However, heat or refresh refresh aborted when trying to call only in the context of the life cycle destroyapproach.

Startup and shutdown sequence of calls can be important. If there is "dependency" relationship between any two objects, the relying party started after its dependent objects, and stop before the dependent objects. Sometimes, however, the direct dependency is unknown. You may only know the object of some type should precede the object of another type of start. In these cases, SmartLifecycleanother option, i.e. the interface parent interface definition Phaseddefined by the getPhase()method.

At startup, the lowest phase objects first start. When stopped, follow the reverse order. Therefore, to achieve SmartLifecyclethe return of Integer.MIN_VALUEthe getPhase()object's methods would be subject first to start and the last to stop. At the other end of the spectrum, the phase value Integer.MAX_VALUEindicates that the object should be the last start and first stop (probably because the object depends on other running processes). When considering the phase value, it is also important to know that for any "normal" does not implement SmartLifecyclethe Lifecycledefault phase is 0. Therefore, any negative values indicate that the phase object should start (and stop after their) until these standard components. For any positive phase value, and vice versa. SmartLifecycleThe default phase is Integer.MAX_VALUE.

SmartLifecycleDefined stopmethod accepts a callback. After closing process of the implementation is complete, any implementation must call all the callback run()method. Since the LifecycleProcessordefault interface implementations DefaultLifecycleProcessorwill target groups within each stage waiting for its time-out value to invoke the callback, so you can enable asynchronous closed when necessary. Each phase is the default timeout 30seconds. You can name by defining the context lifecycleProcessorof the bean to override the default life cycle of the processor instances. If you want to modify the time-out, to the following definitions:

<bean id="lifecycleProcessor" class="org.springframework.context.support.DefaultLifecycleProcessor">
    <!-- timeout value in milliseconds -->
    <property name="timeoutPerShutdownPhase" value="10000"/>
</bean>

As described above, LifecycleProcessorthe interface also defines a callback method for refreshing and closing context. Which drives the closing process, if it had been an explicit call to the stop()same, but it occurs when the context is closed. On the other hand, the "Refresh" callback enabled SmartLifecycleanother feature of the bean. When you refresh the context (after all objects are instantiated and initialized), the callback will be called. At this time, the life cycle of the default processor will check each object SmartLifecycle isAutoStartup()Boolean value returned by the method. If it is true, then the start point of the object, rather than waiting for its own context or explicitly call start()process (context refreshing and different standards for the context implementation, context startup does not occur automatically). phaseValue is determined as the startup sequence according to any preceding relation "dependent" type and.

In non-Web applications normally closed Spring IoC container

This section applies only to non-Web applications. Web-based Spring ApplicationContext implementations have a respective code, normally closed when the associated container Spring IoC Web application is closed.

If you are a non-Web application environment using the Spring IoC container (for example, in the rich client desktop environment), please register with a JVM shutdown hook. Doing so ensures that normal shutdown, and the associated call on your Singleton bean destroymethod to release all resources. You still have to properly configure and implement these destroy callback.

To register a shutdown hook, call the ConfigurableApplicationContextstatement on the interface registerShutdownHook()method, as shown in the following example:

ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");

// add a shutdown hook for the above context...
ctx.registerShutdownHook();

和 1.6.2.ApplicationContextAware BeanNameAware

ApplicationContextAware

org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces

BeanNameAware

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods

Automatic gain assembly is ApplicationContextanother way of reference. Traditional constructor and byType autowiring be provided separately ApplicationContext mode depends on the type of constructor method parameters or parameter setter. For greater flexibility, including the automatic assembly based annotation feature can automatically assemble and use a plurality of parameters field method, use. If you do so, will automatically fitted into ApplicationContext required fields, a constructor parameter or process parameters of the ApplicationContext type (if relevant field, with a constructor or method @Autowiredcomments).

org.springframework.beans.factory.BeanNameAware#setBeanName After filling the bean before the callback attribute in the bean initialization method is called.

1.6.3. Other Aware Interface

In addition ApplicationContextAware and BeanNameAware, Spring also provides a variety of Awarecallback interfaces that enable bean container may indicate to the infrastructure that they require some dependency. Typically, the name indicates the type of dependency.

name Inject dependencies
ApplicationContextAware ApplicationContext
ApplicationEventPublisherAware ApplicationContext closed the event publisher
BeanClassLoaderAware Class loader configured to load the Bean class.
BeanFactoryAware BeanFactory。
BeanNameAware Declares the name of the bean.
BootstrapContextAware BootstrapContext vessel operating in the resource adapter. ApplicationContext instances are usually available only in support of the JCA.
LoadTimeWeaverAware Defined weaver, class definitions for processing when loading.
MessageSourceAware Resolution message of policies configured (parameter support and internationalization).
NotificationPublisherAware Spring JMX notify the publisher.
ResourceLoaderAware Loader configuration for low-level access to resources.
ServletConfigAware Current ServletConfig container in which to run. Valid only in the Spring ApplicationContext Web environment.
ServletContextAware ServletContext the container in which the current run. Valid only in the Spring ApplicationContext Web environment.

Again, note the use of these interfaces your code will be bundled with the Spring API, and do not follow the "inversion of control" style. Therefore, we recommend that they need access to infrastructure Bean container programmatically.

1.7. Bean definition of inheritance

Child bean definition inherits configuration data from a parent definition. DEFINED can override certain values ​​or other values ​​added as needed. Use parent and child bean definitions bean can save a lot of input. In fact, this is a template form.

If you use the ApplicationContext interface programmatically, child bean is defined by the ChildBeanDefinitionrepresentation class. Most users do not use them on this level. But ClassPathXmlApplicationContext class declaratively like configuration defined as Bean. When using XML-based configuration metadata, you can be used parentto define the attributes are designated bean, bean and the parent value for the specified attribute.

If the child bean class definition is not specified, the bean parent class definition, but it can also be covered. In the latter case, the sub bean class parent class must be compatible with (i.e., it must accept the attribute value of the parent class).

If the parent class definition is not specified, mark the parent bean definition explicitly required abstract.

<bean id="inheritedTestBeanWithoutClass" abstract="true">
    <property name="name" value="parent"/>
    <property name="age" value="1"/>
</bean>

<bean id="inheritsWithClass" class="org.springframework.beans.DerivedTestBean"
        parent="inheritedTestBeanWithoutClass" init-method="initialize">
    <property name="name" value="override"/>
    <!-- age will inherit the value of 1 from the parent bean definition-->
</bean>

Examples of parent bean alone can not because it does not complete, and is also explicitly marked abstract. When defined as abstract, it can only be used as a pure template bean definitions, the definition of a parent as a child definition. Another attempt is referred to as the bean refproperty to use such an abstract parent bean or the getBean () using the parent ID bean explicit call will return an error. Likewise, the interior of the container preInstantiateSingletons()bypasses the bean defined abstract definitions.

By default, all of the examples previously ApplicationContext singleton. Therefore, it is important (at least for singleton bean), if there is a (parent) bean definitions only intended to serve as a template, and this definition specifies a class, it must ensure that the abstract property is set to true, otherwise the application context will In fact (try to) pre-instantiate abstract bean.

1.8. Container extension points

Typically, an application developer does not need to implement class ApplicationContext subclass. Instead, the container can be expanded by inserting a special Spring IoC integrated interface implementation.

1.8.1. Use BeanPostProcessor Custom Bean

BeanPostProcessorInterface defines callback methods, you can implement the callback methods, to provide their own (or default values ​​covered container) instantiation logic, the dependency resolution logic. After implement custom logic if you want to complete the instantiated Spring container, configuration and initialization bean, the insert may be one or more custom BeanPostProcessor achieved.

You can configure multiple instances BeanPostProcessor, and can be provided orderto control the execution order of these attributes BeanPostProcessor examples. BeanPostProcessor only achieve Orderedif the interface can set this property.

Spring IoC container instantiates a bean instance, then the implementation of their work BeanPostProcessor instance.

BeanPostProcessor Examples are scoped by the container. Only when using the container hierarchy, this makes sense. If a BeanPostProcessor defined in one vessel, it will be processed only after the container bean. In other words, a container is not defined in the post-processing bean BeanPostProcessor define another container, even if both containers are part of the same hierarchy as well.

To change the actual bean definition (ie, the definition of bean blueprint), you need to use BeanFactoryPostProcessor.

org.springframework.beans.factory.config.BeanPostProcessorMethod callback interface consists of two components. When such the processor is registered as a container, for each container bean instance is created, the processor will in the container after the initialization process (e.g. InitializingBean.afterPropertiesSet()to be called before and after being used or any declared init method). After the processor can perform any operations on the bean instance, including ignoring the callback. After Bean processor typically checks callback interface, or you can use proxy wrapper Bean. Some Spring AOP infrastructure classes are implemented as bean post processor logic to provide the proxy wrapper.

ApplicationContext achieved automatically detects all bean BeanPostProcessor interface configuration metadata defined. These ApplicationContext Bean registered as a post-processor for later recall them when creating Bean. After Bean processor may be deployed in the same manner with the other container Bean.

Note that, by using a configuration based on the @Beandeclaration BeanPostProcessor factory method, the return type plant should be achieved class itself or at least org.springframework.beans.factory.config.BeanPostProcessorthe interface, to clearly show the nature of the post-processor bean. Otherwise, ApplicationContext can not automatically detect it by type before it is completely created. BeanPostProcessor due to the need to apply an early example of initializing the context of other bean, so this type of early detection is crucial.

While the preferred method is by registered BeanPostProcessor ApplicationContext automatically detected (as previously described), but you can use ConfigurableBeanFactorythe addBeanPostProcessormethod to register them programmatically. When you need to assess conditions before registering logic, or even need cross-context hierarchy replication Bean post-processor, which will be very useful. Note, however, BeanPostProcessor instances programmatically add non-compliance Orderedinterface. Here, the order of registration determines the order of execution. Also note, BeanPostProcessor instances programmatically register is always processed before instances by automatically detecting registration, regardless of any clear order.

BeanPostProcessor interface class is implemented a special, and the container handling them differently. All BeanPostProcessor and bean instances they are directly referenced in the startup will be instantiated as part of a special start-up phase of the ApplicationContext. Next, the sort register all instances BeanPostProcessor, and applies to all other bean container. AOP automatically because the agent itself is BeanPostProcessor achieve, so BeanPostProcessor instance, or they are directly referenced bean are not eligible for automatic proxy, and therefore no weave section.

For any such bean, you should see a reference log message: Bean someBean is not eligible for getting processed by all BeanPostProcessor interfaces (for example: not eligible for auto-proxying).

If you use automatic assembly or @Resource(likely return to automatic assembly) to Bean fitted to your BeanPostProcessor bean in the Spring in potentially access an unexpected time dependency candidates bean search type matching, thus making them unsuitable for automatic agents or other types of bean post-processing. For example, if you have a dependency, its comments @Resource field or set the name does not correspond directly with the name of the bean statement, and do not use nameproperty, then Spring will visit other bean to match them by type.

1.8.2. Use custom configuration metadata BeanFactoryPostProcessor

org.springframework.beans.factory.config.BeanFactoryPostProcessorThe semantic interface BeanPostProcessoris similar, but with one major difference: BeanFactoryPostProcessor configuration metadata operate the Bean. That is, Spring IoC container allows BeanFactoryPostProcessor read the configuration metadata, and there may be instances of a container before any change it beyond BeanFactoryPostProcessor Bean instance.

You can configure multiple BeanFactoryPostProcessorinstances, and can be provided orderto control the order in which the run attribute BeanFactoryPostProcessor examples. However, only in BeanFactoryPostProcessor achieve Orderedin order to set this property in the case of the interface. If you write your own code BeanFactoryPostProcessor, you should also consider implementing the Ordered interface.

If you want to change the actual bean instance (that is, from the configuration object metadata created), you need to use BeanPostProcessor. Although you can use the bean instance BeanFactoryPostProcessor technically (for example, through the use of BeanFactory.getBean()), but doing so will result in premature bean instantiation, in contravention of the life cycle of a standard container. This may lead to negative effects, such as bypassing the bean after processing.

Also, BeanFactoryPostProcessorexamples being scoped by the container. It makes sense only when using the container hierarchy. If BeanFactoryPostProcessor defined in one vessel, the bean definition will be applied only to the container. Bean definition of a container will not be post-treated in another container BeanFactoryPostProcessor example, even if both containers belong to the same hierarchy as well.

Bean plants after the ApplicationContext processor declares that it is performed automatically, so the changes are applied to define the configuration of the metadata container. Spring comprising a plurality of bean plants after a predefined processor, for example PropertyOverrideConfigurer, and PropertySourcesPlaceholderConfigurer. You can also use custom BeanFactoryPostProcessor, such as registering the custom property editor.

ApplicationContext automatically detects all bean deployed to achieve BeanFactoryPostProcessor wherein the interface. It will at the appropriate time as the bean bean plant postprocessor. You can deploy these post processors deployed like any other bean as bean.

And BeanPostProcessors like you usually do not want to BeanFactoryPostProcessors configured to delay initialization. If no other bean references Bean (Factory) PostProcessor, the post-processor will not be fully instantiated. Therefore, it is marked as lazy initialization will be ignored, and even if you are <beans />in the element declaration default-lazy-initset properties for true, Bean (Factory) PostProcessor will be instantiated immediately.

Example: class name substitution PropertySourcesPlaceholderConfigurer

You can PropertySourcesPlaceholderConfigureruse the standard Java Properties format attribute value to externalize Bean defined in a separate file in. Doing so allows staff to deploy application-specific properties can be customized environments, such as database URL and password, without having to modify the container main XML definition file and complicated or risky.

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
    <property name="locations" value="classpath:com/something/jdbc.properties"/>
</bean>

<bean id="dataSource" destroy-method="close"
        class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://production:9002
jdbc.username=sa
jdbc.password=root

In operation, the PropertySourcesPlaceholderConfigurerapplied metadata certain properties replacement data source. Specifies the value to be replaced is ${property-name}in the form of a placeholder, this form follows the Ant, log4j JSP EL and styles.

Accordingly, at run time ${jdbc.username}is replaced with a value sa, and other properties of the matching key file placeholder values are also suitable. PropertySourcesPlaceholderConfigurer placeholder for inspection of most properties and attributes defined bean. In addition, you can customize the placeholders prefixes and suffixes.

Spring 2.5 introduced using contextnamespaces, you can use a dedicated configuration elements of the configuration attributes placeholders. You may be provided in one or more location attributes as a comma-separated list of positions, as shown in the following example:

<context:property-placeholder location="classpath:com/something/jdbc.properties"/>

PropertySourcesPlaceholderConfigurer will not only find the specified file in the Properties property. By default, if the property can not be found in the specified properties file, it will check the Spring Environmentproperties and general Java Systemproperties.

You can use PropertySourcesPlaceholderConfigurer instead of the class name, when you have to select a specific implementation class at runtime, which is sometimes very useful. The following example shows how to do this:

<bean class="org.springframework.beans.factory.config.PropertySourcesPlaceholderConfigurer">
    <property name="locations">
        <value>classpath:com/something/strategy.properties</value>
    </property>
    <property name="properties">
        <value>custom.strategy.class=com.something.DefaultStrategy</value>
    </property>
</bean>

<bean id="serviceStrategy" class="${custom.strategy.class}"/>

If you can not run when the class resolves to a valid class, the bean will be created to resolve the failure, which is non-lazy initialization ApplicationContext the bean is preInstantiateSingletons()carried out during the stage.

Example: PropertyOverrideConfigurer

PropertyOverrideConfigurerAfter another bean plants processor, similar to PropertySourcesPlaceholderConfigurer, but different from the latter, you can have default values defined for all of the original bean properties or no value. If the file does not cover the Properties entry of a bean property, the default context definition is used.

Note, bean definitions do not know what will be covered, and therefore can not be seen from the XML definition file immediately being used to cover configurator. If there are multiple instances PropertyOverrideConfigurer define different values ​​for the same attribute bean, since the cover mechanism, will win the last instance.

Properties file configuration lines in the following format

beanName.property=value

Support Composite property:

tom.fred.bob.sammy = 123

Specified replacement value is always literal values. They are not converted to bean reference. When the original value of the XML bean definition to specify bean references, this convention also applies.

Using the context namespace introduced in Spring 2.5, may be used an element-specific configuration attribute overrides configuration, as shown in the following example:

<context:property-override location="classpath:override.properties"/>

1.8.3. Examples of custom logic FactoryBean

You can plant the object is itself implemented as org.springframework.beans.factory.FactoryBeanan interface.

FactoryBeanExamples of the interface logic is insertable Spring IoC container little. If you have complex initialization code instead of (possible) verbose XML, you can be better expressed in Java, you can create your own FactoryBean, writing complex initialization in the class, then the custom FactoryBean inserted into the container.

FactoryBean interface provides three methods:

  • Object getObject(): Returns the object created by this factory instance. Examples which may be shared, depending on the plant or a prototype embodiment of a single return.
  • boolean isSingleton(): If FactoryBean returns a singleton, then returns true, otherwise false.
  • Class getObjectType(): Returns getObject () method returns the object type, or if the type is unknown, null is returned.

Many local Spring framework uses the concept of FactoryBean and interfaces. Spring itself comes with more than 50 FactoryBean interface.

When you need to ask FactoryBean the container itself rather than its actual instance of the bean produced, please call getBean()in front of the bean id plus symbol method &.

Guess you like

Origin www.cnblogs.com/huangwenjie/p/12098568.html