Monday, April 11, 2016

Spring Annotation

Looking at this good doc, which explains really clear:

http://howtodoinjava.com/spring/spring-core/how-to-use-spring-component-repository-service-and-controller-annotations/
In real life, you will face very rare situations where you will need to use @Component annotation. Most of the time, you will using @Repository@Service and @Controller annotations. @Component should be used when your class does not fall into either of three categories i.e. controller, manager and dao.
If you want to define name of the bean with which they will be registered in DI container, you can pass the name in annotation itself e.g. @Service (“employeeManager”).


Enable Config Annotation in applicationContext.xml
 <!-- Enable Annotation -->
 <context:annotation-config/>
or
 <!-- Enable Annotation in base-package -->
 <context:component-scan base-package="com.gvace.spring.annotation"/>

<context:component-scan> is to help you automatically find classes and register them as beans in base-package, and its all sub packages.

<context:component-scan> annotations:
  • @Component: Indicate the class is a Spring Component
    @Component: register the bean id: camel-casing the class name Class Cat => id "cat"
    @Component("cat1") register the bean with specified id
  • @Controller: Indicate the class defines a Spring MVC controller 
  • @Repository: Indicate the class defines a data repository
  • @Service: Indicates that the class defines a service
Filter types in <context:component-scan>
  1. annotation: class with annotation
  2. assignable: class that assignable to target a Class
  3. aspectj: match aspectj type
  4. custom: uses a custom implementation of org.springframework.core.type.TypeFilter
  5. regex: regular expression
Example:
Assume you have a target Class and a custom Annotation: TargetClass and @SkipIt
<context:component-scan base-package="com.gvace.spring">
 <context:include-filter type="assignable" expression="com.gvace.model.TargetClass">
 <context:exclude-filter type="annotation" expression="com.gvace.spring.annotation.SkipIt">
</context:component-scan>


@Configuration and @Bean
<context:component-scan> also scans @Configuration, looking for class which is Configuration for beans
With @Configuration and @Bean, we can move all bean declarations from XML to Java Class!
To use @Configuration and @Bean, just like a class and its function.

@Configuration
public class MyBeansConfig{
 @Bean
 public Cat myCat1(){
  return new Cat();
 }
 @Bean
 public Cat myCat2(){
  Cat cat2 = new Cat();
  cat2.setName("miamia");
  return cat2;
 }
 @Bean
 public Cat myCat1Copy(){
  return myCat1();
  //This is a ref, and Spring is clever enough to intercept function myCat1()
  //And return the existed bean from context, instead of creating a new instance 
 }
}

When using reference, Spring is clever enough to intercept the ref function. And return the existed bean from context, instead of creating a new instance



Property Injection
@Autowired and @Qualifier, is a pair provided by Spring
@Inject and @Named, is a pair provided by Java community, which is suggested to use


@Autowired(required=false)

Doesn't inject if did not find a bean to wire

@Autowired(required=false)
private Cat myCat;

or

@Autowired(required=false)
public void setMyCat(Cat myCat){
 this.myCat = myCat;
}


@Qualifier
specify a bean by bean id/qualifier

Define a bean with qualifier:
<bean class="com.gvace.Cat">
    <qualifier value="miamia"/>
</bean>

or define by Annotation


@Qualifier("miamia")
class Cat {}


Use Qualifier to narrow down selection
@Autowired
@Qualifier("miamia")
private Cat myCat;


You can also create custom qualifiers.



@Inject
From Java community, almost a replacement to@Autowired, so suggest to use @Inject
Remember to add dependency:
<dependency>
 <groupId>javax.inject</groupId>
 <artifactId>javax.inject</artifactId>
 <version>1</version>
</dependency>

@Inject
@Named("cat")
private String name;

Different to @Autowire, @Inject has a Provider interface, which can do lazy injection and inject multiple instances.
In this constructor, we inject a provider and get() gives different instances each time.

 private Set<Cat> cats;
 @Inject
 public CatTest(Provider<Cat> catProvider){
  cats = new HashSet<Cat>();
  for(int i=0;i<5;i++){
   cats.add(catProvider.get());
  }
 }


Difference between @Named and @Qualifier:
@Qualifier is to narrow the selection of matching beans(use bean's ID by default)
@Named specifically identifies a selected bean by its ID


@Value
Inject a hard coded value is not interesting. But we can also inject with SpEL expressions.

Example: We inject a value from a property file
@Value("#{systemProperties.myAddress}")
private String address;



@Resource Auto-wire, find the property name as bean id from applicationContext.xml usage:
@Resource
EmployeeServiceInterface employeeService;
bean config:
<!-- Service Beans -->
<bean id="employeeService" class="com.gvace.service.impl.EmployeeService">
</bean>
@Resource(name="myCat") Set property by annotation in class, by-name In bean class, put @Resource on property or set function
@Resource(name="myCat")
private Cat myCat;
or
@Resource(name="myCat")
public void setMyCat(Cat myCat){
 this.myCat = myCat;
}
@Resource Auto-wire, find the property name as bean id from applicationContext.xml usage:
@Resource
EmployeeServiceInterface employeeService;
bean config:
<!-- Service Beans -->
<bean id="employeeService" class="com.gvace.service.impl.EmployeeService">
</bean>

No comments:

Post a Comment