Annotations for life cycle

We have had enough discussion about the life cycle of a bean, and what are the different ways to achieve it through XML configurations. However, we haven't discussed annotation-based configuration. From Spring version 2.5 onward, the framework added support for life cycle management by @PostConstruct and @PreDestroy, which gives an alternative to the InitializingBean and Disposable interfaces respectively.

@PostConstruct

The method that is annotated with @PostConstruct gets called after the bean, which is instantiated using the default constructor by the container. This method is called just before the instance is returned.

@PreDestroyed

The method annotated with @PreDestroy will be invoked just before the bean gets destroyed, which allows developers to persist it before the object is destroyed.

Let's follow these steps, and use it to understand the bean life cycle:

  1. In the Ch02_Bean_Life_Cycle java project, which we have already used while discussing bean life, add the Car_JSR class in the com.ch02.beans package.
  1. Add an init_car method for the initialization of Car, and annotate it with @PostConstruct, as shown in the following piece of code:
@PostConstruct 
public void init_car() 
{ 
  System.out.println("initializing the car"); 
  price=(long)(price+(price*0.10)); 
} 
  1. Add to the class a method, which has the code for destruction of a car, which is nothing but resource release, as shown in the following lines of code:
@PreDestroy 
public void destroy_car() 
{ 
  System.out.println("demolishing the car"); 
} 
  1. Add beans_new.xml to configure the bean, and don't forget the rule of using annotations in the application. The XML will look as follows:
<context:annotation-config/> 
  <bean id="car"class="com.ch02.beans.Car" 
      scope="prototype"> 
  <property name="chesis_number"value="eng2012"/> 
  <property name="color"value="baker's chocolate"/> 
  <property name="fuel_type"value="petrol"/> 
  <property name="average"value="12.50"/> 
  <property name="price"value="643800"/> 
</bean> 

We can even use the same beans_lifecycle.xml by adding context namespace to it.

  1. Add a main method in TestCar, as shown in the following piece of code:
public static void main(String[] args) { 
  // TODO Auto-generated method stub 
  ApplicationContext context=new 
    ClassPathXmlApplicationContext("beans_new.xml"); 
  // first request to get the car instance 
  Car_JSRcar_one=(Car_JSR)context.getBean("car"); 
  car_one.show(); 
} 
If you are using beans_life cycle.xml then load it instead of loading beans_new.xml by container. 
  1. On execution of the code, we will get the output of life cycle methods. Part of the output for JSR_Car is shown in the following screenshot:
  1. As the destroy method will get invoked after context got switched off, the output will not be shown on the console. We can use the following code to elegantly shut down the container:
((AbstractApplicationContext)context).registerShutdownHook(); 

@Named

The @Named annotation is used instead of @Component, which is applied to the class level. It doesn't provide a composable model, but its scanning is the same way as that of @Component. Let's take a look at a sample code to understand how to apply @Named annotation to the class:

@Named 
public class Customer { 
  private String cust_name; 
  private int cust_id; 
  private Address cust_address; 
  //default and parameterize constructor 
  //getters and setters 
} 

@Inject

The @Inject annotation is used to autowire the dependencies in the same way as we do for @Autowired. However, it won't have an attribute required to specify that the dependency is optional. The following code shows the implementation:

@Named 
public class Customer { 
  private String cust_name; 
  private int cust_id; 
 
  @Inject 
  private Address cust_address; 
  // default and parameterized constructor 
  // getters and setters 
} 

@Configuration

The class level @Configuration annotation is used to indicate the class as a source of the bean definition the same way as we do in an XML file within the<beans></beans> tags.

@Configuration 
public class MyConfiguration { 
  // bean configuration will come here 
} 

The Spring annotations @Component and @Repository need registration with the framework. In XML, scanning of these annotations is enabled by providing <context:component-scan> with an attribute-based package. The @Component-Scan annotation is an alternative to enable the scanning of Spring stereotype annotations. The syntax is shown as follows:

@Component-Scan(basePackage=name_of_base_package) 
@Bean 

The @Bean annotation is used with @Configuration to declare the bean definition as we usually do in the<bean></bean> tag in XML. It's applicable to the method that has the bean definition. The code can be as follows:

@Configuration 
public class MyConfiguration { 
    @Bean 
    public Customer myCustomer() 
    { 
       Customer customer=new Customer(); 
       customer.setCust_name("name by config"); 
       return customer; 
   } 
} 

To define a bean returned from myCustomer(), you can also have a customized bean id, which can be given by @Bean(name="myCustomer").

The XML is replaced by the annotation-based configuration. The AnnotationConfigApplicationContext class helps in loading the configuration in the same way we do it by ClasspathXmlApplicationContext. The test class can be written as follows:

public static void main(String[] args) { 
  ApplicationContext context=new 
  AnnotationConfigApplicationContext(MyConfiguration.class); 
  Customer customer=(Customer)context.getBean("myCustomer"); 
  System.out.println(customer.getCust_id()+"	"+ 
  customer.getCust_name()); 
} 

You can refer to the complete code from Ch02_Demo_JSR_Annot.

XML provides a centralized way to write bean configurations. As the dependencies are kept out of the source code, any changes in them will not affect the source code. Also, in XML configuration, the source code doesn't need to be recompiled. However, an annotation-based configuration is directly a part of the source code, and is scattered throughout the application. It becomes decentralized, which ultimately becomes difficult to control.
Annotation-based injected values will be overridden by the XML injection, as annotation-based injections take place before the XML injection.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.210.91