ApplicationContext is an extension of BeanFactory: it provides all the same functionality, but it reduces the amount of code you need to interact with it and adds new features into the pot for good measure. When using an ApplicationContext, you can control bean instantiation declaratively on a bean-by-bean basis, and any BeanPostProcessors and BeanFactoryPostProcessors registered in the ApplicationContext are executed automatically for you

In addition to providing a model that is focused more on declarative configuration, the ApplicationContext supports the following features not present in a BeanFactory:


Internationalization
Event publication
Resource management and access
Additional life cycle interfaces
Improved automatic configuration of infrastructure components



Implementations of ApplicationContext


Spring provides three implementations intended for use in production applications. All three implementations use the same configuration format as the XmlBeanFactory.


For stand-alone applications where the ApplicationContext cannot be loaded automatically, you can choose from either FileSystemXmlApplicationContext or ClasspathXmlApplicationContext. These names are self-explanatory, and functionally, these classes are quite similar.


With FileSystemXmlApplicationContext, you can load the configuration from anywhere in the file system provided your application has permissions. Using ClasspathXmlApplicationContext, you can load from anywhere on the classpath; this is useful if you want to package the configuration with a bunch of classes inside a JAR file.


The XmlWebApplicationContext is intended solely for use in a web application environment, by using either ContextLoaderListener or ContextLoaderServlet,

you can load the ApplicationContext configuration automatically for your web application


Using ApplicationContextAware


a bean can obtain a reference to its ApplicationContext by implementing ApplicationContextAware.



Implementing ApplicationContextAware
public class ContextAwareDemo implements ApplicationContextAware {
private ApplicationContext ctx;
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
ctx = applicationContext;
}
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"/META-INF/spring/acdemo1-context.xml");
ContextAwareDemo demo = (ContextAwareDemo) ctx.getBean("contextAware");
demo.displayAppContext();
}
public void displayAppContext() {
System.out.println(ctx);
}
}


The ApplicationContextAware interface declares a single method, setApplicationContext(),



Configuration for ContextAwareDemo Class
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="contextAware" class="com.apress.prospring2.ch04.context.ContextAwareDemo"/>
</beans>


Controlling Bean Initialization


When using ApplicationContext, there is a solution to this problem: the lazy-init attribute. By setting the lazy-init attribute on a bean’s <bean> tag to false, you are telling the ApplicationContext that you want to create the bean in advance and the ApplicationContext should not wait until it is first requested.



Using lazy-init
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="destructiveBean"
class="com.apress.prospring2.ch04.lifecycle.DestructiveBeanI">
<property name="filePath" value="/tmp/prospring"/>
</bean>
<bean id="shutdownHook"
lazy-init="false"
class="com.apress.prospring2.ch04.interaction.ShutdownHookBean"/>
</beans>



The LazyInitDemo Class
public class LazyInitDemo {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"/META-INF/spring/acdemo2-context.xml");
ctx.getBean("destructiveBean");
}
}


Using Annotation-Based Configuration
Starting with Spring 2.0, you can use annotations to configure your beans. By annotating your classes, you state their typical usage or stereotype.


Stereotype Annotations in Spring 2.5
@Component - This is the basic stereotype; classes annotated with @Component will become Spring beans.


@Controller - Spring will use any class annotated with the @Controller annotation as
a Controller in Spring MVC support.


@Repository - Classes with the @Repository annotation represent a repository (e.g., a data access object).


@Service - The @Service annotation marks classes that implement a part of the business
logic of the application.


Classes annotated with the @Controller annotation become Spring MVC controllers; classes with the @Repository annotation get automatic exception translation; @Service- and @Component-annotated classes do not change the default behavior of the bean but may carry additional semantics in the future versions


Automatically Detecting Annotated Classes
Without being able to automatically detect the annotated classes, you would not find annotations very usable.


SimplestBean Class with the @Component Annotation


@Component
public class SimplestBean {
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("SimplestBean");
sb.append("{}");
return sb.toString();
}
}


Because we have the @Component annotation, we would like Spring (the ApplicationContext, to be more exact) to automatically pick up this class and turn it into a Spring-managed bean so that we can ultimately use it in an application similar to one


However, we can scan a particular package (and its subpackages) for annotated classes; to do that, we simply use the <context:component-scan /> element in the ApplicationContext XML configuration file.


ApplicationContext XML Configuration File


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.xsd">
<context:component-scan base-package="com.apress.prospring2.ch04.annotations"/>
</beans>



Controlling the Automatic Detection Process


By default, Spring picks up classes annotated with the @Component annotation (or any other annotation that is itself annotated with the @Component annotation). If you want to add to this default behavior, you can use filters to include or exclude candidate classes. You can also use the use-default-filters= "false" attribute in the <component-scan . . ./> element to turn off the annotation-based scanning
behavior.


Whether or not you use the default scanning strategy, there are four filter types, and you need to write an expression that matches the type of the filter you use.


Spring Filter Types


annotation - Set another type of annotation you will use to mark the classes you want Spring to scan.


assignable - Specify a full class name to which the candidate class should be assignable.


regex - Specify a regular expression that the candidate class name should match.


aspectj - Use a pointcut-style expression to specify the class names of the candidate
classes


we can use this application to demonstrate the different configuration settings for component scanning.


ApplicationContext XML Configuration File


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.xsd">
<context:component-scan base-package="com.apress.prospring2.ch04.annotations">
<context:include-filter type="annotation"
expression="com.apress.prospring2.ch04.annotations.Magic"/>
<context:include-filter type="assignable"
expression="com.apress.prospring2.ch04.annotations.ComponentMarker"/>
<context:include-filter type="aspectj"
expression="* void com.apress..annotations.*Service*(..)"/>
</context:component-scan>
</beans>


you may want to be able to control the scope of the automatically created beans. The
easiest way to do so is to use the @Scope annotation and specify the name of the scope. You can use any of the scope names registered in Spring, from the basic singleton and prototype to request, session, and globalSession in web and portal applications.


Alternatively, you can implement the ScopeResolver interface and specify it in the scope-resolver attribute of the <component-scan . . ./> element. To deal with the beans with request, session, and globalSession scopes, we can specify the type of the proxy Spring will return when it returns an instance of the bean using the scoped-proxy attribute in the <component-scan . . ./> element.


Internationalization with MessageSource
One area in which Spring really excels is in support for internationalization (i18n). Using the MessageSource interface, your application can access String resources, called messages, stored in a variety of different languages.


Although you don’t need to use ApplicationContext to use MessageSource, the ApplicationContext interface actually extends MessageSource and provides special support for loading messages and making them available in your environment



Using ApplicationContext and MessageSource
Aside from ApplicationContext, Spring provides three MessageSource implementations:
ResourceBundleMessageSource, ReloadableResourceMessageSource, and StaticMessageSource


The ResourceBundleMessageSource loads messages using a Java ResourceBundle. ReloadableResourceMessageSource is essentially the same, except it supports scheduled reloading of the underlying source files.


All of the implementations, ApplicationContext included, implement another interface called HierarchicalMessageSource, which allows for many MessageSource instances to be nested and is key to the way ApplicationContext works with message sources.


To take advantage of ApplicationContext’s support for MessageSource, you must define a bean in your configuration of type MessageSource and with the name messageSource. ApplicationContext takes this MessageSource and nests it within its default MessageSource, allowing you to access the messages using the ApplicationContext.


Configuring aMessageSource Bean


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages</value>
</list>
</property>
</bean>
</beans>


Using Application Events
Another feature of the ApplicationContext not present in the BeanFactory is the ability to publish and receive events using the ApplicationContext as a broker. An event is class derived from ApplicationEvent, which itself derives from the java.util.EventObject. Any bean can listen for events by implementing the ApplicationListener interface; the ApplicationContext automatically registers any bean that implements this interface as a listener when it is configured. Events are published using the ApplicationContext.publishEvent() method, so the publishing class must have knowledge
of the ApplicationContext.


Accessing Resources
At the core of Spring’s resource support is the Resource interface. The Resource interface
defines seven self-explanatory methods: exists(), getDescription(), getFile(), getFileName(), getInputStream(), getURL(), and isOpen(). In addition to these seven methods, there is one that is not quite so self-explanatory: createRelative(). The createRelative() method creates a new Resource instance using a path that is relative to the instance on which it is invoked.


Internally, Spring uses another interface, ResourceLoader, and the default implementation,
DefaultResourceLoader, to locate and create Resource instances. However, you generally won’t interact with DefaultResourceLoader. Instead, you will be using another ResourceLoader implementation— ApplicationContext.



Accessing Resources Using ApplicationContext
public class ResourceDemo {
public static void main(String[] args) throws Exception{
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"/META-INF/spring/resourcesdemo1-context.xml");
Resource res1 = ctx.getResource("file:///tmp");
displayInfo(res1);
Resource res2 = ctx.getResource("classpath:com/apress/prospring2/ch04/pe/" +
"Complex.class");
displayInfo(res2);
Resource res3 = ctx.getResource("http://www.google.co.uk");
displayInfo(res3);
}
private static void displayInfo(Resource res) throws Exception{
System.out.println(res.getClass());
System.out.println(res.getURL().getContent());
System.out.println("");
}
}

Leave a Reply

Subscribe to Posts | Subscribe to Comments

About This Site

Howdy! My name is Suersh Rohan and I am the developer and maintainer of this blog. It mainly consists of my thoughts and opinions on the technologies I learn,use and develop with.

Blog Archive

Powered by Blogger.

- Copyright © My Code Snapshots -Metrominimalist- Powered by Blogger - Designed by Suresh Rohan -