spring学习笔记(三)

5 篇文章 1 订阅
Combining lifecycle mechanisms

As of Spring 2.5, you have three options for controlling bean lifecycle behavior: theInitializingBean and DisposableBean callback interfaces; custominit() anddestroy() methods; and the@PostConstruct and @PreDestroy annotations. You can combine these mechanisms to control a given bean.

[Note]Note

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.

调用顺序

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 interface

  • A custom configured init() method

Destroy methods are called in the same order:

  • Methods annotated with @PreDestroy

  • destroy() as defined by theDisposableBean callback interface

  • A custom configured destroy() method


Shutting down the Spring IoC container gracefully in non-web applications
[Note]Note

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.

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.

To register a shutdown hook, you call the registerShutdownHook() method that is declared on theAbstractApplicationContext class:

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public final class Boot {

  public static void main(final String[] args) throws Exception {
      AbstractApplicationContext 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...
  }
}

5.6.2 ApplicationContextAware andBeanNameAware

When an ApplicationContext creates a class that implements theorg.springframework.context.ApplicationContextAware interface, the class is provided with a reference to thatApplicationContext.

public interface ApplicationContextAware {

  void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

Thus beans can manipulate programmatically the ApplicationContext that created them, through theApplicationContext interface, or by casting the reference to a known subclass of this interface, such asConfigurableApplicationContext, 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 5.14, “Additional Capabilities of the ApplicationContext

As of Spring 2.5, autowiring is another alternative to obtain reference to theApplicationContext. The "traditional"constructor andbyType autowiring modes (as described inSection 5.4.5, “Autowiring collaborators”) can provide a dependency of typeApplicationContext 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, theApplicationContext is autowired into a field, constructor argument, or method parameter that is expecting theApplicationContext type if the field, constructor, or method in question carries the@Autowired annotation. For more information, seeSection 5.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.

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 asInitializingBeansafterPropertiesSet or a custom init-method.


5.7 Bean definition inheritance

A bean definition can contain a lot of configuration information, including constructor arguments, property values, and container-specific information such as initialization method, static factory method name, and so on. A child bean definition inherits configuration data from a parent definition. The child definition can override some values, or add others, as needed. Using parent and child bean definitions can save a lot of typing. Effectively, this is a form of templating.

If you work with an ApplicationContext interface programmatically, child bean definitions are represented by theChildBeanDefinition class. Most users do not work with them on this level, instead configuring bean definitions declaratively in something like theClassPathXmlApplicationContext. When you use XML-based configuration metadata, you indicate a child bean definition by using theparent attribute, specifying the parent bean as the value of this attribute.

<bean id="inheritedTestBean" abstract="true"
    class="org.springframework.beans.TestBean">
  <property name="name" value="parent"/>
  <property name="age" value="1"/>
</bean>

<bean id="inheritsWithDifferentClass"
      class="org.springframework.beans.DerivedTestBean"
      parent="inheritedTestBean" init-method="initialize">

  <property name="name" value="override"/>
  <!-- the age property value of 1 will be inherited from  parent -->

</bean>

A child bean definition uses the bean class from the parent definition if none is specified, but can also override it. In the latter case, the child bean class must be compatible with the parent, that is, it must accept the parent's property values.

A child bean definition inherits constructor argument values, property values, and method overrides from the parent, with the option to add new values. Any initialization method, destroy method, and/orstatic factory method settings that you specify will override the corresponding parent settings.

The remaining settings are always taken from the child definition:depends on,autowire mode,dependency check,singleton,scope,lazy init.

The preceding example explicitly marks the parent bean definition as abstract by using theabstract attribute. If the parent definition does not specify a class, explicitly marking the parent bean definition asabstract is required, as follows:

<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>

The parent bean cannot be instantiated on its own because it is incomplete, and it is also explicitly marked asabstract. When a definition isabstract like this, it is usable only as a pure template bean definition that serves as a parent definition for child definitions. Trying to use such anabstract parent bean on its own, by referring to it as a ref property of another bean or doing an explicitgetBean() call with the parent bean id, returns an error. Similarly, the container's internalpreInstantiateSingletons() method ignores bean definitions that are defined as abstract.

[Note]Note

ApplicationContext pre-instantiates all singletons by default. Therefore, it is important (at least for singleton beans) that if you have a (parent) bean definition which you intend to use only as a template, and this definition specifies a class, you must make sure to set the abstract attribute totrue, otherwise the application context will actually (attempt to) pre-instantiate theabstract bean.



5.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 certaininfrastructure dependency. The most importantAware interfaces are summarized below - as a general rule, the name is a good indication of the dependency type:


Table 5.4. Aware interfaces
NameInjected DependencyExplained in...

ApplicationContextAware

Declaring ApplicationContext

Section 5.6.2, “ApplicationContextAware and BeanNameAware

ApplicationEventPublisherAware

Event publisher of the enclosing ApplicationContext

Section 5.14, “Additional Capabilities of theApplicationContext

BeanClassLoaderAware

Class loader used to load the bean classes.

Section 5.3.2, “Instantiating beans”

BeanFactoryAware

Declaring BeanFactory

Section 5.6.2, “ApplicationContextAware and BeanNameAware

BeanNameAware

Name of the declaring bean

Section 5.6.2, “ApplicationContextAware and BeanNameAware

BootstrapContextAware

Resource adapter BootstrapContext the container runs in. Typically available only in JCA awareApplicationContexts

Chapter 25,JCA CCI

LoadTimeWeaverAware

Defined weaver for processing class definition at load time

Section 9.8.4, “Load-time weaving with AspectJ in the Spring Framework”

MessageSourceAware

Configured strategy for resolving messages (with support for parametrization and internationalization)

Section 5.14, “Additional Capabilities of theApplicationContext

NotificationPublisherAware

Spring JMX notification publisher

Section 24.7, “Notifications”

PortletConfigAware

Current PortletConfig the container runs in. Valid only in a web-aware SpringApplicationContext

Chapter 20,Portlet MVC Framework

PortletContextAware

Current PortletContext the container runs in. Valid only in a web-aware SpringApplicationContext

Chapter 20,Portlet MVC Framework

ResourceLoaderAware

Configured loader for low-level access to resources

Chapter 6,Resources

ServletConfigAware

Current ServletConfig the container runs in. Valid only in a web-aware SpringApplicationContext

Chapter 17,Web MVC framework

ServletContextAware

Current ServletContext the container runs in. Valid only in a web-aware SpringApplicationContext

Chapter 17,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.


5.8.1 Customizing beans using a BeanPostProcessor

The BeanPostProcessor interface defines callback methods that you can implement to provide your own (or override the container's default) instantiation logic, dependency-resolution logic, and so forth. If you want to implement some custom logic after the Spring container finishes instantiating, configuring, and initializing a bean, you can plug in one or more BeanPostProcessor implementations.

You can configure multiple BeanPostProcessor instances, and you can control the order in which theseBeanPostProcessors execute by setting theorder property. You can set this property only if theBeanPostProcessor implements theOrdered interface; if you write your ownBeanPostProcessor you should consider implementing theOrdered interface too. For further details, consult the Javadoc for theBeanPostProcessor andOrdered interfaces. See also the note below onprogrammatic registration ofBeanPostProcessors

[Note]Note

BeanPostProcessors operate on bean (or object) instances; that is to say, the Spring IoC container instantiates a bean instance andthenBeanPostProcessors do their work.

BeanPostProcessors are scoped per-container. This is only relevant if you are using container hierarchies. If you define aBeanPostProcessor in one container, it willonly post-process the beans in that container. In other words, beans that are defined in one container are not post-processed by aBeanPostProcessor defined in another container, even if both containers are part of the same hierarchy.

To change the actual bean definition (i.e., the blueprint that defines the bean), you instead need to use aBeanFactoryPostProcessor as described inSection 5.8.2, “Customizing configuration metadata with a BeanFactoryPostProcessor.

The org.springframework.beans.factory.config.BeanPostProcessor interface consists of exactly two callback methods. When such a class is registered as a post-processor with the container, for each bean instance that is created by the container, the post-processor gets a callback from the container both before container initialization methods (such as InitializingBean'safterPropertiesSet() and any declared init method) are called as well asafter any bean initialization callbacks. The post-processor can take any action with the bean instance, including ignoring the callback completely. A bean post-processor typically checks for callback interfaces or may wrap a bean with a proxy. Some Spring AOP infrastructure classes are implemented as bean post-processors in order to provide proxy-wrapping logic.

An ApplicationContext automatically detects any beans that are defined in the configuration metadata which implement theBeanPostProcessor interface. TheApplicationContext registers these beans as post-processors so that they can be called later upon bean creation. Bean post-processors can be deployed in the container just like any other beans.


5.8.2 Customizing configuration metadata with a BeanFactoryPostProcessor

The next extension point that we will look at is the org.springframework.beans.factory.config.BeanFactoryPostProcessor. The semantics of this interface are similar to those of theBeanPostProcessor, with one major difference:BeanFactoryPostProcessors operate on the bean configuration metadata; that is, the Spring IoC container allowsBeanFactoryPostProcessors to read the configuration metadata and potentially change itbefore the container instantiates any beans other thanBeanFactoryPostProcessors.

You can configure multiple BeanFactoryPostProcessors, and you can control the order in which theseBeanFactoryPostProcessors execute by setting theorder property. However, you can only set this property if theBeanFactoryPostProcessor implements theOrdered interface. If you write your ownBeanFactoryPostProcessor, you should consider implementing theOrdered interface too. Consult the Javadoc for theBeanFactoryPostProcessor andOrdered interfaces for more details.

[Note]Note

If you want to change the actual bean instances (i.e., the objects that are created from the configuration metadata), then you instead need to use aBeanPostProcessor (described above in Section 5.8.1, “Customizing beans using a BeanPostProcessor). While it is technically possible to work with bean instances within aBeanFactoryPostProcessor (e.g., usingBeanFactory.getBean()), doing so causes premature bean instantiation, violating the standard container lifecycle. This may cause negative side effects such as bypassing bean post processing.

Also, BeanFactoryPostProcessors are scoped per-container. This is only relevant if you are using container hierarchies. If you define aBeanFactoryPostProcessor in one container, it willonly be applied to the bean definitions in that container. Bean definitions in one container will not be post-processed byBeanFactoryPostProcessors in another container, even if both containers are part of the same hierarchy.

A bean factory post-processor is executed automatically when it is declared inside anApplicationContext, in order to apply changes to the configuration metadata that define the container. Spring includes a number of predefined bean factory post-processors, such asPropertyOverrideConfigurer andPropertyPlaceholderConfigurer. A customBeanFactoryPostProcessor can also be used, for example, to register custom property editors.

An ApplicationContext automatically detects any beans that are deployed into it that implement theBeanFactoryPostProcessor interface. It uses these beans as bean factory post-processors, at the appropriate time. You can deploy these post-processor beans as you would any other bean.

[Note]Note

As with BeanPostProcessors, you typically do not want to configureBeanFactoryPostProcessors for lazy initialization. If no other bean references aBean(Factory)PostProcessor, that post-processor will not get instantiated at all. Thus, marking it for lazy initialization will be ignored, and theBean(Factory)PostProcessor will be instantiated eagerly even if you set thedefault-lazy-init attribute to true on the declaration of your <beans /> element.



Example: the PropertyPlaceholderConfigurer

You use the PropertyPlaceholderConfigurer to externalize property values from a bean definition in a separate file using the standard JavaProperties format. Doing so enables the person deploying an application to customize environment-specific properties such as database URLs and passwords, without the complexity or risk of modifying the main XML definition file or files for the container.

Consider the following XML-based configuration metadata fragment, where a DataSource with placeholder values is defined. The example shows properties configured from an externalProperties file. At runtime, aPropertyPlaceholderConfigurer is applied to the metadata that will replace some properties of the DataSource. The values to replace are specified asplaceholders of the form ${property-name} which follows the Ant / log4j / JSP EL style.

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations" value="classpath:com/foo/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>

The actual values come from another file in the standard Java Properties format:

jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://production:9002
jdbc.username=sa
jdbc.password=root

Therefore, the string ${jdbc.username} is replaced at runtime with the value 'sa', and the same applies for other placeholder values that match keys in the properties file. ThePropertyPlaceholderConfigurer checks for placeholders in most properties and attributes of a bean definition. Furthermore, the placeholder prefix and suffix can be customized.

With the context namespace introduced in Spring 2.5, it is possible to configure property placeholders with a dedicated configuration element. One or more locations can be provided as a comma-separated list in thelocation attribute.

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

The PropertyPlaceholderConfigurer not only looks for properties in theProperties file you specify. By default it also checks against the JavaSystem properties if it cannot find a property in the specified properties files. You can customize this behavior by setting thesystemPropertiesMode property of the configurer with one of the following three supported integer values:

  • never (0): Never check system properties

  • fallback (1): Check system properties if not resolvable in the specified properties files. This is the default.

  • override (2): Check system properties first, before trying the specified properties files. This allows system properties to override any other property source.

Consult the Javadoc for the PropertyPlaceholderConfigurer for more information.

[Tip]Class name substitution

You can use the PropertyPlaceholderConfigurer to substitute class names, which is sometimes useful when you have to pick a particular implementation class at runtime. For example:

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

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

If the class cannot be resolved at runtime to a valid class, resolution of the bean fails when it is about to be created, which is during thepreInstantiateSingletons() phase of anApplicationContext for a non-lazy-init bean.


Example: the PropertyOverrideConfigurer

The PropertyOverrideConfigurer, another bean factory post-processor, resembles thePropertyPlaceholderConfigurer, but unlike the latter, the original definitions can have default values or no values at all for bean properties. If an overridingProperties file does not have an entry for a certain bean property, the default context definition is used.

Note that the bean definition is not aware of being overridden, so it is not immediately obvious from the XML definition file that the override configurer is being used. In case of multiplePropertyOverrideConfigurer instances that define different values for the same bean property, the last one wins, due to the overriding mechanism.

Properties file configuration lines take this format:

beanName.property=value

For example:

dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql:mydb

This example file can be used with a container definition that contains a bean calleddataSource, which hasdriver andurl properties.

Compound property names are also supported, as long as every component of the path except the final property being overridden is already non-null (presumably initialized by the constructors). In this example...

foo.fred.bob.sammy=123

... the sammy property of the bob property of the fred property of the foo bean is set to the scalar value 123.

[Note]Note

Specified override values are always literal values; they are not translated into bean references. This convention also applies when the original value in the XML bean definition specifies a bean reference.

With the context namespace introduced in Spring 2.5, it is possible to configure property overriding with a dedicated configuration element:

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

5.8.3 Customizing instantiation logic with a FactoryBean

Implement the org.springframework.beans.factory.FactoryBean interface for objects thatare themselves factories.

The FactoryBean interface is a point of pluggability into the Spring IoC container's instantiation logic. If you have complex initialization code that is better expressed in Java as opposed to a (potentially) verbose amount of XML, you can create your own FactoryBean, write the complex initialization inside that class, and then plug your customFactoryBean into the container.

The FactoryBean interface provides three methods:

  • Object getObject(): returns an instance of the object this factory creates. The instance can possibly be shared, depending on whether this factory returns singletons or prototypes.

  • boolean isSingleton(): returns true if this FactoryBean returns singletons,false otherwise.

  • Class getObjectType(): returns the object type returned by thegetObject() method ornull if the type is not known in advance.

The FactoryBean concept and interface is used in a number of places within the Spring Framework; more than 50 implementations of theFactoryBean interface ship with Spring itself.

When you need to ask a container for an actual FactoryBean instance itself instead of the bean it produces, preface the bean's id with the ampersand symbol (&) when calling thegetBean() method of the ApplicationContext. So for a givenFactoryBean with an id ofmyBean, invokinggetBean("myBean") on the container returns the product of theFactoryBean; whereas, invokinggetBean("&myBean") returns theFactoryBean instance itself.


5.9 Annotation-based container configuration

An alternative to XML setups is provided by annotation-based configuration which rely on the bytecode metadata for wiring up components instead of angle-bracket declarations. Instead of using XML to describe a bean wiring, the developer moves the configuration into the component class itself by using annotations on the relevant class, method, or field declaration. As mentioned inthe section called “Example: The RequiredAnnotationBeanPostProcessor, using aBeanPostProcessor in conjunction with annotations is a common means of extending the Spring IoC container. For example, Spring 2.0 introduced the possibility of enforcing required properties with the@Required annotation. Spring 2.5 made it possible to follow that same general approach to drive Spring's dependency injection. Essentially, the@Autowired annotation provides the same capabilities as described inSection 5.4.5, “Autowiring collaborators” but with more fine-grained control and wider applicability. Spring 2.5 also added support for JSR-250 annotations such as@PostConstruct, and@PreDestroy. Spring 3.0 added support for JSR-330 (Dependency Injection for Java) annotations contained in the javax.inject package such as@Inject and@Named. Details about those annotations can be found in therelevant section.

[Note]Note

Annotation injection is performed before XML injection, thus the latter configuration will override the former for properties wired through both approaches.

As always, you can register them as individual bean definitions, but they can also be implicitly registered by including the following tag in an XML-based Spring configuration (notice the inclusion of thecontext namespace):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd">

   <context:annotation-config/>

</beans>

(The implicitly registered post-processors include AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor, as well as the aforementionedRequiredAnnotationBeanPostProcessor.)

[Note]Note

<context:annotation-config/> only looks for annotations on beans in the same application context in which it is defined. This means that, if you put<context:annotation-config/> in aWebApplicationContext for a DispatcherServlet, it only checks for@Autowired beans in your controllers, and not your services. SeeSection 17.2, “The DispatcherServlet for more information.



5.9.2 @Autowired

As expected, you can apply the @Autowired annotation to "traditional" setter methods:

public class SimpleMovieLister {

  private MovieFinder movieFinder;

  @Autowired
  public void setMovieFinder(MovieFinder movieFinder) {
      this.movieFinder = movieFinder;
  }

  // ...
}
[Note]Note

JSR 330's @Inject annotation can be used in place of Spring's @Autowired annotation in the examples below. See here for more details

You can also apply the annotation to methods with arbitrary names and/or multiple arguments:

public class MovieRecommender {

  private MovieCatalog movieCatalog;

  private CustomerPreferenceDao customerPreferenceDao;

  @Autowired
  public void prepare(MovieCatalog movieCatalog,
                      CustomerPreferenceDao customerPreferenceDao) {
      this.movieCatalog = movieCatalog;
      this.customerPreferenceDao = customerPreferenceDao;
  }

  // ...
}

You can apply @Autowired to constructors and fields:

public class MovieRecommender {

  @Autowired
  private MovieCatalog movieCatalog;

  private CustomerPreferenceDao customerPreferenceDao;

  @Autowired
  public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
      this.customerPreferenceDao = customerPreferenceDao;
  }

  // ...
}

It is also possible to provide all beans of a particular type from theApplicationContext by adding the annotation to a field or method that expects an array of that type:

public class MovieRecommender {

  @Autowired
  private MovieCatalog[] movieCatalogs;

  // ...
}

The same applies for typed collections:

public class MovieRecommender {

  private Set<MovieCatalog> movieCatalogs;

  @Autowired
  public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {
      this.movieCatalogs = movieCatalogs;
  }

  // ...
}

Even typed Maps can be autowired as long as the expected key type is String. The Map values will contain all beans of the expected type, and the keys will contain the corresponding bean names:

public class MovieRecommender {

  private Map<String, MovieCatalog> movieCatalogs;

  @Autowired
  public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {
      this.movieCatalogs = movieCatalogs;
  }

  // ...
}

By default, the autowiring fails whenever zero candidate beans are available; the default behavior is to treat annotated methods, constructors, and fields as indicatingrequired dependencies. This behavior can be changed as demonstrated below.

public class SimpleMovieLister {

  private MovieFinder movieFinder;

  @Autowired(required=false)
  public void setMovieFinder(MovieFinder movieFinder) {
      this.movieFinder = movieFinder;
  }

  // ...
}
[Note]Note

Only one annotated constructor per-class can be marked asrequired, but multiple non-required constructors can be annotated. In that case, each is considered among the candidates and Spring uses thegreediest constructor whose dependencies can be satisfied, that is the constructor that has the largest number of arguments.

@Autowired's required attribute is recommended over the@Required annotation. Therequired attribute indicates that the property is not required for autowiring purposes, the property is ignored if it cannot be autowired.@Required, on the other hand, is stronger in that it enforces the property that was set by any means supported by the container. If no value is injected, a corresponding exception is raised.

You can also use @Autowired for interfaces that are well-known resolvable dependencies:BeanFactory,ApplicationContext,Environment, ResourceLoader,ApplicationEventPublisher, and MessageSource. These interfaces and their extended interfaces, such asConfigurableApplicationContext orResourcePatternResolver, are automatically resolved, with no special setup necessary.

public class MovieRecommender {

  @Autowired
  private ApplicationContext context;

  public MovieRecommender() {
  }

  // ...
}
[Note]Note

@Autowired, @Inject,@Resource, and@Value annotations are handled by a SpringBeanPostProcessor implementations which in turn means that youcannot apply these annotations within your ownBeanPostProcessor or BeanFactoryPostProcessor types (if any). These types must be 'wired up' explicitly via XML or using a Spring@Bean method.



建议使用@Resource,如果要使用@Autowired,最好和@Qualifier一起使用
[Tip]Tip

If you intend to express annotation-driven injection by name, do not primarily use@Autowired, even if is technically capable of referring to a bean name through@Qualifier values. Instead, use the JSR-250 @Resource annotation, which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process.

As a specific consequence of this semantic difference, beans that are themselves defined as a collection or map type cannot be injected through@Autowired, because type matching is not properly applicable to them. Use@Resource for such beans, referring to the specific collection or map bean by unique name.

@Autowired applies to fields, constructors, and multi-argument methods, allowing for narrowing through qualifier annotations at the parameter level. By contrast,@Resource is supported only for fields and bean property setter methods with a single argument. As a consequence, stick with qualifiers if your injection target is a constructor or a multi-argument method.



5.9.5 @Resource

@Resource不指定name,则默认使用变量名注入,如果指定了name,则用指定name的bean注入。

Spring also supports injection using the JSR-250 @Resource annotation on fields or bean property setter methods. This is a common pattern in Java EE 5 and 6, for example in JSF 1.2 managed beans or JAX-WS 2.0 endpoints. Spring supports this pattern for Spring-managed objects as well.

@Resource takes a name attribute, and by default Spring interprets that value as the bean name to be injected. In other words, it followsby-name semantics, as demonstrated in this example:

public class SimpleMovieLister {

  private MovieFinder movieFinder;

  @Resource(name="myMovieFinder")
  public void setMovieFinder(MovieFinder movieFinder) {
      this.movieFinder = movieFinder;
  }
}

If no name is specified explicitly, the default name is derived from the field name or setter method. In case of a field, it takes the field name; in case of a setter method, it takes the bean property name. So the following example is going to have the bean with name "movieFinder" injected into its setter method:

public class SimpleMovieLister {

  private MovieFinder movieFinder;

  @Resource
  public void setMovieFinder(MovieFinder movieFinder) {
      this.movieFinder = movieFinder;
  }
}
[Note]Note

The name provided with the annotation is resolved as a bean name by the ApplicationContext of which the CommonAnnotationBeanPostProcessor is aware.The names can be resolved through JNDI if you configure Spring'sSimpleJndiBeanFactory explicitly. However, it is recommended that you rely on the default behavior and simply use Spring's JNDI lookup capabilities to preserve the level of indirection.

In the exclusive case of @Resource usage with no explicit name specified, and similar to@Autowired, @Resource finds a primary type match instead of a specific named bean and resolves well-known resolvable dependencies: theBeanFactory, ApplicationContext, ResourceLoader, ApplicationEventPublisher, andMessageSource interfaces.

Thus in the following example, the customerPreferenceDao field first looks for a bean named customerPreferenceDao, then falls back to a primary type match for the typeCustomerPreferenceDao. The "context" field is injected based on the known resolvable dependency typeApplicationContext.

public class MovieRecommender {

  @Resource
  private CustomerPreferenceDao customerPreferenceDao;

  @Resource
  private ApplicationContext context;

  public MovieRecommender() {
  }

  // ...
}

5.9.6 @PostConstruct and @PreDestroy

初始化方法和销毁方法

The CommonAnnotationBeanPostProcessor not only recognizes the @Resource annotation but also the JSR-250 lifecycle annotations. Introduced in Spring 2.5, the support for these annotations offers yet another alternative to those described in initialization callbacks and destruction callbacks. Provided that the CommonAnnotationBeanPostProcessor is registered within the Spring ApplicationContext, a method carrying one of these annotations is invoked at the same point in the lifecycle as the corresponding Spring lifecycle interface method or explicitly declared callback method. In the example below, the cache will be pre-populated upon initialization and cleared upon destruction.

public class CachingMovieLister {

  @PostConstruct
  public void populateMovieCache() {
      // populates the movie cache upon initialization...
  }

  @PreDestroy
  public void clearMovieCache() {
      // clears the movie cache upon destruction...
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring是一个开源的Java框架,用于构建企业级应用程序。它提供了一种轻量级的、非侵入式的开发方式,通过依赖注入和面向切面编程等特性,简化了Java应用程序的开发过程。 以下是关于Spring学习的一些笔记: 1. IoC(控制反转):Spring通过IoC容器管理对象的创建和依赖关系的注入。通过配置文件或注解,将对象的创建和依赖关系的维护交给Spring容器来管理,降低了组件之间的耦合度。 2. DI(依赖注入):Spring通过依赖注入将对象之间的依赖关系解耦。通过构造函数、Setter方法或注解,将依赖的对象注入到目标对象中,使得对象之间的关系更加灵活和可维护。 3. AOP(面向切面编程):Spring提供了AOP的支持,可以将与业务逻辑无关的横切关注点(如日志、事务管理等)从业务逻辑中分离出来,提高了代码的可重用性和可维护性。 4. MVC(模型-视图-控制器):Spring提供了一个MVC框架,用于构建Web应用程序。通过DispatcherServlet、Controller、ViewResolver等组件,实现了请求的分发和处理,将业务逻辑和视图展示进行了分离。 5. JDBC和ORM支持:Spring提供了对JDBC和ORM框架(如Hibernate、MyBatis)的集成支持,简化了数据库访问的操作,提高了开发效率。 6. 事务管理:Spring提供了对事务的支持,通过声明式事务管理和编程式事务管理,实现了对数据库事务的控制和管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值