Showing posts with label Spring. Show all posts
Showing posts with label Spring. Show all posts

Monday, September 6, 2010

Conversion from/to between String and non String properties

Spring Custom Property Editors:

We might be wondering that even though the property of a bean if of any type (int, URL, Date etc), we always set the properties in the context file using the property attribute or constructor inside double quotes (" ") i.e. we always set the properties as String.
For example, if there is an age property of an employee and the property is of type int, then too, in the context file, the property for the employee bean is set as following:

<bean id="emp" class="com.blog.examples.employee">
<property name="age" value="25" />
</bean>


So, we see that the property is set within double quotes i.e. String. Similarly, consider this property wsdlDocumentUrl which we use for JaxRpcPortProxyFactoryBean for wiring Web Services:

<property name="wsdlDocumentUrl" value="http://www.mycompany.com/CustomService?wsdl" />


Though the wsdlDocumentUrl accepts a property of java.net.URL type, it is still specified with the String convention inside the context file. The Question is how does the property mapping happens from String to non-String specific types?

Well, under the covers, Spring automatically converts String value to the Specific type based on the Actual property type of the bean and this conversion happens through a feature of JavaBeans API known as PropertyEditor.
The java.beans.PropertyEditor interface provides a means to customize how String values are mapped to non-String types. A convinent implementation of this interface- java.beans.PropertyEditorSupport has 2 methods of interest to us:
1. getAsText() returns the String representation of a property's value
2 setAsText(String value) sets a bean property value from the String value passed in

If an attempt is made to set a non-String property to a String value, the setAsText() method is called to perform the conversion and Likewise, the getAsText() method will be called to to return a textual representation of the property's value.

Similarly, here are the Several PropertyEdiotors that Spring uses internally to convert the value of a property from a String to non-Strng specific type.
ClassEditor, CustomDateEditor, FileEditor, LocaleEditor, URLEditor etc

Bean Lifecycle using BeanFactory And ApplicationContext

The following is the lifecycle of bean in ApplicationContext and BeanFactory:

1. Instantiate: Spring Instantiates the bean
2. Populate Properties: Spring injects the bean proprties
3. Set bean name: If the bean implements BeanNameAware, Spring passes the bean's ID to the setBeanName() method
4. Set bean factory: If the bean implements BeanFactoryAware, Spring passes the bean's factory to setBeanFactory() method
5. Set Application Context: If the bean implements ApplicationContextAware, the setApplicationContext() method will be called. Note: This is the only extra step that comes in the lifecycle of a bean using ApplicationConetxt container instead of BeanFactory
6. PostProcess (Before initialization): If there are any BeanPostProcessors, Spring calls their postProcessBeforeInitialization() method (Example is PropertPlaceHolderConfigurer)
7. Initialize Beans: If the bean implements InitializingBean, its afterPropertiesSet() method will be called. If the bean has a custom init-method defined in context file, that specific initializing method will be called.
8. PostProcess (After Initialization): If there are any BeanPostProcessors, Spring calls their postProcessAfterInitialization() method
9. Bean ready to use: At this point of time, the bean is ready to be used by the application and will remain until it is no longer needed.
10 Destroy Bean: If the bean implements DisposableBean, its destroy() method will be called. However, If the bean has a custom destroy-method defined in context file, that specific method will be called.

Thursday, October 1, 2009

Quartz Scheduler with Spring

Spring and Quartz Scheduler:

We will take an example of sending the reminder of timesheet submission every Friday at 1:00 PM to all the employees using Quartz Scheduler:
Quartz Scheduler mainly uses the following 3 for implementing the job scheduling using spring:

1. JobDetailBean
2. CronTriggerBean
3. SchedulerFactoryBean
Let us see the role of each of them in detail:

JobDetailBean: JobDetailBean is simply a JavaBean representation of a JobDetail. JobDetail can be considered something whose objects contain all the information needed to run a Job. i.e. JobDetailsBean is a subclass of Quartz’s org.quartz.JobDetail, which requires the Job implementation be set through ‘jobClass' property. Let’s see how we configure a JobDetailBean in our context file:

<bean name="timsheetReminderJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.prokarma.TimeSheetReminderJob"/>
<property name="jobDataAsMap">
<map>
<entry key="timesheetServive" value-ref="timesheetService"/>
</map>
</property>
</bean>

And here is the TimeSheetReminderJob class which is declared above:

public class TimeSheetReminderJob extends QuartzJobBean {

private TimesheetService timesheetService;

/**
* Setter called after the TimesheetReminderJob is instantiated
* with the value from the JobDetailBean
*/
public void setTimesheetService(TimesheetService timesheetService) {
this.timesheetService = timesheetService;
}

protected void executeInternal(JobExecutionContext ctx)
throws JobExecutionException {
// do the actual work i.e. send timesheetRemiders
timesheetService.sendTimesheetRemiders();
}
}


As can be seen from the bean declaration and the TimeSheetRemiderClass, We have configured a bean named as ‘timeSheetReminder’ as a JobDetailBean. The properties of this bean are very important to understand. 'jobClass' property specifies which class will act as a job (In this case, TimeSheetReminderJob) and hence run. This class should extend QuartzJobBean and implement the method executeExternal which contains the business logic that should be implemented for the job (in this case, sending timesheet reminders by calling sendTimeSheetRemider() method form it). The ‘jobDataAsMap’ property takes a java.util.Map that contains properties that are to be set on the object specified by the jobClass (Since, we have just 1 property ‘timeSheetService’, we set it and give it a ref to another bean somewhere defined in the context file.

CronTriggerBean: Now, since the job is created, we need to specify when this job should run (In our case, as we said earlier, we need it to run every Friday at 1:00 PM). This is specified through org.quartz.Trigger class. There are 2 implementation of Trigger class. They are SimpleTriggerBean and CronTriggerBean. Using SimpleTriggerBean, we can just specify how often a job should run and (optionally) how long to wait for the job to run for the first time (i.e. after the context startup). Here we cannot specify inner details like the exact day/date/month/year etc and exact time on which it should run. Hence, we opted for CronTriggerBean as our Trigger for our TimeSheetReminderJob and specify the exact date and time for the job.
Here is how we configure the CronTiggerBean as a bean in our context file:

<bean id="cronTriggerBean" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="timesheetReminderJob"/>
<!-- run every Friday at 1 PM -->
<property name="cronExpression" value="0 0 13 ? * FRI"/>
</bean>


As can be seen, we just need to set 2 properties for the CronTriggerBean. They are: jobDetail (which specifies the JobDetailBean we declared earlier i.e. which specifies the class which acts as a job) and ‘cronExpressionProperty’ which specifies a expression that identifies the runtime of a job. It can be broken upto six (or possibly seven) time elements, separated by spaces. In order from left to right, these elements are defined as follows:

1. Seconds (0-59)
2. Minutes (0-59)
3. Hours (0-23)
4. Day of month (1-31)
5. Month (1-12 or JAN-DEC)
6. Day of Week (1-7 or SUN-SAT)
7. Year (1970-2099)


Each of these elements can be specified with an explicit value (eg. 6), a range (ex: 9-12), a list (eg. 9,10,11) or a wildcard (eg. *). The day of the month and day of the week are mutually exclusive, so you should specify just one of those fields by specifying the other field as a blank (i.e. a ‘?’)
In the case of our cronTriggerBean, we’ve set the cronExpression as “0 0 13 ? * FRI”. You can read this as “Zeroth second of 0th minute of 1 PM (13:00 in 24hrs format is 1:00 PM ) on any day of the month of any month and every Friday of the week”. Some examples of cron expressions and their meanings are specified below:

0 0 10,14,16 * * ? Every day at 10AM, 2PM and 4PM
0 0,15,30,45 * 1-30 ? Every 15 minutes on the first 30 days of the month
30 0 0 1 1 ? 2012 30 seconds after midnight on Jan 1, 2012
0 0 8-17 ? * MON-FRI Every Monday to Friday from 8AM to 5PM

SchedulerFactoryBean: To start a Quartz’s job, we will use Spring’s SchedulerFactoryBean. It is declared as:

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTriggerBean"/>
</list>
</property>
</bean>

The ‘triggers’ property takes an array of references to trigger beans. Since we only have a single trigger at the moment, we simply need to wire it with a list containing a single reference to the cronTriggerBean bean.
This was the final step in setting up the Quartz scheduler in Spring. At this time, our timesheet reminder service will be calling sendTimesheetRemiders() menthod on every Friday at 1 PM.

Wednesday, September 30, 2009

Sending email using Spring with JavaMail

Spring and JavaMail for sending emails:

Being a good java and spring developer, we might face a scenario sometime where we would be asked to construct and send an email from our application when something happens. This something may be like when our timesheet is pending or say when we have deposited or withdrawn some amount from our bank account. When we need to do that, there is nothing much simpler than using spring with javamail api for sending emails. Let us take the same example of the banking operation in our example and see how we configure spring with javamail to send emails.
As we all know, spring uses the concept of DI which is nothing but making our classes and interfaces as beans in the context files and wiring the properties directly or through references. Well, spring uses the same concept for emails. The 2 most important interfaces that we need to configure in spring is:
1. MailSender
2. MailMessage
MailSender: Spring comes with an email abstraction API that makes simple work of sending emails. This is MailSender interface. i.e. The purpose of MailSender interface is to send emails after configuring the mail properties from the MailMessage such as the from and to address, subject of the email, body of the email etc. Spring comes with 2 implementation of MailSender interface. They are CosMailSenderImpl and JavaMailSenderImpl. We will not talk about CosMailSenderImpl.
JavaMailSenderImpl is most versatile and widely used. It is a MailSender based on the JavaMail API. It allows us to send messages of MIME type and even to send non SMTP mail (such as Lotus Notes).
Here is how we configure the JavaMailSenderImpl as a bean in our context file, assuming that we would be sending the email to gmail ids, needing authentication

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.gmail.com" />
<property name="port" value="465" />
<property name="protocol" value="smtps" />
<property name="username" value="banking@gmail.com" />
<property name="password" value="banking" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtps.auth">true</prop>
<prop key="mail.smtps.starttls.enable">true</prop>
<prop key="mail.smtps.debug">true</prop>
</props>
</property>
</bean>

The properties explained in the mailSender are self explainatory. For ex: host specifies the hostname of the mail server that we will use for sending emails. port specifies that the mail server is listening to this port no. (This is by default 25. But smtp gmail listens on port no. 465). Since our mails server need authentication, we have specified the username and password property. We have also specified that authentication is required by specifying the mail.smtps.auth javaMailProperty to true. When we specify mail.smtps.starttls.enable as true, it means that the email is delivered in an encrypted way to the user, hence preventing from any unauthorized access.

MailMessage: MailMessage is nothing but the actual message that will be constructed while sending the email. We have lot of implementations of MailMessage but we will just look at its simplest implementation that sends emails as normal text and without any attachments etc. The simplest implementation of the MailMessage is SimpleMailMessage and as said earlier, we configure details like: from and to address, subject and body of the email using the mail message.
It is necessary to configure the MailMessage in the context file, but we have the option of setting its properties in the class level itself. However, it is a generic thing and we can thus create a template of a MailMessage in the context file by specifying the place holders in the template and replace those place holders in the actual class file. Let us see how we can do this:



<bean id="mailMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from">
<value>
<![CDATA[JDBCBanking <banking@gmail.com>]]>
</value>
</property>
<property name="subject">
<value><![CDATA[Amount deposited in your account></value>
</property>
<property name="text">
<value>
<![CDATA[Hello %NAME%!
This is to inform you that %AMOUNT% Rupees has been deposited to your account on %DAT%
Your balance is now Rupees %BAL%

Thanks
Admin-JDBCBanking
]]>
</value>
</property>
</bean>

Now, we need to wire the 2 beans that we created above (i.e. mailSender and mailMessage) into our service bean like:



<bean id="memberService" class="com.prokarma.service.MemberServiceImpl">
<property name=”mailSender” ref=”mailSender” />
<property name=”mailMessage” ref=”mailMessage” />
</bean>

Finally, lets see how we consider these properties in our class and replace the place holders for them with specific values and send email.

In MemberServiceImpl class, provide setter methods for MailSender and MailMessage as:


private MailSender mailSender;
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}

private SimpleMailMessage mailMessage;
public void setMailMessage(SimpleMailMessage mailMessage) {
this.mailMessage = mailMessage;
}

Here is how you can construct the mail message by obtaining from the context file and replacing the place holders and finally send it:



SimpleMailMessage message = new SimpleMailMessage(mailMessage);
message.setTo(member.getEmail().trim());

String text = message.getText(); //Obtains the text form the template
//replaces the %NAME% placeholder from template with actual member's name
text = StringUtils.replace(text,"%NAME%",member.getName());
text = StringUtils.replace(text,"%AMOUNT%",member.getDepositAmount().toString());
text = StringUtils.replace(text,"%DAT%",member.getDepositDate());
text = StringUtils.replace(text,"%BAL%",member.getBalance());

message.setText(text); // Finally, sets the message text with specific member details

mailSender.send(message);


We have first obtained the template text from the context file, then we edit it for a specific member by replacing the place holders with the specific member details and using StringUtils to replace them. Finally, we set the text of the message again and last step is to send the mail by calling mailSender.send(message);

Monday, August 17, 2009

Bean Factory and Application Context

Spring IOC Container:

In Spring, the application objects will live within the Spring container. The Spring IOC container is mainly responsible for creating the objects, wiring them together, configuring them and managing their complete lifecycle i.e. from initializing to destruction. There are various implementation of Spring Containers. The 2 most common of them are:

1. BeanFactory (org.springframework.beans package) and

2. ApplicationContext (org.springframework.context package)

BeanFactory (org.springframework.beans.factory.BeanFactory interface) is the simplest of containers, providing the basic functionality of Dependency Injection. ApplicationContext (org.springframework.context.ApplicationContext interface) builds on the top of BeanFactory and provides application framework services such as the ability to resolve textual messages from a properties file (for i18N), ability to publish application events to interested event listeners etc

BeanFactory:

BeanFactory is an implementation of Factory design Pattern. BeanFactory knows about many objects in the application, it is able to create association between collaborating objects as they are instantiated. As a result, when the bean factory hands out the objects, those objects are fully configured, are aware of their collaborating objects and are ready to use. A BeanFactory also takes part in the lifecycle of the bean, making calls to custom initialization and destruction methods, if they are defined.
There are several implementations of BeanFactory but the one that is most commonly used is org.springframework.beans.factory.xml.XmlBeanFactory, which loads its beans based on the definitions contained in an XML file.To create an XmlBeanFactory, you must pass an instance of org.springframework.core.io.Resource to the constructor. The Resource object will provide the Xml to the factory. There are several implementations of the Resource, but the 2 most commonly used Resource are: FileSystemResource (which reads the bean definitions from an XML file in the file system) and ClassPathResource (which reads the bean definitions from and XML file placed in the classpath)
Let us consider an example which retreives its bean from a file called as applicationContext.xml and is in the classpath of our application

BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));

This line tells the bean factory to read the bean definitions from the XML file. But the bean factory doesn't instantiate the beans yet. Beans are "lazily" loaded into bean factories, which means, while the bean factory immediately load the bean definitions (the description of beans and their properties), the beans are not instantiated until they are needed.
To retreive a bean from a BeanFactory, simply call the getBean() method, passing the ID of the bean you want to retreive:

MyBean myBean = (MyBean) factory.getBean("myBean");

When getBean() is called, the factory will instantiate the bean and sets its properties using DI, thus begins the lifecycle of a bean within the Spring Container.

ApplicationContext:


A bean factory is fine for simple applications, but to take advantage of the full power of Spring framework, you'll probably want to load your beans using Spring's more advanced container: the ApplicationContext
ApplicationContext is pretty much similar to the BeanFactory as both load bean definitions, wire beans together, and dispense beans upon request. But ApplicationContext offers much more:

1. It provides means for resolving text messages, including support for internationalization (I18N) of those messages

2. Provides generic way to load file resources, such as images

3. Can publish events to beans that are registered as listeners.


Three most commonly used implementations of ApplicationContext are: FileSystemXmlApplicationContext, ClassPathXmlApplicationContext and XmlWebApplicationContext
Loading an application context from file system or class path is pretty similar to how we load using bean factory. For example, here is how you would load beans from a FileSystemXmlApplicationContext and

ClassPathXmlApplicationContext:ApplicationContext context = new FileSystemXmlApplicationContext("c://applicationContext.xml"); (OR)
ApplicationContext context = new ClasspathXmlApplicationContext("applicationContext.xml");

One major difference between application context and bean factory is how the singleton beans are loaded:A bean factory lazily loads all the singleton beans , deffering the bean creation until getBean() is called. An applicatio context is a bit smarter and pre loads all the singleton beans upon context startup. By preloading singleton beans you ensure that beans will be ready to use when needed- your application won't have to wait for them to be created.