Spring 3 part 3: Standard wiring
This is the 3rd part of the Spring 3 Series.
In the part 2 of this series explained the Spring way of wiring. The part 2 examples are continued in this blog.mThis part is dedicated to standard wiring that is proposed by the Java Community Process. Spring 3 implements the JSR-330 that is @Inject annotation.
The @Inject is lot common to the @Autowire but no “required” attribute.
import javax.inject.Inject;
import javax.inject.Named;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Parent {
@Inject
@Named("grandChild")
private Child child;
The Parent class’s child property is annotated with @Inject and @Named. Here @Named is similar to @Qualifier, for instance grandChild is declared as a Spring bean in the spring-config.xml file which is referenced in the @Named annotation. It is also possible to create custom qualifier as an alternative way.
Here the custom qualifier
package au.com.blogspot.ojitha.spring3tut1;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
//import org.springframework.beans.factory.annotation.Qualifier;
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface GrandChildQualifier {
}
and the Parent class refer to this custom qualifier as follows
import javax.inject.Inject;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Parent {
@Inject
@GrandChildQualifier
private Child child;
It is important to not that javax.inject package is JCP standard which is available via maven repository by adding the following dependency,
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
There is a way to avoid spring bean declaration in the spring-config.xml file: the magic is @Component. For example, in the spring-config.xml file “component-scan” is enabled and commented out all the bean declarations;
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:component-scan base-package="au.com.blogspot.ojitha.spring3tut1"/>
<!-- bean id="parent" class="au.com.blogspot.ojitha.spring3tut1.Parent"/-->
<!-- bean id="child" class="au.com.blogspot.ojitha.spring3tut1.MyChild"/-->
<!-- bean id="grandChild" class="au.com.blogspot.ojitha.spring3tut1.GrandChild"/-->
</beans>
The Parent bean can be declared as component and access through the application context
package au.com.blogspot.ojitha.spring3tut1;
import javax.inject.Inject;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
@Component("parent")
public class Parent {
@Inject
//@MyChildQualifier
@GrandChildQualifier
private Child child;
public void setChild(Child child){
this.child = child;
}
public Child getChild(){
return this.child;
}
/**
* @param args
*/
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
Parent parent = (Parent) ctx.getBean("parent");
parent.getChild().sayHello();
}
}
The Parent component named as “parent”.
The GrandChild component is as follows
package au.com.blogspot.ojitha.spring3tut1;
import org.springframework.stereotype.Component;
@GrandChildQualifier
@Component
public class GrandChild extends Child {
@Override
public void sayHello(){
System.out.println("I am grand child...");
}
}
With only qualifier, it should be possible to find the component. Obviously, this is possible with <context:include-filter> and <context:exclude-filter>. For example, remove the @component from the GrandChild bean as follows
package au.com.blogspot.ojitha.spring3tut1;
@GrandChildQualifier
//@Component
public class GrandChild extends Child {
@Override
public void sayHello(){
System.out.println("I am grand child...");
}
}
You need to remove the component from the MyChild bean also
package au.com.blogspot.ojitha.spring3tut1;
@MyChildQualifier
//@Component
public class MyChild extends Child{
@Override
public void sayHello(){
System.out.println("Hello");
}
}
Now if you look at carefully in the spring-config.xml file
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:component-scan base-package="au.com.blogspot.ojitha.spring3tut1">
<context:include-filter type="assignable" expression="au.com.blogspot.ojitha.spring3tut1.Child"/>
</context:component-scan>
<!-- bean id="parent" class="au.com.blogspot.ojitha.spring3tut1.Parent"/-->
<!-- bean id="child" class="au.com.blogspot.ojitha.spring3tut1.MyChild"/-->
<!-- bean id="grandChild" class="au.com.blogspot.ojitha.spring3tut1.GrandChild"/-->
</beans>
In the spring-config.xml, all the beans of type “au.com.blogspot.ojitha.spring3tut1.Child” is assignable that means both MyChild an GrandChild are auto discovered as components.
Comments
Post a Comment
commented your blog