Suresh Rohan's Blog

This blog is all about Java, J2EE,Spring, Angular, React JS, NoSQL, Microservices, DevOps, BigData, Tutorials, Tips, Best practice, Interview questions, Views, News, Articles, Techniques, Code Samples, Reference Application and much more

Friday, January 21, 2011

Spring Framework Advanced


What is ApplicationContext?
Extension of BeanFactory interface
– It provides all the same functionality and more
Supports an infrastructure to enable lots of enterprise-specific features such as transactions and AOP
Used in a more framework-oriented style by using layering and hierarchical contexts providing extra features over BeanFactory

Features of ApplicationContext
Extra features over BeanFactory
– Additional life-cycle interfaces
– Event propagation to beans implementing the ApplicationListener interface
– MessageSource, providing access to messages in, i18n-style
– Access to resources, such as URLs and files
– Loading of multiple (hierarchical) contexts, allowing each to be focused on one particular layer, for example the web layer of an application

When to Use ApplicationContext?
Use ApplicationContext over BeanFactory to take advantage of its extended functionality
– Except for a few limited situations such as perhaps in an Applet, where memory consumption might be critical, and a few extra kilobytes might make a difference

How to use ApplicationContext?
Many users will use ApplicationContext in a completely declarative fashion, not even having to create it manually, but instead relying on support classes such as ContextLoader to automatically start an ApplicationContext as part of the normal startup process of a J2EE webapp
– It is still possible to programmatically create an ApplicationContext

Life-cycle Interfaces
ApplicationContextAware interface
– A bean which implements this interface will be called on creation of the bean, using the interface's setApplicationContext() method, and provided with a reference to the context, which may be stored for later interaction with the context

Example: ApplicationContextAware

public class Publisher implements ApplicationContextAware {

private ApplicationContext ctx;
// This method will be called by the container
public void setApplicationContext( ApplicationContext applicationContext) throws BeansException {
// Save the ApplicationContext object for
// later use.
this.ctx = applicationContext;
}
// Code that uses ApplicationContext

Life-cycle Interfaces
BeanPostProcessor interface
– In an ApplicationContext, any deployed bean which implements this interface is automatically detected and registered as a bean post-processor, to be called appropriately at creation time for each bean in the factory

Propagating Events
Event handling in the ApplicationContext is provided through the ApplicationEvent class and ApplicationListener interface
– If a bean which implements the ApplicationListener interface is deployed into the context, every time an ApplicationEvent gets published to the ApplicationContext, that bean will be notified
– Essentially, this is the standard Observer design pattern.

Three Built-in Events
ContextRefreshEvent
– ApplicationContext is initialized or refreshed
ContextClosedEvent
– ApplicationContext is closed
RequestHandleEvent
– A web-specific event telling all beans that a HTTP request has been serviced

Example: Event Handling

● Configuration in the ApplicationContext.xml - whenever you receive an email from an address from a black list, send a notification to spam@list.org

<bean id="emailer" class="example.EmailBean">
<property name="blackList">
<list>
<value>black@list.org</value>
<value>white@list.org</value>
<value>john@doe.org</value>
</list>
</property>
</bean>
<bean id="blackListListener" class="example.BlackListNotifier">
<property name="notificationAddress" value="spam@list.org"/>
</bean>

Bean class – publish events through ApplicationContext object

public class EmailBean implements ApplicationContextAware {
/** the blacklist */
private List blackList;
public void setBlackList(List blackList) {
this.blackList = blackList;
}
public void setApplicationContext(ApplicationContext ctx) {
this.ctx = ctx;
}
public void sendEmail(String address, String text) {
if (blackList.contains(address)) {
BlackListEvent evt = new BlackListEvent(address, text);
ctx.publishEvent(evt);
return;
}
// send email
}


Notifier class – gets event notifications

public class BlackListNotifier implement ApplicationListener {
/** notification address */
private String notificationAddress;
public void setNotificationAddress(String notificationAddress) {
this.notificationAddress = notificationAddress;
}
public void onApplicationEvent(ApplicationEvent evt) {
if (evt instanceof BlackListEvent) {
// notify appropriate person
}
}
}

Using MessageSource
ResourceBundleMessageSource is an implementation of MessageSource interface
The example below assumes you have three resource bundles defined on your classpath called format, exceptions and windows

<beans>
<bean id="messageSource”
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>format</value>
<value>exceptions</value>
<value>windows</value>
</list>
</property>
</bean>
</beans>


Getting Resources
Resource x = contextObject.getResource(String location);
Returns a Resource handle for the specified resource
– getClass()
– getURL()
Supported formats
– fully qualified URLs, e.g. "file:C:/test.dat".
– classpath pseudo-URLs, e.g. "classpath:test.dat".
– relative file paths, e.g. "WEB-INF/test.dat".

Example: Getting a Resource

ApplicationContext ctx = new FileSystemXmlApplicationContext(
"./events/events.xml");
Resource res1 = ctx.getResource("test.txt");
Resource res2 = ctx.getResource("classpath:log4j.properties");
Resource res3 = ctx.getResource("http://www.google.co.uk");

ApplicationContext Instance
As opposed to the BeanFactory, which will often be created programmatically,
ApplicationContext instances can be created declaratively using for example a ContextLoader

The listener inspects the contextConfigLocation parameter. If it doesn't exist, it'll use /WEB-INF/applicationContext.xml as a default

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/daoContext.xml /WEBINF/
applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

PropertyPlaceholderConfigurer
Used to externalize property values from a BeanFactory definition, into another separate file in the standard Java Properties format
– Useful to allow the person deploying an application to customize enviroment-specific properties (for example database URLs, usernames and passwords), without the complexity or risk of modifying the main XML definition file or files for the container

PropertyPlaceholderConfigurer

<!-- Configurer that replaces ${...} placeholders with values from a
properties file -->
<!-- (in this case, JDBC-related settings for the dataSource definition below) -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderC
onfigurer">
<property name="location" value="/WEB-INF/jdbc.properties"/>
</bean>

jdbc.properties

# Properties file with JDBC-related settings.
# Applied by PropertyPlaceholderConfigurer from "applicationContext-*.xml".
# Targeted at system administrators, to avoid touching the context XML files.
jdbc.driverClassName=org.hsqldb.jdbcDriver
#jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:hsqldb:hsql://localhost:9001
#jdbc.url=jdbc:mysql://localhost:3306/petclinic
jdbc.username=sa
jdbc.password=
# Property that determines the Hibernate dialect
# (only applied with "applicationContext-hibernate.xml")
hibernate.dialect=org.hibernate.dialect.HSQLDialect
#hibernate.dialect=org.hibernate.dialect.MySQLDialect
# Property that determines the JDBC implementation of Clinic
# (only applied with "applicationContext-jdbc.xml")
petclinic.jdbcImplBeanName=hsqlClinic
#petclinic.jdbcImplBeanName=mysqlClinic

Checking for Dependencies
Used to check for the existence of unresolved dependencies of a bean deployed into the container
– These are JavaBeans properties of the bean, which do not have actual values set for them in the bean definition, or alternately provided automatically by the autowiring feature
This feature is sometimes useful when you want to ensure that all properties (or all properties of a certain type) are set on a bean.
Can also be enabled and disabled per bean

Dependency Checking Modes
none – no dependency checking
simple – dependency checking is performed for primitive types and collections (everything except collaborators)
object – dependency checking is performed for collaborators only
all – dependency checking is done for collaborators, primitive types and collections

Singleton
When a bean is a singleton, only one shared instance of the bean will be managed, and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned by the Spring container
Default behavior in Spring

Example: Singleton (version 1.2.x)

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- Singleton examples -->
<bean id="Singleton" class="java.lang.String" singleton="true">
<constructor-arg>
<value>Value</value>
</constructor-arg>
</bean>
</beans>

PropertyEditor
A PropertyEditor is a class that converts a property's value to and from its native type representation into a String
Spring comes with built-in PropertyEditor implementations that are preregistered with the BeanFactory
– ClassEditor
– FileEditor
– LocaleEditor
– PropertiesEditor
– URLEditor

FactoryBean
Interface to be implemented by objects used within a BeanFactory that are themselves factories.
If a bean implements this interface, it is used as a factory, not directly as a bean
getObject() method
– Return an instance (possibly shared or independent) of the object managed by this factory

No comments:

Post a Comment