Since Java adopted annotations, most of application has
started using it to cut down the xml configuration, spring 3 also introduce the
annotation driven configuration, let’s explore.
Here is the Martin Fowler’s famous dependency injection
example of moviLister and moveFinder
MovieFinder
public interface MovieFinder {
List findAll();
}
Implementation of MovieFinder
public class ColonMovieFinder implements MovieFinder {
Resource
filename;
public Resource
getFilename() {
return filename;
}
public void setFilename(Resource
filename) {
this.filename = filename;
}
@Override
public List<Movie>
findAll() {
List<Movie>
movies=null;
try {
movies
= inputStreamAsString(this.filename.getInputStream());
}
catch (IOException e) {
// TODO Auto-generated
catch block
e.printStackTrace();
}
return movies;
}
}
MovieLister needs MovieFinder dependency
public class MovieLister {
private MovieFinder finder;
public void setFinder(MovieFinder
finder) {
this.finder = finder;
}
public Movie[]
moviesDirectedBy(String arg) {
List
allMovies = finder.findAll();
for (Iterator it =
allMovies.iterator(); it.hasNext();) {
Movie
movie = (Movie) it.next();
if
(!movie.getDirector().equals(arg))
it.remove();
}
return (Movie[]) allMovies.toArray(new
Movie[allMovies.size()]);
}
}
Setup the dependency
1.
Configuration java class need to be written to
define the dependency.
2.
Add @Configuration to tell the spring about your
configuration class
3.
@Bean should be define to tell the spring, they
are spring bean
4.
initMethod and distroyMethod attribute should be
used in @Bean annotation to define the life cycle.
5.
@Scope should be used to define the scope is singleton
or prototype or request ect
@Configuration
public class AppConfig {
public
@Bean(destroyMethod="distroy",initMethod="init")
@Scope("prototype")
MovieLister
movieLister() {
MovieLister
moviLister = new MovieLister();
moviLister.setFinder(movieFinder());
return moviLister;
}
public @Bean
MovieFinder
movieFinder() {
ColonMovieFinder
colonMovieFinder = new ColonMovieFinder();
Resource
resource = new ClassPathResource("examples/movies.txt");
colonMovieFinder.setFilename(resource);
return colonMovieFinder;
}
}
Construct the
application context
1.
Pass the class having @Configuration to AnnotationConfigApplicationContext
constructor
2.
More than one configuration can be written and
all of them can be passed to constructor as it support java 5 vargar
AnnotationConfigApplicationContext context
= new
AnnotationConfigApplicationContext(AppConfig.class);
Test class
public class
ApplicationContextAnnotationTest {
public static void main(String[] args) {
//Initialize
IoC Container
AnnotationConfigApplicationContext
context = new AnnotationConfigApplicationContext(AppConfig.class);
//Retrieve the bean
from Container
MovieLister
myBean = context.getBean(MovieLister.class);
for(Movie m :
myBean.moviesDirectedBy("Rajnikant")){
System.out.println(m);
}
context.destroy();
context.close();
}
}
Problems what if you
two bean of same type?
1.
Pass the name to @bean attribute
2.
Get the bean from context using been class and
name.
Register bean by name
public @Bean(name="moviFinder")
MovieFinder
movieFinder() {
ColonMovieFinder
colonMovieFinder = new ColonMovieFinder();
Resource
resource = new ClassPathResource("examples/movies.txt");
colonMovieFinder.setFilename(resource);
return colonMovieFinder;
}
Retrieve bean by name
AnnotationConfigApplicationContext
context = new AnnotationConfigApplicationContext(AppConfig.class);
MovieFinder
myFind = context.getBean("moviFinder",MovieFinder.class);
Problem : this approach doesn’t
cut the configuration it just move the configuration from xml file to java file,
right way to cut the configuration is autowiring that I will post in next blog
No comments:
Post a Comment