Spring notes

Spring Bean Life Cycle Callback Methods

life cycle A bean life cycle includes the following steps.

  1. Within IoC container, a spring bean is created using class constructor.
  2. Now the dependency injection is performed using setter method.
  3. Once the dependency injection is completed, BeanNameAware.setBeanName() is called. It sets the name of bean in the bean factory that created this bean.
  4. Now < code>BeanClassLoaderAware.setBeanClassLoader() is called that supplies the bean class loader to a bean instance.
  5. Now < code>BeanFactoryAware.setBeanFactory() is called that provides the owning factory to a bean instance.
  6. Now the IoC container calls BeanPostProcessor.postProcessBeforeInitialization on the bean. Using this method a wrapper can be applied on original bean.
  7. Now the method annotated with @PostConstruct is called.
  8. After @PostConstruct, the method InitializingBean.afterPropertiesSet() is called.
  9. Now the method specified by init-method attribute of bean in XML configuration is called.
  10. And then BeanPostProcessor.postProcessAfterInitialization() is called. It can also be used to apply wrapper on original bean.
  11. Now the bean instance is ready to be used. Perform the task using the bean.
  12. Now when the ApplicationContext shuts down such as by using registerShutdownHook() then the method annotated with @PreDestroy is called.
  13. After that DisposableBean.destroy() method is called on the bean.
  14. Now the method specified by destroy-method attribute of bean in XML configuration is called.
  15. Before garbage collection, finalize() method of Object is called.

Spring framework provides following 4 ways for controlling life cycle events of bean:

  • InitializingBean and DisposableBean callback interfaces
  • Other Aware interfaces for specific behavior
  • Custom init() and destroy() methods in bean configuration file
  • @PostConstruct and @PreDestroy annotations

InitializingBean

The org.springframework.beans.factory.InitializingBean interface specifies a single method −

void afterPropertiesSet() throws Exception;

Destruction callbacks

The org.springframework.beans.factory.DisposableBean interface specifies a single method −

void destroy() throws Exception;

Custom init() and destroy() methods in bean configuration file

The default init and destroy methods in bean configuration file can be defined in two ways:

Bean local definition applicable to a single bean Global definition applicable to all beans defined in beans context

Local definition is given as below.

<beans>

	<bean id="demoBean" class="com.howtodoinjava.task.DemoBean" 
					init-method="customInit" 
					destroy-method="customDestroy"></bean>

</beans>

Where as global definition is given as below. These methods will be invoked for all bean definitions given under tag. They are useful when you have a pattern of defining common method names such as init() and destroy() for all your beans consistently. This feature helps you in not mentioning the init and destroy method names for all beans independently.


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

    	<bean id="demoBean" class="com.howtodoinjava.task.DemoBean"></bean>

</beans>

@PostConstruct and @PreDestroy annotations

Spring 2.5 onwards, you can use annotations also for specifying life cycle methods using @PostConstruct and @PreDestroy annotations.

@PostConstruct annotated method will be invoked after the bean has been constructed using default constructor and just before it’s instance is returned to requesting object. @PreDestroy annotated method is called just before the bean is about be destroyed inside bean container. A sample implementation will look like this:

package com.howtodoinjava.task;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class DemoBean 
{
	@PostConstruct
	public void customInit() 
	{
		System.out.println("Method customInit() invoked...");
	}
	
	@PreDestroy
	public void customDestroy() 
	{
		System.out.println("Method customDestroy() invoked...");
	}
}

Spring Notes

AOP

 execution(* concert.Performance.perform())  and !bean('woodstock')
 @Aspect
public class Audience {
  @Before("execution(** concert.Performance.perform(..))")
  public void silenceCellPhones() {
Before performance
  • Fortunately, there’s a way: the @Pointcut annotation defines a reusable pointcut within an @AspectJ aspect. The next listing shows the Audience aspect, updated to use @Pointcut.

  • Reuse pointuct
    @Aspect
    public class Audience {
    @Pointcut("execution(** concert.Performance.perform(..))")
    public void performance() {} //Define named pointcut
    
      @Before("performance()")
    public void silenceCellPhones() {
      System.out.println("Silencing cell phones");
    @Before("performance()")
    public void takeSeats() {
      System.out.println("Taking seats");
    }
    
  • The body of the performance() method is irrelevant and, in fact, should be empty. The method itself is just a marker, giving the @Pointcut annotation something to attach itself to.
import org.aspectj.lang.ProceedingJoinPoint; public class Audience {
public void watchPerformance(ProceedingJoinPoint jp) { try {

System.out.println("Silencing cell phones"); System.out.println("Taking seats");
<aop:config>
<aop:aspect ref="audience">
<aop:pointcut
id="performance"
expression="execution(** concert.Performance.perform(..))" />
<aop:around     Declare around advice
        
pointcut-ref="performance" method="watchPerformance"/> </aop:aspect>
</aop:config>   
  • to use AspectJ’s @DeclareParents annota¬tion to magically introduce a new method into an advised bean. But AOP introduc¬tions aren’t exclusive to AspectJ. Using the element from Spring’s aop namespace, you can do similar magic in XML.

  • Listing 1.7 Spring offers Java-based configuration as an alternative to XML.
    package com.springinaction.knights.config;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import com.springinaction.knights.BraveKnight; import com.springinaction.knights.Knight; import com.springinaction.knights.Quest; import com.springinaction.knights.SlayDragonQuest;
    @Configuration
    public class KnightConfig {
    @Bean
    public Knight knight() {
    return new BraveKnight(quest());
    }
    @Bean
    public Quest quest() {
    return new SlayDragonQuest(System.out);
    }
    }
    
  • 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 imple¬mentations of its application context, each primarily differing only in how it loads its configuration.

  • When the beans in knights.xml are declared in an XML file, an appropriate choice for application context might be ClassPathXmlApplicationContext.1

  • These system services are commonly referred to as cross-cut¬ting concerns because they tend to cut across multiple components in a system.

  • Your components are littered with code that isn’t aligned with their core func¬tionality. A method that adds an entry to an address book should only be con¬cerned with how to add the address and not with whether it’s secure or transactional.

  • Spring seeks to eliminate boilerplate code by encapsulating it in templates. Spring’s JdbcTemplate makes it possible to perform database operations without all the ceremony required by traditional JDBC. The container is at the core of the Spring Framework. Spring’s container uses DI to manage the components that make up an application. This includes creating associa¬tions between collaborating components. As such, these objects are cleaner and easier to understand, they support reuse, and they’re easy to unit test.
  • There’s no single Spring container. Spring comes with several container imple¬mentations 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 applica¬tion contexts, bean factories are often too low-level for most applications. Therefore, application contexts are preferred over bean factories. We’ll focus on working with application contexts and not spend any more time talking about bean factories.

  • As you can see, a bean factory performs several setup steps before a bean is ready to use. Let’s break down figure 1.5 in more detail: 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 set-BeanName() 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 calls the set-ApplicationContext() method, passing in a reference to the enclosing appli¬cation context. 6 If the bean implements the BeanPostProcessor interface, Spring calls its post- ProcessBeforeInitialization() method. 7 If the bean implements the InitializingBean interface, Spring calls its after- PropertiesSet() method. Similarly, if the bean was declared with an init-method, then the specified initialization method is called. 8 If the bean implements BeanPostProcessor, Spring calls its postProcess-AfterInitialization() method. 9 At this point, the bean is ready to be used by the application and remains in the application context until the application context is destroyed. 10 If the bean implements the DisposableBean interface, Spring calls its destroy() method. Likewise, if the bean was declared with a destroy-method, the specified method is called.

  • Spring Boot heavily employs automatic configuration techniques that can elimi¬nate most (and in many cases, all) Spring configuration. It also provides several starter projects to help reduce the size of your Spring project build files, whether you’re using Maven or Gradle.

· Spring began to support Servlet 3.0, including the ability to declare servlets and filters in Java-based configuration instead of web.xml. · You should now have a good idea of what Spring brings to the table. Spring aims to make enterprise Java development easier and to promote loosely coupled code. Vital to this are dependency injection and aspect-oriented programming. When it comes to expressing a bean wiring specification, Spring is incredibly flexible, offering three primary wiring mechanisms: · Explicit configuration in XML · Explicit configuration in Java · Implicit bean discovery and automatic wiring · in many cases, the choice is largely a matter of personal taste, and you’re welcome to choose the approach that feels best for you. Spring attacks automatic wiring from two angles: · Component scanning—Spring automatically discovers beans to be created in the application context. · Autowiring—Spring automatically satisfies bean dependencies. Working together, component scanning and autowiring are a powerful force and can help keep explicit configuration to a minimum.

package soundsystem;
public interface CompactDisc { void play();
}
  • The specifics of the CompactDisc interface aren’t important. What is important is that you’ve defined it as an interface. As an interface, it defines the contract through which a CD player can operate on the CD. And it keeps the coupling between any CD player implementation and the CD itself to a minimum.
package soundsystem;
import org.springframework.stereotype.Component;
@Component
public class SgtPeppers implements CompactDisc {
private String title = "Sgt. Pepper's Lonely Hearts Club Band"; private String artist = "The Beatles";
public void play() {
System.out.println("Playing " + title + " by " + artist);
}
}
  • that SgtPeppers is annotated with @Component. This simple annotation identifies this class as a component class and serves as a clue to Spring that a bean should be created for the class. Component scanning isn’t turned on by default, however. You’ll still need to write an explicit configuration to tell Spring to seek out classes annotated with @Component and to create beans from them. The configuration class in the following listing shows the minimal configuration to make this possible.
package soundsystem;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;
@Configuration @ComponentScan
public class CDPlayerConfig {
}
  • you can explicitly identify any state as the starting state by setting the start-state attri¬bute in the element: ```xml <?xml version="1.0" encoding="UTF-8"?>
...

Welcome to Spizza!!!


</html>


- The _eventId_ portion of the button’s name is a clue to Spring Web Flow that what follows is an event that should be fired. When the form is submitted by clicking that button, a phoneEntered event is fired, triggering a transition to lookupCustomer.

    Flow execution key
```xml
<p>The address is outside of our delivery area. You may
still place the order, but you will need to pick it up
yourself.</p>
<![CDATA[
<a href="${flowExecutionUrl}&_eventId=accept">
Continue, I'll pick up the order</a> |
<a href="${flowExecutionUrl}&_eventId=cancel">Never mind</a>
11>
  • Note that the customerReady end state includes an element. This ele-ment is a flow’s equivalent of Java’s return statement. It passes back some data from a subflow to the calling flow. In this case, returns the customer flow variable so that the identifyCustomer subflow state in the pizza flow can assign it to the order. you use the element to pass the Order in to the flow. Here you’re using it to accept that Order object. If you think of this subflow as being analo¬gous to a method in Java, the element used here is effectively defining the subflow’s signature. This flow requires a single parameter called order.

  • States, transitions, and entire flows can be secured in Spring Web Flow by using the element as a child of those elements. For example, to secure access to a view state, you might use like this:

As configured here, access to the view state will be restricted to only users who are granted ROLE_ADMIN access (per the attributes attribute). The attributes attribute takes a comma-separated list of authorities that the user must have to gain access to the state, transition, or flow.

@RequestBody converter

Spring uses HttpMessageConverters to render @ResponseBody (or responses from @RestController).

If a bean you add is of a type that would have been included by default anyway (such as MappingJackson2HttpMessageConverter for JSON conversions), it replaces the default value. A convenience bean of type HttpMessageConverters is provided and is always available if you use the default MVC configuration. It has some useful methods to access the default and user-enhanced message converters (For example, it can be useful if you want to manually inject them into a custom RestTemplate).

On the contrary, REST has little to do with RPC. Whereas RPC is service oriented and focused on actions and verbs, REST is resource oriented, emphasizing the things and nouns that comprise an application.

Put more succinctly, REST is about transferring the state of resources—in a representational form that is most appropriate for the client or server—from a server to a client (or vice versa).

It’s a small start, but you’ll build on this controller throughout this chapter as you learn the ins and outs of Spring’s REST programming model.

Representation is an important facet of REST. It’s how a client and a server communicate about a resource. Any given resource can be represented in virtually any form. If the consumer of the resource prefers JSON, then the resource can be

Meanwhile, a human user viewing the resource in a web browser will likely prefer seeing it in HTML (or possibly PDF, Excel, or some other human-readable form). The resource doesn’t change—only how it’s represented.

Understanding how ContentNegotiatingViewResolverworks involves getting to know the content-negotiation two-step:

  1. Determine the requested media type(s).

  2. Find the best view for the requested media type(s).

The @ResponseBodyannotation tells Spring that you want to send the returned object as a resource to the client, converted into some representational form that the client can accept. More specifically, DispatcherServletconsiders the request’s Acceptheader and looks for a message converter that can give the client the representation it wants.

Just as @ResponseBody tells Spring to employ a message converter when sending data to a client, the @RequestBody tells Spring to find a message converter to convert a resource representation coming from a client into an object. For example, suppose that you need a way for a client to submit a new Spittle to be saved. You can write the controller method to handle such a request like this:

The body of the POST request is expected to carry a resource representation for a Spittle. Because the Spittleparameter is annotated with @RequestBody, Spring will look at the Content-Type header of the request and try to find a message converter that can convert the request body into a Spittle.

For example, if the client sent the Spittle data in a JSON representation, then the Content-Type header might be set to application/json. In that case, DispatcherServletwill look for a message converter that can convert JSON into Java objects. If the Jackson 2 library is on the classpath, then MappingJackson2Http-MessageConverterwill get the job and will convert the JSON representation into a Spittle that’s passed into the saveSpittle()method. The method is also annotated with @ResponseBodyso that the returned Spittle will be converted into a resource representation to be returned to the client.

Notice that the @RequestMappinghas a consumesattribute set to application/json. The consumesattribute works much like the producesattribute, only with regard to the request’s Content-Typeheader. This tells Spring that this method will only handle POSTrequests to /spittles if the request’s Content-Typeheader is application/json. Otherwise, it will be up to some other method (if a suitable one exists) to handle the request.

The key thing to notice in listing 16.3is what’s not in the code. Neither of the handler methods are annotated with @ResponseBody. But because the controller is annotated with @RestController, the objects returned from those methods will still go through message conversion to produce a resource representation for the client.The @ExceptionHandler annotation can be applied to controller methods to handle specific exceptions. Here, it’s indicating that if a SpittleNotFoundException is thrown from any of the handler methods in the same controller, the spittleNotFound() method should be called to handle that exception.

@ExceptionHandler(SpittleNotFoundException.class)@ResponseStatus(HttpStatus.NOT_FOUND)public @ResponseBody Error spittleNotFound(SpittleNotFoundException e) { long spittleId = e.getSpittleId(); return new Error(4, “Spittle [” + spittleId + “] not found”);}

@ExceptionHandler(SpittleNotFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public @ResponseBody Error spittleNotFound(SpittleNotFoundException e) { long spittleId = e.getSpittleId(); return new Error(4, “Spittle [” + spittleId + “] not found”); }

Because spittleNotFound() always returns an Error, the only reason to keep Response-Entity around is so you can set the status code. But by annotating spittleNotFound() with @ResponseStatus(HttpStatus.NOT_FOUND), you can achieve the same effect and get rid of ResponseEntity.

Again, if the controller class is annotated with @RestController, you can remove the @ResponseBody annotation and clean up the code a little more:

@ExceptionHandler(SpittleNotFoundException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public Error spittleNotFound(SpittleNotFoundException e) { long spittleId = e.getSpittleId(); return new Error(4, “Spittle [” + spittleId + “] not found”); }

public Spittle fetchSpittle(long id) { RestTemplate rest = new RestTemplate(); ResponseEntity response = rest.getForEntity(

 "http://localhost:8080/spittr-api/spittles/{id}",
 Spittle.class, id);  if(response.getStatusCode() == HttpStatus.NOT_MODIFIED) {    throw new NotModifiedException();  }  return response.getBody(); }

Just like the getForEntity() method, postForEntity() returns a Response-Entity object. From that object, you can call getBody() to get the resource object (a Spitter in this case). And the getHeaders() method gives you an HttpHeaders from which you can access the various HTTP headers returned in the response. Here, you’re calling getLocation() to retrieve the Location header as a java.net.URI.

By passing in HttpMethod.GET as the HTTP verb, you’re asking exchange() to send a GET request. The third argument is for sending a resource on the request, but because this is a GET request, it can be null. The next argument indicates that you want the response converted into a Spitter object. An

Used this way, the exchange() method is virtually identical to the previously used getForEntity(). But unlike getForEntity()—or getForObject()—exchange() lets you set headers on the request sent. Instead of passing null to exchange(), you pass in an HttpEntity created with the request headers you want.

RESTful architecture uses web standards to integrate applications, keeping the interactions simple and natural. Resources in a system are identified by URLs, manipulated with HTTP methods, and represented in one or more forms suitable for the client.

Spring’s philosophy of avoiding checked exceptions, you don’t want to let the JMSException escape this method, so you’ll catch it instead.

In the catch block, you can use the convertJmsAccessException() method from Spring’s JmsUtils class to convert the checked JMSException to an unchecked JmsException. This is effectively the same thing JmsTemplate does for you in other cases.

A message-listener container is a special bean that watches a JMS destination, waiting for a message to arrive. Once a message arrives, the bean retrieves the message and passes it on to any message listeners that are interested.

JmsInvokerServiceExporter is much like those other service exporters. In fact, note that there’s some symmetry in the names of JmsInvokerServiceExporter and HttpInvokerServiceExporter. If HttpInvokerServiceExporter exports services that communicate over HTTP, then JmsInvokerServiceExporter must export services that converse over JMS.

As it turns out, AMQP offers several advantages over JMS. First, AMQP defines a wire-level protocol for messaging, whereas JMS defines an API specification. JMS’s API specification ensures that all JMS implementations can be used through a common API but doesn’t mandate that messages sent by one JMS implementation can be consumed by a different JMS implementation. AMQP’s wire-level protocol, on the other hand, specifies the format that messages will take when en route between the producer and consumer. Consequently, AMQP is more interoperable than JMS—not only across different AMQP implementations, but also across languages and platforms.

In JMS, there are just three primary participants: the message producer, the message consumer(s), and a channel (either a queue or a topic) to carry the message between producers and consumers. These essentials of the JMS messaging model are illustrated in figures 17.3 and 17.4.

In JMS, the channel helps to decouple the producer from the consumer, but both are still coupled to the channel. A producer publishes messages to a specific queue or topic, and the consumer receives those message from a specific queue or topic. The channel has the double duty of relaying messages and determining how those messages will be routed; queues route using a point-to-point algorithm, and topics route in publish/subscribe fashion.

In contrast, AMQP producers don’t publish directly to a queue. Instead, AMQP introduces a new level of indirection between the producer and any queues that will carry the message: the exchange. This relationship is illustrated in figure 17.8.

Figure 17.8. In AMQP, message producers are decoupled from message queues by an exchange that handles message routing.

For example, to have a message routed to multiple queues with no regard for the routing key, you can configure a fanout exchange and several queues like this:

As its name implies, the RabbitMQ connection factory is used to create connections with RabbitMQ. If you want to send messages via RabbitMQ, you could inject the connectionFactory bean into your AlertServiceImpl class, use it to create a Connection, use that Connection to create a Channel, and use that Channel to publish a message to an exchange. Yep, you could do that. you can configure different defaults using the exchange and routing-key attributes on the