Monday 6 January 2014

Spring Auto scanning components

Normally you declare all the beans or components in XML bean configuration file, so that Spring container can detect and register your beans or components.

Actually, Spring provides the capability of automatically detecting 'stereotyped' classes and registering corresponding BeanDefinitions with the ApplicationContext.

To autodetect these classes and register the corresponding beans requires the inclusion of the following element in XML where 'basePackage' would be a common parent package for the two classes (or alternatively a comma-separated list could be specified that included the parent package of each class).


example 

<context:component-scan base-package="com.mahesh.example" />


By default, looks for classes that are annotated with one of the following sterotype 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 (=DAO)
  • @Service - Indicates that the class defines a service

 @Component, @Service and @Controller. @Component serves as a generic stereotype for any Spring-managed component; whereas, @Repository, @Service, and @Controller serve as specializations of @Component for more specific use cases (e.g., in the persistence, service, and presentation layers, respectively). What this means is that you can annotate your component classes with @Component, but by annotating them with @Repository, @Service, or @Controller instead, your classes are more properly suited for processing by tools or associating with aspects. For example, these stereotype annotations make ideal targets for pointcuts. Of course, it is also possible that @Repository, @Service, and @Controller may carry additional semantics in future releases of the Spring Framework. Thus, if you are making a decision between using @Component or @Service for your service layer, @Service is clearly the better choice. Similarly, as stated above, @Repository is already supported as a marker for automatic exception translation in your persistence layer.

Example


Here is the content for Customer.java

package com.mahesh.training.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("customerBean")
public class Customer {

    @Autowired
    private Person person;
  
    @Value("#{personBean.getName()}")
    private String personName;

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public String getPersonName() {
        return personName;
    }

    public void setPersonName(String personName) {
        this.personName = personName;
    }
  
    @Override
    public String toString() {
        return "Customer [person=" + person + ", personName=" + personName + "]";
    }
  
}



Here is the content for Person.java

package com.mahesh.training.spring;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component("personBean")
public class Person1 {

    @Value("#{'mahesh'.toUpperCase()}")
    String name;
   
    @Value("#{'address'}")
    String address;
   
    @Value("#{'30'}")
    int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
   
    @Override
    public String toString() {
        return "Person [address=" + address + ", age=" + age + ", name=" + name + "]";
    }

}

Here is the content for Spring Configuration file SpringBeans-AUTO-SCAN.xml.

<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-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="com.mahesh.training.spring">
        <context:include-filter type="regex" expression="com.mahesh.training.spring.*Customer.*" />
    </context:component-scan>

</beans>

Using filters to customize scanning

Filter Types


Filter TypeExample ExpressionDescription
annotationorg.example.SomeAnnotationAn annotation to be present at the type level in target components.
assignableorg.example.SomeClassA class (or interface) that the target components are assignable to (extend/implement).
aspectjorg.example..*Service+An AspectJ type expression to be matched by the target components.
regexorg\.example\.Default.*A regex expression to be matched by the target components' class names.
customorg.example.MyCustomTypeFilterA custom implementation of the org.springframework.core.type.TypeFilter interface.

Here is the App.java

package clientpack;

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

import com.mahesh.training.spring.Customer;

public class App {

    /**
     * @param args
     */
    public static void main(String[] args) {
        ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
                "SpringBeans-AUTO-SCAN.xml");
       
        Customer cust = (Customer4) context.getBean("customerBean");
        System.out.println(cust);
       
    }
}

OutPut:
Customer [person=Person [address=address, age=30, name=MAHESH], personName=MAHESH]

No comments:

Post a Comment