显示标签为“Spring in Action”的博文。显示所有博文
显示标签为“Spring in Action”的博文。显示所有博文

2015年9月10日星期四

3. Spring in Action -- Advanced wiring

1.  An environment-specific decision is made as to which beans will and won’t be created. But rather than make that decision at build time, Spring waits to make the decision at runtime. Consequently, the same deployment unit (perhaps a WAR file) will work in all environments without being rebuilt. In version 3.1, Spring introduced bean profiles. To use profiles, you must gather all the varying bean definitions into one or more profiles and then make sure the proper profile is active when your application is deployed in each environment.

2.  In Java configuration, you can use the @Profile annotation to specify which profile a bean belongs to:

@Configuration

@Profile("dev")

public class DevelopmentProfileConfig {

  @Bean(destroyMethod="shutdown")

  public DataSource dataSource() {
      …
  }
}

The @Profile annotation applied at the class level tells Spring that the beans in this configuration class should be created only if the dev profile is active.

3.  In Spring 3.1, you could only use the @Profile annotation at the class level. Starting with Spring 3.2, however, you can use @Profile at the method level, alongside the @Bean annotation.

4.  Any bean that isn’t given a profile will always be created, regardless of what profile is active.

5.  You can also configure profiled beans in XML by setting the profile attribute of the <beans> element. Rather than creating a proliferation of XML files for each environment, you also have the option of defining <beans> elements embedded in the root <beans> element.

6.  If spring.profiles.active is set, then its value determines which profiles are active. But if spring.profiles.active isn’t set, then Spring looks to spring.profiles.default. If neither spring.profiles.active nor spring.profiles.default is set, then there are no active profiles, and only those beans that aren’t defined as being in a profile are created. You can activate multiple profiles at the same time by listing the profile names, separated by commas.

7.  There are several ways to set these properties:
  • As initialization parameters on DispatcherServlet
  • As context parameters of a web application
  • As JNDI entries
  • As environment variables
  • As JVM system properties
  • Using the @ActiveProfiles annotation on an integration test class

8.  Spring 4 offers a more general-purpose mechanism for conditional bean definitions where the condition is up to you. Spring 4 introduced a new @Conditional annotation that can be applied to @Bean methods. If the prescribed condition evaluates to true, then the bean is created. Otherwise the bean is ignored. @Conditional is given a Class that specifies the condition. The class given to @Conditional can be any type that implements the Condition interface:

   public interface Condition {

    boolean matches(ConditionContext ctx, AnnotatedTypeMetadata metadata);

}

ConditionContext is an interface that looks something like this

public interface ConditionContext {

  BeanDefinitionRegistry getRegistry();

  ConfigurableListableBeanFactory getBeanFactory();

  Environment getEnvironment();

  ResourceLoader getResourceLoader();

  ClassLoader getClassLoader();

}

From the ConditionContext, you can do the following:
  • Check for bean definitions via the BeanDefinitionRegistry returned from getRegistry().
  • Check for the presence of beans, and even dig into bean properties via the ConfigurableListableBeanFactory returned from getBeanFactory().
  • Check for the presence and values of environment variables via the Environment retrieved from getEnvironment().
  • Read and inspect the contents of resources loaded via the ResourceLoader returned from getResourceLoader().
  • Load and check for the presence of classes via the ClassLoader returned from getClassLoader().
AnnotatedTypeMetadata offers you a chance to inspect annotations that may also be placed on the @Bean method:

public interface AnnotatedTypeMetadata {

  boolean isAnnotated(String annotationType);

  Map<String, Object> getAnnotationAttributes(String annotationType);

  Map<String, Object> getAnnotationAttributes(

          String annotationType, boolean classValuesAsString);

  MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationType);

  MultiValueMap<String, Object> getAllAnnotationAttributes(

          String annotationType, boolean classValuesAsString);

}

9.  Starting with Spring 4, the @Profile annotation has been refactored to be based on @Conditional and the Condition interface:

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.TYPE, ElementType.METHOD})

@Documented

@Conditional(ProfileCondition.class)

public @interface Profile {

  String[] value();

}

ProfileCondition implements Condition and considers several factors from both ConditionContext and AnnotatedTypeMetadata in making its decision:

class ProfileCondition implements Condition {

  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

    if (context.getEnvironment() != null) {

      MultiValueMap<String, Object> attrs =

          metadata.getAllAnnotationAttributes(Profile.class.getName());

      if (attrs != null) {

        for (Object value : attrs.get("value")) {

          if (context.getEnvironment().acceptsProfiles(((String[]) value))) {
            return true;
          }

        }

        return false;

      }

    }

    return true;

  }

}

10.  When there’s more than one matching bean, the ambiguity prevents Spring from autowiring the property, constructor argument, or method parameter and Spring throws a NoUniqueBeanDefinitionException.

11.  You can avoid autowiring ambiguity by designating one of the candidate beans as a primary bean. In the event of any ambiguity, Spring will choose the primary bean over any other candidate beans. You can express that favorite choice in Spring using the @Primary annotation. @Primary can be used either alongside @Component for beans that are component-scanned or alongside @Bean for beans declared in Java configuration. If you’re configuring your beans in XML, The <bean> element has a primary attribute to specify a primary bean.

12.  The primary attribute defaults to true. That means that all autowire candidates will be primary (and thus none will be preferred). So, to use primary, you’ll need to set it to false for all of the beans that are not the primary choice. If you’d rather eliminate some beans from consideration when autowiring, then you can set their autowire-candidate attribute to false.

13.  The @Qualifier annotation is the main way to work with qualifiers. It can be applied alongside @Autowired or @Inject at the point of injection to specify which bean you want to be injected. The parameter given to @Qualifier is the ID of the bean that you want to inject. To be more precise, @Qualifier ("iceCream") refers to the bean that has the String “iceCream” as a qualifier. For lack of having specified any other qualifiers, all beans are given a default qualifier that’s the same as their bean ID.

14.  Instead of relying on the bean ID as the qualifier, you can assign your own qualifier to a bean. All you need to do is place the @Qualifier annotation on the bean declaration. It can be applied alongside @Component and the @Bean annotation.

15.  Java doesn’t allow multiple annotations of the same type to be repeated on the same item. Java 8 allows repeated annotations, as long as the annotation is annotated with @Repeatable. Even so, Spring’s @Qualifier annotation isn’t annotated with @Repeatable.

16.  You can create a custom qualifier annotation by annotating the annotation class with @Qualifier:

@Target({ElementType.CONSTRUCTOR, ElementType.FIELD,ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Cold { }

At the injection point, you can use any combination of custom qualifier annotations necessary to narrow the selection to the one bean that meets all your specifications.

17. You can also attach a qualifier to a bean in XML configuration through qualifier element :

<bean class="com.springinaction.springidol.Guitar">

  <qualifier value="stringed" />

</bean>

18.  Known in the Java Community Process as JSR-330 or more commonly as at inject, this specification brings a common dependency injection model to Java. As of Spring 3, Spring supports the at inject model. Google Guice and Picocontainer also support the JSR-330 model.

19.  The centerpiece of JSR-330 is the @Inject annotation. This annotation is an almost complete drop-in replacement for Spring’s @Autowired annotation.

20.  Just like @Autowired, @Inject can be used to autowire properties, methods, and constructors. Unlike @Autowired, @Inject doesn’t have a required attribute. Therefore, @Inject-annotated dependencies are expected to be fulfilled, failing with an exception if they’re not.

21.  @Inject’s answer to the @Qualifier annotation is the @Named annotation. The key difference between Spring’s @Qualifier and JSR-330’s @Named is one of semantics. Whereas @Qualifier helps narrow the selection of matching beans (using the bean’s ID by default), @Named specifically identifies a selected bean by its ID.

22.  Rather than inject a reference directly, you could ask @Inject to inject a Provider. The Provider interface enables, among other things, lazy injection of bean references and injection of multiple instances of a bean:

private Set<Knife> knives;

@Inject

public KnifeJuggler(Provider<Knife> knifeProvider) {

    knives = new HashSet<Knife>();

    for (int i = 0; i < 5; i++) {

        knives.add(knifeProvider.get());

   }

}

At this point, only the provider is injected. No actual Knife object will be injected until the get() method is called on the provider. Suppose the Knife bean is a prototype, we know that the Set of knives will be given five distinct Knife objects to work it.

23.  JSR-330 has its own @Qualifier annotation in the javax.inject package. Unlike Spring’s @Qualifier, the JSR-330 version isn’t intended to be used on its own. Instead, you’re expected to use it to create custom qualifier annotations, much as we did with Spring’s @Qualifier. In fact, the @Named annotation is just an annotation that’s itself annotated with @Qualifier.

24.  Spring 3.0 introduced @Value, a new wiring annotation that lets you wire primitive values such as int, boolean, and String using annotations. To use it, annotate a property, method, or method parameter with @Value and pass in a String expression to be wired into the property. The String parameter passed into @Value is just an expression—it can evaluate down to any type and thus @Value can be applied to just about any kind of property. SpEL lets you dynamically evaluate complex expressions, at runtime, into values to be wired into bean properties. That makes @Value a powerful wiring option:

@Value("#{systemProperties.myFavoriteSong}")

private String song;

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

26.  The <context:component-scan> element does everything that <context:annotation-config> does, plus it configures Spring to automatically discover beans and declare them for you. By default, <context:component-scan> looks for classes that are annotated with one of a handful of special stereotype annotations:
  • @Component—A general-purpose stereotype annotation indicating that the class is a Spring component
  • @Controller—Indicates that the class defines a Spring MVC controller
  • @Repository—Indicates that the class defines a data repository
  • @Service—Indicates that the class defines a service
  • Any custom annotation that is itself annotated with @Component
By default, the bean’s ID will be generated by camel-casing the class name. You can also specify a bean ID as a parameter to @Component.

27.  By adding <context:include-filter> and/or <context:exclude-filter> subelements to <context:component-scan>, you can tweak component-scanning behavior to your heart’s content:

<context:component-scan

        base-package="com.springinaction.springidol">

      <context:include-filter type="assignable"

          expression="com.springinaction.springidol.Instrument"/>

</context:component-scan>

In this case, we’re asking for all classes that are assignable to Instrument to be automatically registered as Spring beans.

28.  Component scanning can be customized using any of five kinds of filter types:
  • annotation (default): Filters scan classes looking for those annotated with a given annotation at the type level. The annotation to scan for is specified in the expression attribute.
  • assignable : Filters scan classes looking for those that are assignable to the type specified in the expression attribute.
  • aspectj : Filters scan classes looking for those that match the AspectJ type expression specified in the expression attribute.
  • custom : Uses a custom implementation of org.springframework.core.type.TypeFilter, as specified in the expression attribute.
  • regex : Filters scan classes looking for those whose class names match the regular expression specified in the expression attribute.

29.  By default, all Spring beans are singletons. When the container dispenses a bean (either through wiring or as the result of a call to the container’s getBean() method) it’ll always hand out the exact same instance of the bean. You have the option of declaring a scope for a bean. To force Spring to produce a new bean instance each time one is needed, you should declare the bean’s scope attribute to be prototype.

30.  Spring’s bean scopes let you declare the scope under which beans are created without hard-coding the scoping rules in the bean class itself:

Scope
What it does
singleton
Scopes the bean definition to a single instance per Spring container (default).
prototype
Allows a bean to be instantiated any number of times (once per use).
request
Scopes a bean definition to an HTTP request. Only valid when used with a web-capable Spring context (such as with Spring MVC).
session
Scopes a bean definition to an HTTP session. Only valid when used with a web-capable Spring context (such as with Spring MVC).
global-session
Scopes a bean definition to a global HTTP session. Only valid when used in a portlet context.


31.  Spring’s notion of singletons is limited to the scope of the Spring context. Unlike true singletons, which guarantee only a single instance of a class per classloader, Spring’s singleton beans only guarantee a single instance of the bean definition per the application context.

32.  To select an alternative type, you can use the @Scope annotation, either in conjunction with the @Component annotation or with the @Bean annotation. You can specify prototype scope by using the ConfigurableBeanFactory.SCOPE_PROTOTYPE. You could also use @Scope("prototype"), but using the SCOPE_PROTOTYPE constant is safer and less prone to mistakes. In the event that you’re configuring the bean in XML, you can set the scope using the scope attribute of the <bean> element.

33.  To apply session scope:

@Component

@Scope(

    value=WebApplicationContext.SCOPE_SESSION,

    proxyMode=ScopedProxyMode.INTERFACES)

public ShoppingCart cart() { ... }


The proxyMode attribute addresses a problem encountered when injecting a session- or request-scoped bean into a singleton-scoped bean:

@Component

public class StoreService {

  @Autowired

  public void setShoppingCart(ShoppingCart shoppingCart) {

    this.shoppingCart = shoppingCart;

  }

  ...

}

Because StoreService is a singleton bean, it will be created as the Spring application context is loaded. As it’s created, Spring will attempt to inject ShoppingCart into the setShoppingCart() method. But the ShoppingCart bean, being session scoped, doesn’t exist yet. There won’t be an instance of ShoppingCart until a user comes along and a session is created. Moreover, You don’t want Spring to inject just any single instance of ShoppingCart into StoreService. You want StoreService to work with the ShoppingCart instance for whichever session happens to be in play when StoreService needs to work with the shopping cart. Instead of injecting the actual ShoppingCart bean into StoreService, Spring should inject a proxy of the ShoppingCart bean. This proxy will expose the same methods as ShoppingCart so that for all StoreService knows, it is the shopping cart. But when StoreService calls methods on ShoppingCart, the proxy will lazily resolve it and delegate the call to the actual session-scoped ShoppingCart bean:


proxyMode is set to ScopedProxyMode.INTERFACES, indicating that the proxy should implement the ShoppingCart interface and delegate to the implementation bean. This is fine (and the most ideal proxy mode) as long as ShoppingCart is an interface and not a class. But if ShoppingCart is a concrete class, there’s no way Spring can create an interface-based proxy. Instead, it must use CGLib to generate a class-based proxy. So, if the bean type is a concrete class, you must set proxyMode to ScopedProxyMode.TARGET_CLASS to indicate that the proxy should be generated as an extension of the target class.

34.  <aop:scoped-proxy> is the Spring XML configuration’s counterpart to the @Scope annotation’s proxyMode attribute. It tells Spring to create a scoped proxy for the bean. By default, it uses CGLib to create a target class proxy. But you can ask it to generate an interface-based proxy by setting the proxy-target-class attribute to false:

<bean id="cart"

      class="com.myapp.ShoppingCart"

      scope="session">

  <aop:scoped-proxy proxy-target-class="false" />

</bean>

35. Spring offers two ways of evaluating values at runtime:

  • Property placeholders
  • The Spring Expression Language (SpEL)


36.  The following codes show a basic Spring configuration class that uses external properties to wire up a BlankDisc bean:

@Configuration

@PropertySource(“classpath:/com/soundsystem/app.properties”)

public class ExpressiveConfig{

    @Autowired

    Environment env;

    @Bean

    public BlankDisc disc() {

    return new BlankDisc( env.getProperty(“disc.title”) , env.getProperty(“disc.artist”));

  }

}

@PropertySource references a file named app.properties in the classpath. This properties file is loaded into Spring’s Environment, from which it can be retrieved later.

37.  If you use getProperty() methods of Environment class without specifying a default value, you’ll receive null if the property isn’t defined. If you want to require that the property be defined, you can use getRequiredProperty() in which case, if the property is undefined, an IllegalStateException will be thrown.

38.  Environment also offers some methods for checking which profiles are active:

  • String[] getActiveProfiles() —Returns an array of active profile names
  • String[] getDefaultProfiles() —Returns an array of default profile names
  • boolean acceptsProfiles(String... profiles) —Returns true if the environment supports the given profile(s)

39.  In Spring wiring, placeholder values are property names wrapped with ${ ... }:

<bean id="sgtPeppers"

      class="soundsystem.BlankDisc"

      c:_title="${disc.title}"

      c:_artist="${disc.artist}" />

40.  When relying on component-scanning and autowiring to create and initialize your application components, you can use the @Value annotation in much the same way as you might use the @Autowired annotation:

public BlankDisc(

      @Value("${disc.title}") String title,

      @Value("${disc.artist}") String artist) {

  this.title = title;

  this.artist = artist;

}


41.  In order to use placeholder values, you must configure either a PropertyPlaceholderConfigurer bean or a PropertySourcesPlaceholderConfigurer bean. Starting with Spring 3.1, PropertySourcesPlaceholderConfigurer is preferred because it resolves placeholders against the Spring Environment and its set of property sources. If you’d rather use XML configuration, the <context:property-placeholder> element from Spring’s context namespace will give you a PropertySourcesPlaceholderConfigurer bean.

42.  Spring 3 introduced the Spring Expression Language (SpEL), a powerful yet succinct way of wiring values into a bean’s properties or constructor arguments using expressions that are evaluated at runtime. SpEL has a lot of tricks up its sleeves, including

  • The ability to reference beans by their ID
  • Invoking methods and accessing properties on objects
  • Mathematical, relational, and logical operations on values
  • Regular expression matching
  • Collection manipulation


43.  SpEL expressions are framed with #{ ... }, much as property placeholders are framed with ${ ... }. What follows could be mixed with non-SpEL values as well:

<property name="message" value="The value is #{5}"/>

44.  Numbers can even be expressed in scientific notation:

<property name="capacity" value="#{1e4}"/>

45.  Literal String values can be expressed in SpEL with either single or double quote marks:

<property name="name" value="#{'Chuck'}"/>

46.  A couple of other literal values you may use are the Boolean true and false values:

<property name="enabled" value="#{false}"/>

47.  You could use SpEL to wire one bean into another bean’s property by using the bean ID as the SpEL expression:

<property name="instrument" value="#{saxophone}"/>

48.  You can refer to another bean’s property using the Spring Expression Language:

<bean id="carl" class="com.springinaction.springidol.Instrumentalist">
    <property name="song" value="#{kenny.song}" />
</bean>

The first part (the part before the period delimiter) refers to the kenny bean by its ID. The second part refers to the song attribute of the kenny bean. It’s effectively as if you programmatically performed the following Java code:

Instrumentalist carl = new Instrumentalist();
carl.setSong(kenny.getSong());

49.  You could also invoke a method of a bean:

<property name="song" value="#{songSelector.selectSong()}"/>

50.  ?. operator makes sure that the item to its left isn’t null before accessing the thing to its right:

<property name="song" value="#{songSelector.selectSong()?.toUpperCase()}"/>

If selectSong() were to return a null, then SpEL wouldn’t even try to invoke toUpperCase() on it.

51.  The key to working with class-scoped methods and constants in SpEL is to use the T() operator. The result of the T(java.lang.Math) is a Class object that represents java.lang.Math.

52.  You can reference the Math class’s PI constant by:

<property name="multiplier" value="#{T(java.lang.Math).PI}"/>

Similarly, static methods can also be invoked on the result of the T() operator:

<property name="randomNumber" value="#{T(java.lang.Math).random()}"/>

53.  SpEL includes several operators that you can use to manipulate the values of an expression:

Operation type
Operators
Arithmetic
+, -, *, /, %, ^
Relational
<, >, ==, <=, >=, It, gt, eq, le, ge
Logical
and, or, not, !
Conditional
?: (ternary), ?: (Elvis)
Regular expression
matches

54.  Unlike Java, SpEL also offers a power-of operator in the form of the carat:

<property name="area" value="#{T(java.lang.Math).PI * circle.radius ^ 2}"/>

55.  It is consistent with Java in that the + operator can be used to concatenate String values.

56.  The less-than and greater-than symbols pose a problem when using these expressions in Spring’s XML configuration, as they have special meaning in XML. So, when using SpEL in XML, it’s best to use SpEL’s textual alternatives to these operators:

Operation
Symbolic
Textual
Equals
==
eq
Less than
lt
Less than or equals
<=
le
Greater than
gt
Greater than or equals
>=
ge

57.  SpEL’s ternary operator works the same as Java’s ternary operator:

<property name="instrument" 
    value="#{songSelector.selectSong()=='Jingle Bells'?piano:saxophone}"/>

58.  SpEL offers a variant of the ternary operator that simplifies the following expression:

<property name="song" value="#{kenny.song != null ? kenny.song : 'Greensleeves'}"/>

which is Elvis operator:

<property name="song" value="#{kenny.song ?: 'Greensleeves'}"/>

59.  The matches operator attempts to apply a regular expression (given as its right-side argument) against a String value (given as the left-side argument). The result of a matches evaluation is a Boolean value: true if the value matches the regular expression, false otherwise:

<property name="validEmail" 
    value="#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.com'}"/>

60.  The <util:list> element comes from Spring’s util namespace. It effectively creates a bean of type java.util.List that contains all of the values or beans that it contains:

<util:list id="cities">
  <bean class="com.habuma.spel.cities.City"
     p:name="Chicago" p:state="IL" p:population="2853114"/>
  <bean class="com.habuma.spel.cities.City"
     p:name="Atlanta" p:state="GA" p:population="537958"/>
  ...
</util:list>

61.  The most basic thing we could do with a collection is extract a single element out of the list and wire it into a property:

<property name="chosenCity" 
    value="#{cities[T(java.lang.Math).random() * cities.size()]}"/>

62.  The [] operator is also good for retrieving a member of a java.util.Map collection:

<property name="chosenCity" value="#{cities['Dallas']}"/>

63.  To load a properties configuration file into Spring:

<util:properties id="settings" location="classpath:settings.properties"/>

Here the settings bean will be a java.util.Properties that contains all of the entries in the file named settings.properties. With SpEL, you can access a property from <util:properties> in the same way you access a member of a Map:

<property name="accessToken" value="#{settings['twitter.accessToken']}"/>

64.  Spring makes two special selections of properties available to SpEL: systemEnvironment and systemPropertiessystemEnvironment contains all of the environment variables on the machine running the application:

<property name="homePath" value="#{systemEnvironment['HOME']}"/>

Meanwhile, systemProperties contains all of the properties that were set in Java as the application started (typically using the -D argument):

<property name="homePath" value="#{systemProperties['application.home']}"/>

65.  The [] operator can also be used on String values to retrieve a single character by its index within the String.

66.  The selection operator .?[] will create a new collection whose members include only those members from the original collection that meet the criteria expressed between the square braces:

<property name="bigCities" value="#{cities.?[population gt 100000]}"/>

SpEL also offers two other selection operators, .^[] and .$[], for selecting the first and last matching items (respectively) from a collection.

67.  Collection projection involves collecting a particular property from each of the members of a collection into a new collection. SpEL’s projection operator (.![]) can do exactly that:

<property name="cityNames" value="#{cities.![name]}"/>

But projection isn’t limited to projecting a single property:

<property name="cityNames" value="#{cities.![name + ', ' + state]}"/>

Now the cityNames property will be given a list containing values such as “Chicago, IL”, “Atlanta, GA”, and “Dallas, TX”.

2014年11月6日星期四

1. Spring in Action -- Springing into action

1.  Spring was created as an alternative to heavier enterprise Java technologies, especially EJB. Spring offered a lighter and leaner programming model as compared to EJB. It empowered plain old Java objects (POJOs) with powers previously only available using EJB and other enterprise Java specifications. These techniques furnish plain-old Java objects (POJOs) with a declarative programming model reminiscent of EJB, but without all of EJB’s complexity. No longer must you resort to writing an unwieldy EJB component when a simple JavaBean will suffice. Leading the charge for lightweight POJO-based development is the Spring Framework.

2.  Spring is an open source framework, originally created by Rod Johnson and described in his book “Expert One-on-One: J2EE Design and Development”. It was created to address the complexity of enterprise application development, and makes it possible to use plain-vanilla JavaBeans to achieve things that were previously only possible with EJB.

3.  To back up its attack on Java complexity, Spring employs four key strategies:
    1)  Lightweight and minimally invasive development with plain old Java objects (POJOs)
    2)  Loose coupling through dependency injection and interface orientation
    3)  Declarative programming through aspects and common conventions
    4)  Eliminating boilerplate code with aspects and templates

4.  Some frameworks lock you in by forcing you to extend one of their classes or implement one of their interfaces. These heavyweight frameworks forced developers to write classes that were littered with unnecessary code, locked into their framework, and were often difficult to write tests against. Spring avoids (as much as possible) littering your application code with its API. Spring almost never forces you to implement a Spring-specific interface or extend a Spring-specific class. Instead, the classes in a Spring-based application often have no indication that they’re being used by Spring. At worst, a class may be annotated with one of Spring’s annotations, but is otherwise a POJO.

5.  Any nontrivial application is made up of two or more classes that collaborate with each other to perform some business logic. Traditionally, each object is responsible for obtaining its own references to the objects it collaborates with (its dependencies). This can lead to highly coupled and hard-to-test code.

6.  Coupling is a two-headed beast. On one hand, tightly coupled code is difficult to test, difficult to reuse, difficult to understand, and typically exhibits “whack-a-mole” bug behavior (fixing one bug results in the creation of one or more new bugs). On the other hand, a certain amount of coupling is necessary—completely uncoupled code doesn’t do anything. In order to do anything useful, classes need to know about each other somehow. Coupling is necessary, but should be carefully managed. With DI, on the other hand, objects are given their dependencies at creation time by some third party that coordinates each object in the system. Objects aren’t expected to create or obtain their dependencies—dependencies are injected into the objects that need them.

7.  The key benefit of DI is loose coupling. If an object only knows about its dependencies by their interface (not by their implementation or how they’re instantiated), then the dependency can be swapped out with a different implementation without the depending object knowing the difference. One of the most common ways that a dependency will be swapped out is with a mock implementation during testing.

8.  The act of creating associations between application components is commonly referred to as wiring. In Spring, there are many ways to wire components together, but a common approach has always been via XML. If XML configuration doesn’t suit your tastes, you might like to know that Spring also allows you to express configuration using Java.

9. In a Spring application, an application context loads bean definitions and wires them together. The Spring application context is fully responsible for the creation of and wiring of the objects that make up the application. Spring comes with several implementations of its application context, each primarily differing only in how they load their configuration.

10.  ClassPathXmlApplicationContext implementation loads the Spring context from one or more XML files located in the application’s classpath. For Java-based configurations, Spring offers AnnotationConfigApplicationContext.

11.  Although DI makes it possible to tie software components together loosely, aspect-oriented programming (AOP) enables you to capture functionality that’s used throughout your application in reusable components.

12.  System services such as logging, transaction management, and security often find their way into components whose core responsibility is something else. These system services are commonly referred to as cross-cutting concerns because they tend to cut across multiple components in a system. By spreading these concerns across multiple components, you introduce two levels of complexity to your code:
    1)  The code that implements the system-wide concerns is duplicated across multiple components. This means that if you need to change how those concerns work, you’ll need to visit multiple components. Even if you’ve abstracted the concern to a separate module so that the impact to your components is a single method call, that method call is duplicated in multiple places.
    2)  Your components are littered with code that isn’t aligned with their core functionality. A method to add an entry to an address book should only be concerned with how to add the address and not with whether it’s secure or transactional.

AOP makes it possible to modularize these services and then apply them declaratively to the components that they should affect. This results in components that are more cohesive and that focus on their own specific concerns, completely ignorant of any system services that may be involved. At its core, an application consists of modules that implement business functionality. With AOP, you can then cover your core application with layers of system functionality. These layers can be applied declaratively throughout your application in a flexible manner without your core application even knowing they exist. This is a powerful concept, as it keeps the security, transaction, and logging concerns from littering the application’s core business logic.


13.  JDBC’s not alone in the boilerplate code business. Many activities often require similar boilerplate code. JMS, JNDI, and the consumption of REST services often involve a lot of commonly repeated code. Spring seeks to eliminate boilerplate code by encapsulating it in templates.

14.  In a Spring-based application, your application objects will live within the Spring container. The container will create the objects, wire them together, configure them, and manage their complete lifecycle from cradle to grave.

15.  The container is at the core of the Spring Framework. Spring’s container uses dependency injection (DI) to manage the components that make up an application. This includes creating associations between collaborating components.

16.  Spring comes with several container implementations that can be categorized into two distinct types:
  • Bean factories (defined by the org.springframework.beans.factory.BeanFactory interface) are the simplest of containers, providing basic support for DI. 
  • Application contexts (defined by the org.springframework.context.ApplicationContext interface) build on the notion of a bean factory by providing application framework services, such as the ability to resolve textual messages from a properties file and the ability to publish application events to interested event listeners. 
Although it’s possible to work with Spring using either bean factories or application contexts, bean factories are often too low-level for most applications. Therefore, application contexts are preferred over bean factories.

17.  Spring comes with several flavors of application context:
    1)  AnnotationConfigApplicationContext —Loads a Spring application context from one or more Java-based configuration classes
    2)  AnnotationConfigWebApplicationContext —Loads a Spring web application context from one or more Java-based configuration classes
    3)  ClassPathXmlApplicationContext—Loads a context definition from an XML file located in the classpath, treating context definition files as classpath resources.
    4)  FileSystemXmlApplicationContext—Loads a context definition from an XML file in the file system.
    5)  XmlWebApplicationContext—Loads context definitions from an XML file contained within a web application.

18.  With an application context in hand, you can retrieve beans from the Spring container by calling the context’s getBean() method.

19.  A bean factory performs several setup steps before a bean is ready to use:
    1)  Spring instantiates the bean.
    2)  Spring injects values and bean references into the bean’s properties.
    3)  If the bean implements BeanNameAware, Spring passes the bean’s ID to the setBeanName() method.
    4)  If the bean implements BeanFactoryAware, Spring calls the setBeanFactory() method, passing in the bean factory itself.
    5)  If the bean implements ApplicationContextAware, Spring will call the setApplicationContext() method, passing in a reference to the enclosing application context.
    6)  If any of the beans have a method annotated as @PostConstruct, that method will be called first. If any of the beans implement the BeanPostProcessor interface, Spring calls their postProcessBeforeInitialization() method.
    7)  If any beans implement the InitializingBean interface, Spring calls their afterPropertiesSet() method. Similarly, if the bean was declared with an init-method, then the specified initialization method will be called.
    8)  If there are any beans that implement BeanPostProcessor, Spring will call their postProcessAfterInitialization() method.
    9)  At this point, the bean is ready to be used by the application and will remain in the application context until the application context is destroyed.
    10) If any of the beans have a method annotated as @PreDestroy, that method will be called first. If any beans implement the DisposableBean interface, then Spring will call their destroy() methods. Likewise, if any bean was declared with a destroy-method, then the specified method will be called.




20.  As of Spring 4.0, there are 20 distinct modules in the Spring Framework distribution. These modules can be arranged into six categories of functionality:



You don’t have to base your application fully on the Spring Framework. You’re free to choose the modules that suit your application and look to other options when Spring doesn’t fit the bill. Spring even offers integration points with several other frameworks and libraries so that you won’t have to write them yourself.

21.  The centerpiece of the Spring Framework is a container that manages how the beans in a Spring-enabled application are created, configured, and managed. Within this module you’ll find the Spring bean factory, which is the portion of Spring that provides dependency injection. Building upon the bean factory, you’ll find several implementations of Spring’s application context, each of which provides a different way to configure Spring. This module also supplies many enterprise services such as email, JNDI access, EJB integration, and scheduling. All of Spring’s modules are built on top of the core container. You’ll implicitly use these classes when you configure your application.

22. Spring’s JDBC and data access objects (DAO) module abstracts away the boilerplate code so that you can keep your database code clean and simple, and prevents problems that result from a failure to close database resources. This module also builds a layer of meaningful exceptions on top of the error messages given by several database servers. No more trying to decipher cryptic and proprietary SQL error messages. For those who prefer using an object-relational mapping (ORM) tool over straight JDBC, Spring provides the ORM module. Spring’s ORM support builds on the DAO support, providing a convenient way to build DAOs for several ORM solutions. Spring doesn’t attempt to implement its own ORM solution, but does provide hooks into several popular ORM frameworks, including Hibernate, Java Persistence API, Java Data Objects, and iBATIS SQL Maps. Spring’s transaction management supports each of these ORM frameworks as well as JDBC. This module also includes a Spring abstraction over the Java Message Service (JMS) for asynchronous integration with other applications through messaging. In addition, this module uses Spring’s AOP module to provide transaction-management services for objects in a Spring application.

23.  Java has no shortage of MVC frameworks, with Apache Struts, JSF, WebWork, and Tapestry being among the most popular MVC choices. Even though Spring integrates with several popular MVC frameworks, its web and remoting module comes with a capable MVC framework that promotes Spring’s loosely coupled techniques in the web layer of an application.

24.  Spring’s remoting capabilities include Remote Method Invocation (RMI), Hessian, Burlap, JAX-WS, and Spring’s own HTTP invoker. Spring also offers first-class support for exposing and consuming REST APIs.

25.  Spring’s instrumentation module includes support for adding agents to the JVM. Specifically, it provides a weaving agent for Tomcat that transforms class files as they’re loaded by the classloader.

26.  Within the Test module you’ll find a collection of mock object implementations for writing unit tests against code that works with JNDI, servlets, and portlets. For integration-level testing, this module provides support for loading a collection of beans in a Spring application context and working with the beans in that context.

27.  Spring Web Flow builds upon Spring’s core MVC framework to provide support for building conversational, flow-based web applications that guide users toward a goal (think wizards or shopping carts). And you can learn more about Spring Web Flow from its home page at http://www.springsource.org/webflow.

28.  Spring Framework provides for declaratively publishing Spring beans as web services, those services are based on an arguably architecturally inferior contract-last model. The contract for the service is determined from the bean’s interface. Spring Web Services offers a contract-first web services model where service implementations are written to satisfy the service contract. You can read more about it from its home page at http://static.springsource.org/spring-ws/sites/2.0.

29.  Implemented using Spring AOP, Spring Security offers a declarative security mechanism for Spring-based applications. For further exploration, Spring Security’s home page is at http://static.springsource.org/spring-security/site.

30.  Many enterprise applications must interact with other enterprise applications. Spring Integration offers implementations of several common integration patterns in Spring’s declarative style. If you want more information on Spring Integration, have a look at “Spring Integration in Action” or you can visit the Spring Integration home page at http://www.springsource.org/spring-integration.

31.  If you’re going to be developing a batch application, you can leverage Spring’s robust, POJO-oriented development model to do it using Spring Batch. For more information, you can read “Spring Batch in Action”. You can also learn about Spring Batch from its home page at http://static.springsource.org/spring-batch.

32.  Whether you’re using a document database like MongoDB, a graph database such as Neo4j, or even a traditional relational database, Spring Data offers a simplified programming model for persistence. This includes, for many database types, an automatic repository mechanism that creates repository implementations for you.

33.  Spring Social is a social networking extension to Spring. It helps you connect your Spring application with REST APIs, including many that may not have any social purpose to them. You can find out more about it at http://www.springsource.org/spring-social. The following two links can help you connect with Facebook or Twitter :
https://spring.io/guides/gs/accessing-facebook/ and https://spring.io/guides/gs/accessing-twitter/.

34.  Spring Mobile is a new extension to Spring to support development of mobile web applications. Related to Spring Mobile is the Spring Android project, which aims to bring some of the simplicity afforded by the Spring Framework to development of native applications for Android-based devices. You can learn more about them at http://www.springsource.org/spring-mobile and http://www.springsource.org/spring-android.

35.  Spring Dynamic Modules (Spring-DM) blends Spring’s declarative dependency injection with OSGi’s dynamic modularity. Using Spring-DM, you can build applications that are composed of several distinct, highly cohesive, loosely coupled modules that publish and consume services declaratively within the OSGi framework. The Spring-DM model for declarative OSGi services has been formalized into the OSGi specification itself as the OSGi Blueprint Container. In addition, SpringSource has transitioned Spring-DM to the Eclipse project as a part of the Gemini family of OSGi projects and is now known as Gemini Blueprint.

36.  Spring LDAP brings Spring-style template-based access to LDAP, eliminating the boilerplate code that’s commonly involved in LDAP operations. More information on Spring LDAP can be found at http://www.springsource.org/ldap.

37.  Spring Rich Client a rich application toolkit that brings the power of Spring to Swing.

38.  The Spring-Flex integration package enables Flex and AIR applications to communicate with server-side Spring beans using BlazeDS. It also includes an addon for Spring Roo to enable rapid application development of Flex applications. You may begin your exploration of Spring Flex at http://www.springsource.org/spring-flex. You may also want to check out Spring ActionScript at http://www.springactionscript.org, which offers many benefits of the Spring Framework in ActionScript.

39.  Spring Roo provides an interactive tooling environment that enables rapid development of Spring applications, pulling together the best practices that have been identified over the past few years. More information about Spring Roo can be found at http://www.springsource.org/roo.

40.  There’s also a community-driven collection of Spring extensions at http://www.springsource.org/extensions.

41.  The significance of Spring 2.5 was that it marked Spring’s embrace of annotation-driven development. Prior to Spring 2.5, XML-based configuration was the norm. With the 3.0 release, Spring one-upped itself with the continuation of the annotation-driven theme and several new features.