Professional Documents
Culture Documents
In case of Spring MVC user has to send the request with extension *.htm or *.mvc or *.web or *.action
depends on the DispatcherServlet configuration wild card pattern. When user send the request it will be
received by DispatcherServlet. Now DispatcherServlet asks the HandlerMapping to give the Controller
information to whom he has to send the request by giving incoming url. Now HandlerMapping will take the
url and map the appropriate Controller and return the Controller information to DispatcherServlet. Now
DispatcherServlet will forward the request to Controller for processing the request. Now controller will
process the request and return back the logical view name to the DispatcherServlet. After getting the
logical view name DispatcherServlet will ask the ViewResolver to resolve the view by passing logical view
name. View resolver will take the logical view and creates the object of the view which should be
rendered by DispatcherServlet and return the View Object to DispatcherServlet. Now by getting the View
Object DispatcherServlet will render the appropriate view. In this way Spring MVC flow works. In the
above explanation we have understoond the overall flow of spring MVC.
Let’s see how each and every component declared above in spring mvc perform their task to full fill the
users request through small web application-
FirstMvcWeb
|-src
|-WebContent
|-WEB-INF
|-lib
|-web.xml
|-home.jsp
In above project directory structure FirstMvcWeb is the root directory of our application. This application
will show how to render the home.jsp. In a typical web application we put jsp pages in WebContent
directory but in above application we have put the home.jsp inside the WEB-INF. In case of Spring MVC it
is recommended to keep View inside the WEB-INF. Let’s see what happens when we keep view in
WebContent directory in case of Servlet and Jsp or Struts framework-
1. WebContent is a public directory, views in this directory can be accessed by any users directly. In this
case our presentation layer component get exposed to End-User. It means if users of our application is
technically strong then they might hack our application by using session and knowing the type of view
(jsp/html).
2. As End-User can directly access the view he or she may send the request to access the view which
expect some data to render. In this case user will get an ugly error message which will give bad
experience of using our application to the user.
3. Let’s suppose our application is for booking movie ticket a user comes and book ticket and live the
system without logout to the page another user comes and he request the same view page with same url
and in same session then he will also gets the same ticket with same information as that is booked by first
user. It will be the biggest problem.
In case of Servlet and Jsp or Struts or any other framework except spring Mvc views are either Jsp or
Html.There is no point in placing the views in WEB-INF to abstract it from user. That’s why it is not
recommended to place the views inside WEB-INF.
In case of Spring Mvc views may be any thing like jsp, html, xml, pdf, Excel Sheet etc. so, due to above
reasons it is recommended to place the views inside WEB-INF directory only.
WEB-INF is the protected directory in the project directory structure. Any thing placed inside the WEB-INF
directory can be used by application component only. It cannot be used by user directly from outside. In
this way our views will be abstracted from end user and our application does not suffer the above
explained problems.
Now Let’s first create the home.jsp page and put it in the WEB-INF directory-
home.jsp
<html>
<head>
<title>Home</title>
</head>
<body>
<p>Welcome to FirstMvcWeb Home. </p>
</body>
</html>
Now we want to access home.jsp to access it we cannot send the request directly to the home.jsp
because it is inside the WEB-INF directory. It can be accessed by application internal component only
which is Controller. Controller will access home.jsp but the problem is we cannot send request directly to
the controller because it is not JEE component. To send the request to the Controller DispatcherServlet
comes into picture.
DispatcherServlet is the component which is provided by spring.It is the single entry point to our
application. It is the front controller in our application which will forward the request to controller to handle
the request. Now to forward the request to Controller we need DispatcherServlet so, let’s configure the
DispatcherServlet in descriptor file (web.xml) as follows-
Instead of writing our Own HandlerMapping spring has provided lot of implementation class for
HandlerMapping which we can use to map the Controller. Some of the HandlerMapping implementation
are-
1.SimpleUrlHandlerMapping
2.BeanNameUrlHandlerMapping
3.ControllerBeanNameHandlerMapping
4.ControllerClassNameHandlerMapping
In our first application let’s use SimpleUrlHandlerMapping.We will discuss about various HandlerMapping
implementaion classes in later section. As this implementation class is provided by spring
DispatcherServlet knows which method it has to call to get the handler (Controller). Now to call the
getHandler(…) method DispatcherServlet needs object of SimpleUrlHandlerMapping but it cannot create
because, it will get tightly coupled with it. To solve this problem spring has provided dependency injection
mechanism. DispatcherServlet will create IOC container by reading the spring bean
configuration file.Configuration file name should be “<Servlet-name>-servlet.xml” by default
DispatcherServlet will looks for the dispatcher-servlet.xml file to create the IOC container. Spring bean
configuration file name should starts with <servlet-name> configured in web.xml then append -servlet.xml
to it. Let’s configure SimpleUrlHandlerMapping in spring bean configuration file-
dispatcher-servlet.xml
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.htm">homeViewController
</prop>
</props>
</property>
</bean>
In the above configuration file homeViewController will be the bean id of View Controller which we will
configure in dispatcher-servlet.xml later. We have configured the SimpleUrlHandlerMapping without any
bean id because DispatcherServlet always takes any HandllerMapping implentations as HandllerMapping
only. We will understand it when we discuss internals of DispatcherServlet. Now DispatcherServlet will
get the SimpleUrlHandllerMapping bean from IOC container and keep it as HandllerMapping reference
because it will not know which HandllerMapping is configured by programmer. After that
DispatcherServlet will invoke getHandller(HttpServletRequest request) method of
SimpleUrlHandllerMapping to get the Controller bean id. SimpleUrlHandlerMapping will take the request
and try to match the incoming url to the configured property key of mappings url if matched then it will
return the value which is the bean id of the Controller to DispatcherServlet. Now by getting the bean id of
the Controller DispatcherServlet will get the Controller from the IOC container and forward the request to
it by calling handle(request,respose) method.We will discuss about internals of DispatcherServlet in later
section.
Now Let’s create a Controller class which will handle the request and then configure it in spring bean
configuration file (dispatcher-servlet.xml). Just creating any class will not become Controller class
because DispatcherServlet will not know which method it has to call to forward the request so, Spring has
given an interface called Controller and its multiple implementation class. to make our class as Controller
class we have to either implements from Controller interface or extends from its implementation
classes. We will discuss about various implementation classes in later section. At this time let’s extends
our class from AbstractController class which is one of the implementaion class provided by spring.
Controller
dispatcher-servlet.xml
<!-->HandllerMapping Configuration<-->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.htm">homeViewController</prop>
</props>
</property>
</bean>
<!-->Cotroller Configuration<-->
<bean id="homeViewController" class="HomeViewController"/>
Now After getting the ModelAndView object from Controller DispatcherServlet has to render the view but
it does not know which type of view he has to render. To solve this problem ViewResolver comes into
picture. ViewResolver is the component which will take the logical view name and resolve it to the View
class object which is to be rendered. Now DispatcherServlet has logical view name so it will call the
ViewResolver by passing the logicla view name. To get the ViewResolver Dispatcher Servlet will have to
find it in IOC container. So, let’s configure the ViewResolver in spring bean configuration file(dispatcher-
servlet.xml). Again tere are lots of ViewResolver impementations are provided by spring so we not need
to create our own ViewResolver. Let’s use one of the ViewResolver implementations provided by Spring.
Here we are using InternalResourceViewResolver.
dispatcher-servlet.xml
<!-->HandllerMapping Configuration<-->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.htm">homeViewController</prop>
</props>
</property>
</bean>
<!-->Cotroller Configuration<-->
<bean id="homeViewController" class="HomeViewController"/>
<!-->ViewResolver Configuration<-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"/>
<property name="suffix" value=".jsp"/>
</bean>
We have not configured InternalResourceViewresolver with bean id because DispatcherSerrvlet treat all
Implementations of ViewResolver as ViewResolver only. Now ViewResolver will takes the logical view
name and appends prefix and suffix to it to get the view location after finding the view it will creates the
View Type(Jstl for jsp) class and its object which is to be rendered and returns the object of that class to
DispatcherServlet. Now DispatcherServlet will call the render(model) method of that View class by
passing model (data) to render the respective view to the user. In this case there is no data so model will
be null and home.jsp page will be rendered.
In this way various components of Spring MVC communicate with each other to process the request. We
will discuss each and every component in details in later section.
In servlet project architecture usually client will be Jsp or Html. When client send a request it will goes to
servlet container then servlet container will checks for which servlet the request is coming for in descriptor
file (web.xml) based on that, container will forward the request to appropriate servlet. Servlet will gather
the request sent by client through request.getParameter(“–”) in form of String. Now servlet will decide
what operation should be done on the
request. As servlet is one which makes the decision for the operation it is also called as controller.
Let’s take a simple use case of Employee Registration to understand it
registration.jsp
<html>
<head/>
<body>
<form action="${pageContext.request.contextPath}/employeeRegistrationServlet"
method="post">
<table>
<tr>
<td>
First Name</td>
<td>
<input type="text" name="fName">
</td>
</tr>
<tr>
<td>
Last Name
</td>
<td>
<input type="text" name="lName">
</td>
</tr>
<tr>
<td>
Gender
</td>
<td>
<input type="radio" name="gender" value="Male">Male
</td>
<td>
<input type="radio" name="gender" value="female">Female
</td>
</tr>
<tr>
<td>
EmployeeID
</td>
<td>
<input type="text" name="eid">
</td>
</tr>
<tr>
<td>
Salary
</td>
<td>
<input type="text" name="salary">
</td>
</tr>
<tr>
<td>ProjectID
</td>
<td><input type="text" name="pid">
</td>
</tr>
</table>
<input type="submit" value="submit">
</form>
</html>
Servlet
success.jsp
<html>
<head/>
<body>
<p> Data is saved successfully </p>
</body>
</html>
<web-app>
<servlet>
<servlet-name>EmployeeRegistration</servlet-name>
<servlet-class>com.spt.employee.servlet.EmployeeRegistrationServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>EmployeeRegistration</servlet-name>
<url-pattern>/employeeRegistrationServlet</url-pattern>
</servlet-mapping>
<web-app>
Now when user send the request form registration.jsp first it will be received by servlet container then
servlet container goes to deployment descriptor file to find the appropriate servlet for which request is
coming for. Now first servlet container goes to <servlet-mapping> section in web.xml match the incoming
request url with the configured url if matches then get the servlet-name from there and comes to <servlet>
section match the servlet-name taken from servlet-mapping section to the servlet-name configured in the
servlet section if matches then it get the servlet class to which container has to forward the request. In this
way request to the appropriate servlet is mapped by servlet container.
We should never write the business operational logic or persistency logic in servlet. Let’s see why we
should not write persistency logic or business logic in presentation tyre component.
Let’s suppose in above application we have used oracle database to persist the data and written the logic
for doing this in our servlet itself. After some time due to some reason if we want to use SQL Server or
DB2 in place of oracle then to perform the persistent operation again we have to modify the logic in
servlet according to database vendor which will be costlier. Now we can see that changes made in
persistent layer vendors is forcing us to make changes in prsentation layer. Similarly if we have to move
from JDBC technology to Hibernate again we have to modify the code in servlet. In this way we can say
that writing the persistence logic in presentation tyre component(Servlet) is very bad approach to develop
an application. It will make presentation tyre tightly coupled with persistent tyre.
Now let’s suppose we are writing the business logic in servlet to develop the application. After some
period of time, we wan to add some more business functionality in our application then again we have to
modify the servlet. In this way whenever business requirement change we have to modify the code in
servlet. Here, also change required for business layer is affecting presentation layer. So, we should not
write the business logic in presentation tyre component. It will also make presentation tyre tightly coupled
with business tyre logic.
Now let’s see what are the drawbacks in developing the application using servlet architecture-
In a web application there will be multiple servlet and jsp. From each jsp whenever request comes to its
respective servlet it brings some input data to the servlet then in servlet programmer has to write the logic
for wrapping the data. Wrapping of data means collecting the input data from jsp and map it to an object
which will be passed to business layer. In this way we can see that for each and every servlet
programmer has to write data wrapping logic which seems to be redundant process. This is the biggest
problem with servlet based application. To solve this problem we need some front controller which will
perform the redundant process. In case of servlet based application programmer has two choice one
make one servlet as front controller and other use Filter as front controller. But, the problem is still
programmer has to write the complicated wrapping logic. To solve this major problem web application
frameworks came into picture like Struts, JSF, Spring MVC etc.
STRUTS ARCHITECTURE
Let’s understand the struts framework architecture-
In case of struts view (client) will be JSP or Html whenever user send a request it comes to servlet
container then servlet container goes to deployment descriptor file (web.xml) and match the incomming
url to the configured url-pattern. In web.xml url pattern for ActionServlet is *.do which means for any url
request ends with .do will match with the url of ActionServlet. So, in this case for every request ending
with .do will be forwarded to ActionServlet.
Now ActionServlet will perform the request wrapping process and forward the request to Action class by
calling execute(req, res, actionForm) method. Let’s understand how ActionServlet perform this operation-
ActionServlet is struts framework in-built class which acts as front controller. In ActionServlet logic for
wrapping the data coming from jsp to ActionForm is written. The wrapping logic is generic it means it is
not specific to the ActionForm or any input control. When ActionServlet receives a request it collects the
input data and goes to struts-config.xml file search for the Action class to which request is coming based
on the path configured for the Action class by matching path and url inside <action-mappings> Section.
After getting the Action class it search for the name attributes in <action-mappings> section if there is any
name it gets it and go to <form-beans> section find the actual ActionForm which will be sent to the Action
class based on that name. Now after getting the ActionForm ActionServlet will create the object of
ActionForm and populate the collected input data from JSP to the ActionForm class. If any validation over
data is required then ActionServlet will call the validate method of ActionForm. After performing the
validation ActionServlet will call execute method of Action class by passing request, response,
actionForm as input to perform the requested operation.
From the above explanation we come to know how ActionServlet Identify the appropriate Action class and
ActionForm. But, the point is how ActionServlet knows to validate the data it has to call validate() method
and to pass the actionForm it has to call execute(—) method of Action class. To solve this problem struts
has recommended the programmer to not write any class as Action class or ActionForm. To make a class
as ActionForm programmer must have to extends from ActionForm class and to make a class as Action
class they must have to extends the class from Action class. Let’s see the below example-
When we write EmployeeAction and EmployeeActionForm by extending from Action and ActionForm
class we are overriding the execute() method and validate() method which is coming from Struts
components that’s why both execute() and validate() are known to ActionServlet. In this way ActionServlet
performs common system processing logic(Data wrapping) and plumbing logic.
STRUTS PROJECT ARCHITECTURE
Let’s understand how the project will be developed using Struts framework using a use-case of
Employee Management-
In the above project JSP is acting as a view. when user send a request it is received by Action class. All
the input control sent by user through JSP comes to Action class in form of actionForm. In ActionForm
class there will be attributes and the number of attributes is same as the number of input controls coming
from JSP. Generally the types of attributes in ActionForm will be String only. Below example shows how
does ActionForm class looks like-
Now after receiving the request by Action class it will populate the actionForm data to Value Object and
then call the Business Delegate by passing value object. Value Object is a pojo class which will contain
same number of attribute as there in ActionForm and types of the attribute is String only. Let’s see how
value object will looks like-
class EmployeeRegistrationVO
{
private String emp_ID;
private String firstName;
private String lName;
private String salary;
private String gender;
//Accessor methods (Setter and Getter)
}
Value Object contain the data in presentation tyre format. So, Business delegate will call the Object
Transformer to convert the value Object into Business object. Business Delegate itself will not convert
Value Object to Business Object because delegator are not meant for doing. It just delegate the request
to appropriate component to perform the operation. After getting the Business Object Business Delegate
will call the Service class by passing Business Object as input to perform the business operation. Service
class is just a pojo class which will contain the logic for performing the complex business operation. After
performing the business operation Business Delegate will call the DAO to perform the persistent
operation by passing Business object or entity. DAO is a class which will contain only persistent logic
only. Some time while performing the persistent operation DAO will raise an exception then Business
Delegate will catch it and pass this exception to Exception Translator which will translate the exception to
Application specific exception or End-User friendly Exception. Application Specific Exception are tied with
error code and error description which will be understand by technical team who are using this
application. Now After translating the Exception Business Delegate will give it to Action class now Action
class will pass this to Exception Mapper to map it to appropriate Exception based on that Action class will
give response back to the end user as friendly erorr message.
.Let’s suppose there are two DAO1 and DAO2. Now DAO1 is performing the operation of Saving the
Employee in data base with data as Emp_ID= “E1”, fName=Ramesh after performing the operation DAO1
has commit it. Now DAO2 starts performing the operation of sving the Employee to the Project based on
their id now suppose there is already an employee with Emp_Id=E1 on Project_ID=P1 in this case DAO2
will raise an exception and it will rollback but this rollback will not applied on DAO1 so Emp_ID=E1 will be
there in Data base. In this situation we can see that if we perform transaction on DAO level then it will
become indivisual to the DAO it will not become an application level transaction. That’s why instead of
doing the commit or roll back on indivisual DAO do it in Transaction Manager component which will be
called by Business Delegate after Performing each and every DAO operation so commit and roll back will
be applied at once.
If every thing goes fine then Business Delegate will return appropriate response to Action and Action will
give expected response back to the user. In this way all the components in Struts based project going to
communicate with each other and perform the operation while receiving a request. All the component
shown in the above diagram need not to be in each and every struts based project. it depends on the
requirement but a standar struts project should contain all those component.
Business logic
package com.demo.bean;
public class Calculator
{
public int add(int a,int b)
{
return a + b;
}
}
Caching logic
package com.demo.bean;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Cache
{
private static Cache instance;
private Map<String,Object> mapData;
private Cache()
{
mapData=new ConcurrentHashMap<String, Object>();
}
public static synchronized Cache getInstance()
{
if(instance==null)
{
instance=new Cache();
}
return instance;
}
public void put(String key,Object value)
{
mapData.put(key,value);
}
public Object get(String key)
{
return mapData.get(key);
}
public boolean containsKey(String key)
{
return mapData.containsKey(key);
}
}
Now in the above application if user wants to add two same (10,20) value repeatedly then all the
time our application has to perform the operation and return the same value (30) to the user.
Instead of performing the operation each and every time for the same value if we store the result
for that two same value in cache memory then whenever user ask for the operation we can give
them from cache memory. It will make our application fast. Similarly if we want to know the
control flow of our application then we have to write the logging logic. In this way we can see
that to make our business logic work better we require some helper logic which can be called as
secondary logic or cross-cutting logic. Here Caching and logging are cross-cutting logic and
add(–) method of Calculator application containing business logic. In this way we can say that in
every real-time application there will be two types of logic one is primary business logic and
other is cross-cutting logic to make the application perform better.
Aop principles
1.Aspect:- It is the piece of logic or code which has to be applied on a target class joinpoint.
3.JoinPoint:- It is the point on the target class where Advice can be applied to execute the Apect.
4.Pointcut:- It is the set of JoinPoint where advices are applied to execute the Aspect.
When Spring released AOP at that time AspectJ has already accepted in the market and it seems
to be more powerful than Spring AOP. Instead of building Spring AOP more powerful than
AspectJ Spring people provided integration to the AspectJ to take the benefits of it. From Spring
2.x Spring not only supports its own AOP it allows us to work with AspectJ also.
Initially when spring has not support for AspectJ it provides only one way to work with AOP
that isProgrammatic approach after integration with AspectJ it provides two more way to work
with it one isSpring AspectJ declaretive approach and another is AspectJ Annotation approach.
Types Of Advices
1. Around Advice :- This is the advice which executes the aspect logic (cross-cutting logic) around
the target class joinpoint. In this case advice method will be called before the target class method
execution and after the target class method execution. This advice can control the target class
method execution.
2. Before Advice :- In this advice before executing the target class method it will execute the advice
method and after finishing the execution of advice method control will not come back to the advice
method.
3. After Returning Advice :- In this advice method will executes after executing the target class
method successfully but before returning the value to the caller.
4. Throws Advice :- This advice method will be invoked only when the target class method throws
an exception.
Programamatic AOP
To work with programmatic approach we have to use Spring AOP API. Programmatic AOP
Supports All type of Advices defined above. let’s start working with one advice after another and
understand how it is going to work
AroundAdvice
To work with any advice we need target class
Target Class:-
Class Calculator
{
public int add(int a, int b)
{
return a + b;
}
}
Spring support joinPoint at method level. Now in the target class we have add(–) methods which
is a joinpoint. Now on this joinpoint how we want to apply aspect is known by advice here we
want to use around advice. AroundAdvice means before the target class method execution and
after the method execution of target class we want to perform some additional functionality on
target. Now suppose we want to perform logging operation on target to know the details of
execution. Logging operation can be applied on any classes and any methods in our application
to get the execution details of application so writing this Logging logic in every class or at every
method will be bad approach. To deal with this Aop provides very suitable way-
Now to execute Target and Aspect(Cross cutting logic or cross cutting concerns or secondary
logic) together we have to give both to the Aop. Aop will take it and weaved both to generate
proxy at run-time(Spring supports both static weaving and dynamic weaving but on integration
with AspectJ it supports static Weaving only).
After generating the proxy it gives its reference to programmer.
Let’s write weaving class
Weaving class
Class Test
{
public void main (String[] args)
{
proxyFactory pf=new ProxyFactory();
Pf.setTarget(new Calculator);
Pf.addAdvice(new LoggingAdvice);
Calculator proxy=(Calculator)pf.getProxy();
proxy.add(10,20);
}
}
Aop will create the proxy class Calculator$proxy by extending from original target class
(Calculator). It will do for Calculator because initially we have set the target class object as a
calculator. Now Calculator$proxy is the child class of Calculator class so Calculator can hold the
reference of its child class that’s why we have type cast the proxy to Calculator like following in
weaving-
Calculator proxy=(Calculatror)pf.getProxy().
Now Aop will override the add(–)method in Proxy like following-
Class Calculator$proxy extends Calculator
private Object target;
MethodInvocation methodInvocation=new MethodInvocation();
{
public int add(int a,int b)
{
methodInvocation.setThis(target); //Calculator.class
methodInvocation.setArguments(new Object[] {a,b});
methodInvocation.setAdviceChain(adviceChain);
methodInvocation.setMethod(Thread.currentmethod.getStackTrace);
Object ret=methodInvocation.invoke(methodInvocation);
}
}
Class MethodInvocation
{
private Object this;
private Object[] arguments;
private Object args ;
private Object adviceChain;
private Object executingAdvice;
public Object proceed()
{
Return method.invoke(this,args);
}
//Setter
//Getter
}
Now when we call the proxy.add(10,20) instead of going to target class method it will goes to
LoggingAdvice invoke() method in which logging logics are written. It happens because after
weaving we get the proxy and when we call the proxy.add(10,20) control goes to proxy class
add(–) method. AOP will create the proxy class at run time by extending from Target class after
weaving. add(–) method of proxy class is overridden in which invoke method of AroundAdvice
is called by passing all the details of target method.
So when in invoke() method we call method invocation.proceed() it will goes to target class
method and target class will return the value to the invoke method. After finishing the invoke()
method execution it will return the value to the proxy class add method which will finally return
the value to the callee.
Before Advice
Before Advice apply the aspects before the joinpoint. It means before executing the target class
method it will apply the aspects on joinpoint.
Usecase-1 –Auditing
Let’s see an example-
Target class-
Class LoanAprover
{
public boolean approve()
{
return true;
}
}
Now we can see that approve() method is the joinpoint in target class which contains the primary
business. Now we can understand that approving of loan cannot be done by any one so we need
auditing which will keep the records of the user who access the approve() and who try to access
it.
Now we can see Auditing logic is crosscutting logic which is to be used before the execution of
approve() method so we need Before Advice.
Now when we call proxy.approve(), before calling the target class approve() method control will
goes to MethodBeforeAdvice before(Method method,Object[] args,Object target) method. We
can see the details of target class method by using “this” we can perform some auditing
operation. Once the before operation finished control automatically goes to target approve()
method which will execute and returns the value to caller. It will not return to before(—) because
it will not called from there. Target class method will be called automatically by Aop after
finishing the before(—) operation.
AfterReturnning Advice
In this advice method will executes after executing the target class method successfully but
before returning the value to the caller.
Target Class
Class KeyGenerator {
Public int generateKey(int len)
{
if(len<=8)
{
return 0;
}
return 1;
}
Advice Class
Weaving Class
public class Test {
public static void main(String[] args) {
ProxyFactory pf=new ProxyFactory();
pf.setTarget(new KeyGenerator());
pf.addAdvice(new VerifyKeyAdvice());
KeyGenerator proxy=(KeyGenerator) pf.getProxy();
int value=proxy.generateKey(8);
System.out.println(value);
}
}
In this case control comes to the afterReturning (—-) when target class execute normally. If
target class throw any exception then control does not comes to afterReturning(–). After
executing afterReturning (—-) method of VerifyAdvice class return value will automatically
goes to callee. In this case we can abrupt the execution of target class by throwing an exception
in afterReturning (–) method.
Throws Advice
This advice method will be invoked only when the target class method throws an exception.
Target Class
package com.ta.bean;
public class Thrower {
public int throwing(int i)
{
if(i<=0)
{
throw new IllegalArgumentException("In valid Input");
}
else
{
return 1;
}
}
}
package com.ta.bean;
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
public class LoggingThrowsAdvice implements ThrowsAdvice {
public void afterThrowing(IllegalArgumentException iae)
{
System.out.println("Please provide positive value");
System.out.println( new IllegalArgumentException("invalid i"));
}
public void afterThrowing(Method method,Object[] args,Object
target,IllegalArgumentException iae)
{
System.out.println("Please provide positive value");
System.out.println( new IllegalArgumentException("invalid value of i"));
throw new IllegalArgumentException("invalid i="+args[0]+" Please provide positive value to
"+method.getName());
}
}
Weaving Class
package com.ta.test;
import org.springframework.aop.framework.ProxyFactory;
import com.ta.bean.LoggingThrowsAdvice;
import com.ta.bean.Thrower;
public class TATest {
public static void main(String[] args) {
ProxyFactory pf=new ProxyFactory();
pf.setTarget(new Thrower());
pf.addAdvice(new LoggingThrowsAdvice());
Thrower proxy=(Thrower) pf.getProxy();
System.out.println(proxy.throwing(-1));
}
}
In case of throws advice control will comes to this advice method only when target class method
throws exception.When target class throws exception then control comes to the throws advice
method in which we can see the exception thrown by target class method and represent that
exception in end-user understanding format. The ain purpose of the throws advice is to
centralized the error handling mechanism.
Annotation Vs Xml
Annotation and Xml both are meant for providing meta-data or information about our classes or program
to another program or application, so they can start using our classes or program. These are just like
documents which will be read by underlying application such as Servlet container or IOC container.
Annotation is an alternate of xml configuration file. In early days there is only one way to configure the file
which is through xml. There are some problems with xml for which java developers does not want to use
xml.
Disadvantage of XML
1. Xml is verbose:-
It means xml configurations are larger in length. To configure a single class also programmer has to
write too many lines of xml file which is irritating.
2. Xml is to be written in external file. Xml syntax is completely different from java syntax so Java
developer feels that they have been thrown out of java.
3. To configure in xml programmers have to remember all the tags of the xml and the syntaxes
which are large in number. So, java developer feels difficulty in doing this.
4. There is no any intermediate compiler for Xml that’s why configuration can be checked at run time
only after the application is deployed. Now if any exception occurs at run time related to configuration
then it will be very difficult for java developer to identify the exception and fix it. To fix the problem
developers have to stop the server fix the problem redeploy it and restart the server. It kills the
productivity of developer. These are the reasons xml is not suitable for rapid production.
5. There is no strong tools or IDE which helps developer in xml configuration. That is IDE support for
xml is very less.
Due to above reasons java developer starts raising their voices against the xml. To solve all the above
problems Sun Microsystem starts developing an alternate for xml in this way annotations comes into
picture.
Xml Advantage
1. If any run time problems occur due to xml then programmer does not need to make change in the
code just go to external xml configuration file and do the required changes due to which application
does not need to be recompiled, retested and redeployed on server which will prevent extra cost in
developing application.
2. Xml gives the clear picture of the project in one single place. By looking at Xml configuration
programmer can understand the flow of the application.
3. Xml support pojo class appication development. It means when we configure our class in xml
configuration file we not need to extends or implement our classes from other application environment
which are out of jdk environment.
Advantage of Annotation
1. Annotations are very small in length. Programmers have to write one word or one line of
annotation to configure the class.
2. Annotations are Java related classes so java developers feel comfortable in working with
annotations.
4. Annotations are written as part of source code so Java compiler compiles it along with source
code. So any errors in annotations is detected at compile time so developers can fix it at compile time
only. This will speed up the productivity of programmer. Annotations are suitable for rapid production.
5. As annotations are java related classes there are number of IDE which helps programmer in
writing configuration through annotations.
Above are the reasons annotations are used frequently in today’s development.
Limitations of Annotation
1. If developer uses annotation and if any runtime exception occurs due to annotation then again
developer has to make the change in code which will be very costlier.
2. Annotation does not give clear understanding about the flow of control in an application. Any new
developer feels very difficult in understanding it.
3. To get the clear understanding of control flow of application using annotation programmer has to
follow the stander rule. But there is no guarantee that everyone in a team will follow it.
Now we know that both Xml and Annotation has its own advantages and disadvantages then how to
chose one of them in any project. Let’s discuss based on nature of the Project-
In this case if we use annotation it will give more benefit than Xml.
In this way we can see that there are various factors which has to be considered while choosing Xml or
Annotation.
Introduction
The Spring Framework provides a comprehensive programming and configuration model for modern
Java-based enterprise applications – on any kind of deployment platform. A key element of Spring is
infrastructural support at the application level: Spring focuses on the “plumbing” of enterprise applications
so that teams can focus on application-level business logic, without unnecessary ties to specific
deployment environments.
Features
1. Dependency Injection.
As we can see in the architecture core module is the base module. It is the foundation module of
spring. We can use any required module in combination with core module without disturbing the
other module.
To start working with spring developer need not to learn each and every module they can start
working just having the knowledge of required module.
For example we can work on persistence layer by learning spring jdbc module only.
Similarly we can work on crosscutting logic by learning AOP (Aspect Oriented Programming)
module.
MVC module ( Top module in the architecture) can be used with any module to develop web
applications.
Bean Aliasing
In spring when we configure a class as bean we declare an id with which we want to retrieve it back from
the IOC container. Along with id we can attach multiple names to the beans and these names act as alias
names with which can look up the bean from the container. Giving multiple name to a bean is called bean
aliasing.
How does it work
There are two ways to specify the multiple name to bean-
1.Using “name” attribute at <bean> tag level.
2.Using <alias-name> tag.
Let’s see an example-
package com.ba;
class Student
{
private int sid;
private String sname;
public void setSid(int sid)
{
this.sid=sid;
}
public void setSname(String sname)
{
this.sname=sname;
}
public String toString() {
return "Student [sid=" + sid + ",sname=" + sname+"]";
}
}
In the above configuration we can see that <alias-name> is used as a tag outside of <bean> tag.
We can use both name attribute and <alias-name> in spring bean configuration file. Now IOC container
can create the object of Student class by seeing any of the bean name student or student1 or student2 or
student4 or student5.
package com.ba.Student;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class BATest {
public static void main(String[] args)
{
BeanFactory factory=new XmlBeanFactory(new ClassPathResource("application-context.xml"));
Student s=factory.getBean("student",Student.class);
Student s1=factory.getBean(“student1”,Student.class);
Student s2=factory.getBean(“student4”,Student.class);
System.out.println(s);
System.out.println(s1);
System.out.println(s2);
}
}
any of the above configured name of bean can be used it will give same result.
Difference between name and <alias-tag>
When we give comma(,) in case of name attribute between two name it acts as a separator.
While in case of alias if we give comma(,) it will be considered as the part of name.
Example:-
<bean id=”student” name=”student1, student2” class=”com.ba.Student”/>
In this case there are three name of the bean student, student1, and student2. Here comma(,) separate
the name of bean.
<bean id=”student” class=”com.ba.Student”/>
<alias-name=”student” alias=”student3,student4”/>
In this case there are only two names of the bean student and student3,student4. Here commoa (,)
becomes the part of bean name.
When Bean Aliasing is used
Let’s see a real time use case as example:-
We know that Amazon is an e-commerce company. Now amazon is not directly providing services to
customer it has hired courier supplier vendors like BlueDart and Dtdc. Let’s suppose the request for
delivering the item in metro city is taken care by bluedart and for small city or town delivery of items is
taken care by Dtdc. Now suppose for any reason bluedart came to amazon and tells that he will not be
able to deliver the products to customer for one month. In this case amazon will have to face huge loss.
To avoid the loss first he will talk to Dtdc if he can do the work of bluedart also. Dtdc agrees to do that
work.
Now all the request for delivering items comes from metro city for Bludart should go to Dtdc, for this
application developer has to change the code and we know that changing the code is very costlier. To
avoid the change in code spring has given the facility called bean aliasing. Now for one bean we can give
any number of names-
<beans>
<bean id=”amazon” class=”Amazon”>
<property name=”address” ref=”bluedart”>
<bean id=”bluedart” class=”BlueDart”/>
<bean id=”dtdc”class=”Dtdc”/>
<alias name=”dtdc” alias=”bluedart”>
</beans>
By configuring alias name as above whatever be the request comes from amazon to deliver the items it
will goes to Dtdc. In this way we can see without touching the code through alias name we can solve the
problem.
Bean Autowiring
Instead of telling the spring to manage the dependency by writing <property> or <constructor> tag in
spring bean configuration file if we instruct the spring to automatically detect the dependencies and
perform the injection between them then it is called as bean autowiring.
The drawback of autowiring is we don’t have control over which beans has to get injected into what, so it
is least recommended to use in larger application.
It is used only where rapid application development is required.
By default bean autowire is turned off. If we want to use bean autowiring we have to turn on the bean
autowire by using autowire mode.
There are four autowire modes-
autowire=”byName”
=”byType”
=”constructor”
=”autodetect”
Let’s see an example
class Robot
{
private Chip chip;
public void setChip(Chip chip)
{
this.chip=chip;
}
}
class Chip
{
private String manufacturer;
public void setManufacturer(String manufacturer)
{
this.manufacturer=manufacturer;
}
}
Writing the spring bean configuration file for above classes using bean autowiring.
Bean Inheritance
Reusing the features of one bean to another bean is known as bean inheritance.
Bean which is inherited is called as parent bean and bean which is inheriting is called as child bean.
When to use bean inheritance
Let’s suppose there is a Car showroom of Maruti Suzuki in which only one model of car with similar
features are available
class Car
{
private int id;
private String model;
private String manufacturer;
private String fuelType;
private String colour;
public void setId(int id)
{
this.id=id;
}
public void setModel(String model)
{
this.model=model;
}
public void setManufacturer(String manufacturer)
{
this.manufacturer=manufacturer;
}
public void setFuelType(String fuelType)
{
this.fuelType=fuelType;
}
public void setColour(String colour)
{
this.colour=colour;
}
}
In the above configuration we can see that whatever be the configuration properties are in car1 all are
required to car2 except id.
If we are writing the same configuration properties in different-different bean then it leads to duplication of
code which cause many problems like maintenance, hard to read and understand etc.
To solve this problem Bean Inheritance comes into the picture
It gives us the facility of reusing the configuration properties by inheriting the features from parent to child.
How does it Work
1. Setter:-
Spring has given an attribute called “parent”. It is used on < bean> tag level to those beans which
requires the features of another bean.
In the above bean configuration car2 requires the configuration
properties of car1 then car2 has to write parent=”car1” at car2 bean tag level like following-
<bean id=”car2” class=”Car” parent=”car1”/>
When IOC container find the bean definition of car2 it sees the parent
attribute then it goes to the parent bean car1 and copy all the configuration properties from there and
comes back to child bean car2 and placed all that configuration properties in child. In this way it work in
case of setter when all the properties are required by child from parent.
But when the child wants the same property as of parent with different value then child has to write that
property configuration explicitly like following-
In the above bean car2 wants the id property with different id value then it has to write id property
explicitly-
In this case IOC will go to parent but it will not copy the id property because it is already defined in child.
We can say that id property is overridden by child but actually it is not copied from parent and rest of the
configuration properties are copied and placed in child as usual.
Based on property name IOC container will copy the bean from parent to child if same property name
which are defined in child are found in
parent then that configuration property will not be copied.
2.Constructor:-
class Car
{
private int id;
private String model;
private String manufacturer;
private String fuelType;
private String colour;
public Car(int id, String model, String manufacturer, String fuelType, String colour)
{
this.id=id;
this.model=model;
this.manufacturer=manufacturer;
this.fuelType=fuelType;
this.colour=colour;
}
}
Bean configuration:-
<bean id=”car1” class=”Car”>
<constructor-arg value=”10”/>
<constructor-arg value=”swift”/>
<constructor-arg value=”Maruti-Suziki”/>
<constructor-arg value=”Disele”/>
<constructor-arg value=”red”/>
</bean>
<bean id=”car2” class=”Car”>
<constructor-arg value=”20”/>
<constructor-arg value=”swift”/>
<constructor-arg value=”Maruti-Suziki”/>
<constructor-arg value=”Disele”/>
<constructor-arg value=”red”/>
</bean>
Now through constructor also if one bean requires all the features of another bean then we will use bean
inheritance concept by using
“parent” attribute at <bean> tag level like following-
<bean id=”car2” class=”Car” parent=”car1”/>
In this case IOC container will first see the parent attribute in bean definition and go to parent bean and
go to respective bean class and find the injection type if it is constructor injection it will copy all the
configuration properties from parent bean and placed it into child bean. In this case if any extra property
or any existing property value is required is different then it will not work.
In simple word we can say that overriding of properties configuration in case of constructor injection is not
possible by default.
<bean id=”car2” class=”Car” parent=”car1”>
<constructor-arg value=”20”/>
</bean>
The above bean configuration will not work because we are trying to override the existing parent bean id
value using constructor injection.
In this case IOC container will not decide which type of value is going to be override. So IOC container
will consider it as an extra argument for constructor but in our original class we have limited argument so
it will raise exception.
This problem can be solved by using two attribute-
1.”name”
2.”index”
<bean id=”car1” class=”Car”>
Or
<bean id=”car1” class=”Car”>
<constructor-arg value=”20” index=”0”/>
</bean>
<bean id=”car2” class=”Car” parent=”car1”>
<constructor-arg value=”20” index=”0”/>
</bean>
By using above any one configuration method in case of constructor injection of bean inheritance we can
override the existing parent bean value.
Now when object of A is created JVM will automatically calls the default constructor and perform
initialization of object state.We can see that after the birth of object JVM has given a special method
called constructor which is called implicitly by the JVM.In this way JVM has given life cycle management
method to the programmer as constructor for initialize the state of object.
Similarly JVM has also provided finalize() life cycle method to perform some activity like releasing the
state just before the death of the object. Whenever an object becomes dangling pointer it will be available
for the garbage collector. Whenever garbage collector start it will call the finalize method. So, if we want
to perform any activity just before the death of the object we can do it in finalize method.
Now let’s see in case of Servlet
Servlet has given init(ServletConfig config) method as life cycle method to perform initialization of the
servlet and destroy() method to perform some activity just before the death of the object.Now we know
that object of the servlet is created by Servlet container. Servlet container internally takes the help of JVM
to create the object of servlet. Now JVM knows when the servlet object is created and JVM also provide
the life cycle method in form of constructor to initialize the state of servlet and finalize() method to perform
operation just before the death of the servlet object then why additionally servlet has given separate life
cycle method.
Let’s see the answer of the above question-
We can use the constructor and finalize method to manage the life cycle of servlet object but we don’t
know when the object is created and when the object is going to destroy.Only servlet container and JVM
are knowing this.
In case of core java we are holding the reference of object which is created by the JVM. But here Servlet
container holds the reference so when we have to initialize the state of servlet we cannot do it through
JVM provided life cycle method. That’s why to perform the life cycle management like initializing the
Servlet and performing some activity just before the object is going to die servlet has given separate life
cycle method in form of init(cofig) and destroy();
Like the j2ee spring has also given separate life cycle management method.
Let’s see an example-
class Calculator
{
private int a;
private int b;
private int sum;
public Calculator(int a)
{
this.a=a;
sum=this.a+this.b;
}
public setB()
{
this.b=b;
}
//toString
}
Application-context.xml:
<bean id=”caculator” class=”Calculator”>
<constructor-arg name=”a” value=”10”/>
<property name=”b” value=”20”/> </bean>
Now when we call the bean calculator to get the object IOC container will create the object by initializing
the state a and b of the object but programmer also wants to initialize the state sum so he had written the
sum as part of the constructor but it will not get initialized with programmer required outcome. Because
when object is created IOC will call the constructor and inject the value which is passed but at that time
value of b will be initialize to its default value, after constructor injection setter injection will happen then
value of b is initialized to programmer requirements.
1. Configurational approach
2. Programmatic approach
3. Anotational approach
Let’s see how to work with bean life cycle using configurational approach-
class Calculator
{
private int a;
private int b;
private int sum;
public Calculator(int a)
{
this.a=a;
sum=this.a+this.b;
}
public setB()
{
this.b=b;
}
public void init()
{
System.out.println(“init…”);
this.sum=a+b;
}
public void release()
{
System.out.println(“release……”);
}
//toString
}
Application-context.xml:
<bean id=”caculator” class=”Calculator” init-method=”init” destroy-method=”release”> <constructor-arg
name=”a” value=”10”/> <property name=”b” value=”20”/> </bean>
Now test the above application
class Test
{
Public static void main(Strin[] args)
{
BeanFactory factory=new XmlBeanfactory(new ClassPathResource(“application-context.xml));
Claculator calc=factory.getBean(“calculator”Calculator.class);
System.out.println(calc);
}
}
Bean Scopes
Bean scope is a concept which is provided by spring to help the programmer in deciding the number of
objects they want to create for that bean. To specify the scope of a bean we have to use scope attribute
at bean tag level with their modes.
1. singleton – By default every bean declared in the configuration file is singleton. This indicates
when you try to refer the bean through injection or factory.getBean() the same bean instance will be
returned from the core container.
2. prototype- When we declare a bean scope as prototype this indicates every reference to the bean
will return a unique instance of it.
3. request- When we declare a bean scope as request, for every Http Request new bean instance
will be injected.
4. session- For every new Http Session, new bean instance will be injected.
5. Global Session- This globalsession csope has been removed from spring3.0. This is used in
spring MVC portlet framework where if we want to inject bean for a portal session we need to use this
scope.
By the above it is clear that we can use request and session in case of web application. So we will
postpone the discussion on these till Spring MVC. Let’s understand how to use singleton and prototype.
Example
<bean id=”a” class=”A”/>
As we have not specified the scope of the bean then by default its scope is singleton. Now when we
request the IOC container to create the object of bean first it will check it scopes as it is singleton so, it
checks weather the object for that bean is already created or not in IOC contaainer, as we have
requested first time for that bean’s object so it will not be there, then IOC container will create the object
and store it and return to us.
Here we are trying to create two objects of bean but actually a and a1 both are same. when we request
second time for creating the object of bean “a” IOC container will check the scope of bean definition as it
is singleton first it checks weather the object for that bean is available or not in IOC container, as it is
available then IOC container will return the same object to us.
a=a1 (true)
We can specified the singleton scope as below also-
In this case when we request for the bean object the IOC container will check the scope of the bean as it
is prototype it will create the object of that bean and return to us. In this case IOC container will not look
for the availability of the object. It means whenever we are requesting for the bean object it will check the
scope, if scope is prototype then it will create a new object and return to us.
In this case a!=a1
That is a and a1 are two separate object created by IOC container.
a=a1(false)
Now we can say that in case of singleton an IOC container will create only one object per bean definition
and in case of prototype IOC container will create as many objects as it is requested to create.
package com.bs.bean;
public class Toy {
private int id;
private String manufacturer;
public void setId(int id) {
this.id = id;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public String toString() {
return "Toy [id=" + id + ", manufacturer=" + manufacturer + "]";
}
}
O/P
Toy [id=101, manufacturer=Jhon]
Toy [id=101, manufacturer=Jhon]
Toy [id=1012, manufacturer=Jhon]
false
ClassLoader
class A
{
public static void main(String[] args)
{
// some logic
}
}
To run the above program first we have to compile it. Java has provided a tool called javac to
compile the source code.
C:\>Javac A.java
when we compile the ‘A’ class java compiler will generates the dot (.) class file for the source
code which is called as byte code. A.class is generated after compilation. But, byte code is not
directly excutable code on any OS because byte code is not in the form of binary code which is
machine understandable format.
.exe file are directly executable on OS because it is in the form of binary code. To make the byte
code executable java has provided a platform called JVM which will read the byte code and
makes it to the native understanding format.
JVM will initiate when we use a tool called java to run the program. To run the above program
we use following command
C:/>java A
When we write java it launches the JVM. Now in general we call that JVM will go to the
specified class path location of the byte code and reads it and store it in the JVM memory.
But actually JVM will never goes to the specified class path location. To load the class file into
JVM memory java has given some ClassLoader.
When JVM starts it ask one of the class loader to load the class in its memory. JVM ask the class
loader to load the class by giving the class name.
Now class loader will go to the specified class file location and reads it byte by byte and stores it
in JVM memory.
1.Bootstrap classloader
2.Extension classloader
3.System classloader
Bootstrap class loader is also called as ultimate class loader or native class loader. It is the
bootstrap class loader which is different for different OS. It is the bootstrap class loader which
compiled to the native platform which makes our jdk useful for that native platform. It means
actually for different platform bootstrap class loader is different not the JVM.
Bootstrap ClassLoader loads the class from java_home\jdk\jre\lib\rt.jar . In the rt.jar all the core
jdk classes are available . Bootstarp ClassLoader loads the core jdk classes (all predefined
classes in core jdk like String, Object, etc.);
The class loaded by Bootstrap ClassLoader is under the rt.jar which is signed jar if we extract
that jar and do some changes in it and repackage it for loading by Bootstrap ClassLoader then
that classes are not loaded by Bootstrap ClassLoader because it loads that jar only which is
signed by sun microsystem. In that case our jdk will be treted as corrupt jdk and it will not work.
To avoid this problem we have to download another jdk.
Bootstrap ClassLoader is the super class of all the ClassLoader. There is no parent ClassLoader
of bootstrap ClassLoader.
1. Principle of delegation
2. Principle of visibility
3. Principle of uniqueness
Principle of Delegation:-
Principle of delegation tells that when request comes for loading the class to ClassLoader it will
not load the class immediately first it delegates the request to its parent ClassLoader to load the
class if parent ClassLoader has not parent ClassLoader in hierarchy then that parent ClassLoader
will go to the respective location from where it loads the class and checks whether the requested
class is present there or not if it is present then it will load that class otherwise it will deligate that
request to its child ClassLoader. child ClassLoader also do the same if the child ClassLoader has
no further child in hirerachy and class is not loaded then ClassNotFoundException is raised.
c:/> java A
when we write the java launcher it launch the JVM. Now JVM has three ClassLoader to load the
class but JVM always first ask to that ClassLoader which is list in the ClassLoader hirerarchy .
In JDK ClassLoader hierarchy System ClassLoader is list in hierarchy so JVM ask System
ClassLoader to load load the class A. when System ClassLoader gets the request of loading the
class A then it first check in its cache memory is it already loaded or not if not then it delegates
the request to Extension ClassLoader.
Extension ClassLoader will also do the same if not found in cache memory of Extension
ClasssLoader then it delegates the request to Bootstrap ClassLoader.
Bootstrap ClassLoader also search the class A in cache if not found then it will go to the path
from where it loads the class(rt.jar) and search for the class A if it is not found then it send the
request to its child Extesion ClassLoader.
Extension will search the class A in ext folder or system.ext.dirs(system property) if it is found
then it loads the class otherwise it will send the request to its child System ClassLoader.
System CLassLoader go to the specified classpath and reads the class and store it in the JVM
memory. If class is not found at specified classpath resource then it will throw
ClassNotFoundException.
If same class is again asked by JVM to load then System ClassLoader checks in its cache
memory when it found that class it just return that class to JVM. It means a class is loaded only
once by the ClassLoader.
Principle of Visibility:-
Principle of visibility tells that whatever be the functionality is with parent ClassLoader it will be
visible to their children but children functionality will not be visible to parent.
Let’s suppose Class A loaded by Extension ClassLoader then System ClassLoader can see that
class but if System ClassLoader has loaded that class then Extension ClassLoader cannot see that
class.
Let’s see the below example
class A
{
public static void main(String[] args)
{
B b=new B();
b.m1()
}
}
public Class B
{
public void m1()
{
System.out.println(“I m1() IN B”);
}
}
Now we will get two .class file B.class and A.class. Convert the A.class and B.class in to
separate jar files like following
If we put the App2.jar file in java_home\jdk\jre\lib\ext directory and try to run the program from
any directory it will execute .
Suppose App1.jar is in E:\> drive and we try to run the program from D:\> drive like following
To make class B visible to System ClassLoader class B and its function must be public.
Note:- .class file directly copied in ext directory will not work. .class file should be packaged
into jar files and then jar files should be copied in ext directory to work.
Principle of Uniqueness:-
Principle of uniqueness talks about the number of times a class can be loaded by a ClassLoader.
At any point of time a class can be loaded only once by one of the ClassLoader. It means if any
Class loader has loaded a class then no other ClassLoader can load the same class due to
principle of delegation.
Let’s say class ‘A’ is loaded by Extension ClassLoader using the principle of delegation. Now,
again if we wants to load the class ‘A’ JVM will follow the same principle of delegation and give
us same ‘A’ which is loaded by Extension class Loader.
When ClassLoader X loads class ‘A’ it will store it in JVM memory as X.A similarlly
ClassLoader Y will store it in JVM memory as Y.A. It means whenever a ClassLoader Load the
classes it stores it by using namespace concept as ClassLoaderName.className. Now JVM can
differentiate between class ‘A’ loaded by ClassLoader X and ClassLoader Y. JVM will treat both
loaded ‘A’ as two different class.
Dependency Check
We can perform injection in two ways either via setter or constructor. When we apply constructor injection
it is mandatory for us to configure the constructor in spring bean configuration file as
<constructor-arg>. But in case of setter injection it is optional to configure the setter as
<property name>
By default dependency check is disabled in spring for setter. To make setter injection mandatory we have
to enable the dependency check by using an attribute called dependency-check at bean tag level with
different modes.
Three different Modes are –
1. simple
2. object
3. all
class Person
{
private int id;
private Address address;
public void setId(int id)
{
this.id=id;
}
public void setAddress(Address address)
{
this.address=address;
}
}
class Address
{
private String cityName;
public void setCityName(String cityName)
{
this.cityName=cityName;
}
}
Now if we configure the bean like above for the class Person and class Address IOC container will create
the object for ‘Person’ and ‘Address’ because we have applied setter injection which is optional. By calling
the default constructor of ‘Person’ and ‘Address’ Spring will create the object. To make the setter injection
mandatory we have to on the dependency check which is by default off like following-
In this case IOC container will see that dependency is of simple type then it goes to respective bean class
and find the attribute name of primitive type for which setter is defined and comes to the configuration file
and search the property name in bean configuration if it is found then inject the value to the respective
bean otherwise throws an exception.
Note:- In this case IOC will only checks the simple type attributes name for which setter is defined. It does
not consider the object type for which setter is defined or not.
In this case IOC container goes to the respective bean class and finds the name of the object type for
which setter is defined and comes to the configuration file and checks the corresponding name in property
of the bean if found then inject the reference otherwise throws an exception.
Note:- In this case IOC will only checks the object type attributes name for which setter is defined. It does
not consider the simple type for which setter is defined or not.
Note:- In this case IOC will only checks the object type attributes name for which setter is defined and the
simple type attribute name for which setter is defined. It means for both IOC will check the dependency .
Depends On
If a class uses the functionality of of other class inside it, then those classes are directly dependent on
each other. But every class may not directly dependent on other, sometimes there may be indirect
dependency. Let us consider a use case to understand.
We have a class LoanCalculator, it has a method calIntrest to it we pass principle, year, city name as
input. When we call this method it should find the applicable rate of interest for the city we passsed by
fetching it from properties file.
package com.don.bean;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class LoanCalculator {
private Properties props;
public void calIntrest(int principle,int year,String city) throws IOException
{
InputStream is=new FileInputStream(new File("E:/New
folder/EclipseApps/City.properties.txt"));
props=new Properties();
props.load(is);
//giving the city name it will give rate of interest for that city
String roi=(String) props.get(city);
float roIntrest=Float.parseFloat(roi);
System.out.println("Rate of Intrest for"+city+" = "+roIntrest+"%");
float totalIntrest=(principle*year*roIntrest)/100;
System.out.println("Total Intrest = "+totalIntrest);
float totalAmount=principle+totalIntrest;
System.out.println("Total Amount to be paid after 5 years = "+totalAmount);
}
}
package com.don.bean;
import java.io.IOException;
public class CalculatorTest {
public static void main(String[] args) throws IOException {
LoanCalculator lc=new LoanCalculator();
lc.calIntrest(200000, 5,"Hyderabad");
}
}
The problem with the above application is we will have to read the same data repeatedly for every call to
the calInterest(…) method of the LoanCalculator class.
So instead we want to cache the data so that the LoanCalculator now can go and get the data from
cache. So for this when we call calInterest(…) method we will check whether the data is available with
cache or not. If it is not available we will read the city and rate of interest values from properties file as key
and values and place it in properties collection. Now we will store this properties collection into the cache
as shown below-
package com.don.bean;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class LoanCalculator {
private Properties props;
public void calIntrest(int Principle,int year,String city) throws IOException
{
Cache c=Cache.getInstance();
if(c.containsKey("CityRI")==false)
{
System.out.println("CityRI is not avilable");
InputStream is=new FileInputStream(new File("E:/New
folder/EclipseApps/City.properties.txt"));
props=new Properties();
props.load(is);
c.put("CityRI",props);
String roi=(String) props.get(city);
System.out.println("Rate Of Intrest : "+roi+"%");
}
else{
String roi=(String) props.get(city);
System.out.println("Rate Of Intrest : "+roi+"%");
}
}
public void roiDemo(String city)
{
System.out.println("I M getting the file from Cache");
String roi=(String) props.get(city);
System.out.println("Rate Of Intrest : "+roi+"%");
}
}
Now the problem is here the city and rate of interest values may not only required for LoanCalculator
there may be several other classes in the application want to read the data from the Cache. So, we need
to write the logic for checking the data is available in Cache or not if not load the data into Cache and use
it.
So, we end up in duplicating the same logic across various places in the application. Instead we can write
the logic for populating the data into Cache in Cache constructor, because constructor of the Cache will
be called only once as it is singleton and we need to read the data only once, so the better place to write
the logic for populating is in constructor of the class as shown bellow-
Cache
package com.don.bean;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
public class Cache {
private static Cache instance;
private Map<String,Object> mapdata;
private Properties props;
private Cache()
{
mapdata=new ConcurrentHashMap<String, Object>();
//write the logic for reading the data from properties file
InputStream is=new FileInputStream(new File("E:/New
folder/EclipseApps/City.properties.txt"));
props=new Properties();
//put that file into properties collection
props.load(is);
//store collection into datamap
mapdata.put("CityRI",props);
}
public static synchronized Cache getInstance() {
if(instance==null)
{
instance=new Cache();
}
return instance;
}
public boolean containsKey(String key) {
return mapdata.containsKey(key);
}
public Object get(String key)
{
return mapdata.get(key);
}
public void put(String CityRI, Properties props) {
mapdata.put(CityRI,props);
}
}
now the problem with the above code is Cache is exposed to the details of the source from where the
data is coming from. Due to which any changes to underlying source again will affect the cache.
Instead we should never write the logic for populating the data into cache rather we should write that logic
in separate class called CacheManager. CacheManager is one which is responsible for reading the data
from underlying source system and massaging the data and storing the data into Cache.
CacheManager
package com.don.bean;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class CacheManager {
private Cache cache;
private Map<String,Object> mapData;
private static CacheManager instance;
private Properties props;
private Object object;
private CacheManager() throws FileNotFoundException, IOException
{
mapData=new HashMap<String, Object>();
cache=Cache.getinstance();
//write the logic for reading the data from properties file
InputStream is=new FileInputStream(new File("E:/New
folder/EclipseApps/City.properties.txt"));
props=new Properties();
//put that file into properties collection
props.load(is);
//store collection into datamap
mapdata.put("CityRI",props);
cache.put("CityRI",mapData);
}
public static synchronized CacheManager getInstance() throws FileNotFoundException,
IOException
{
if(instance==null)
{
instance=new CacheManager();
}
return instance;
}
}
Again the problem with the above code is the data comes from several source systems again we will write
multiple access related logic in one single class. This may become complicated and dfificult to manage
and modify.
Instead write the logic for reading the data from source system in Accessor class. Now CacheManager
will talk to Accessor in retrieving the data and populating into cache.
package com.don.bean;
import java.io.FileNotFoundException;
import java.io.IOException;
public interface IAccessor {
Object getData() throws FileNotFoundException, IOException;
}
package com.don.bean;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class Accessor implements IAccessor {
private Properties props;
@Override
public Object getData() throws IOException
{
InputStream is=new FileInputStream(new File("E:/New
folder/EclipseApps/City.properties.txt"));
props=new Properties();
props.load(is);
return props;
}
}
package com.don.bean;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class CacheManager {
private Cache cache;
private IAccessor accessor;
private Map<String,Object> mapData;
private static CacheManager instance;
private Object object;
private CacheManager() throws FileNotFoundException, IOException
{
mapData=new HashMap<String, Object>();
accessor=new Accessor();
object=accessor.getData();
cache=Cache.getinstance();
cache.put("CityRI",object);
}
public static synchronized CacheManager getInstance() throws FileNotFoundException,
IOException
{
if(instance==null)
{
instance=new CacheManager();
}
return instance;
}
}
So here the LoanCalculator and cacheManager are indirectly dependent on each other. Before the
LoanCalculator gets created, always the CacheManager has to be created first. This is called creational
dependencies these can be managed using depends on as shown below-
package com.don.accessor;
import java.io.IOException;
public interface IAccessor {
}
package com.don.accessor;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class CityRateOfIntrestPropertiesAccessor implements IAccessor {
private Properties props;
public Object getData() throws IOException {
props=new Properties();
InputStream is=new FileInputStream(new File("E:/New
folder/EclipseApps/City.properties.txt"));
props.load(is);
return props;
}
}
package com.don.util;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.don.accessor.IAccessor;
public class CacheManager {
private IAccessor accessor;
private Cache cache;
private Map<String,Object> mapData;
public CacheManager(Cache cache,IAccessor accessor) throws IOException
{
this.cache=cache
this.accessor=accessor;
mapData=new HashMap<String, Object>();
load();
}
public void load() throws IOException
{
Object data=accessor.getData();
cache.put("CityRI",data);
}
}
package com.don.util;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Cache {
private Map<String,Object> mData;
public Cache()
{
mData=new ConcurrentHashMap<String,Object>();
}
public void put(String key, Object data) {
mData.put(key,data);
}
public Object get(String key)
{
return mData.get(key);
}
public boolean containsKey(String key)
{
return mData.containsKey(key);
}
}
package com.don.bean;
import java.util.Properties;
import com.don.util.Cache;
public class LoanCalculator {
private Cache cache;
private Object obj;
Properties props;
public void calIntrest(long principle,int tenure,String city) throws Exception
{
obj=cache.get("CityRI");
if(obj==null)
{
throw new Exception("Cache is not initialized");
}
if(cache.containsKey("CityRI")==false)
{
throw new Exception("Invalid Key");
}
props=(Properties)obj;
String roi=props.getProperty(city);
float rate_of_intrest=Float.parseFloat(roi);
System.out.println("Rate Of Intrest for "+city+"= "+rate_of_intrest);
float totalIntrest=(principle*tenure*rate_of_intrest)/100;
System.out.println("Total Intrest = "+totalIntrest);
float totalAmount=principle+totalIntrest;
System.out.println("Total amount to be paid after "+tenure+" year = "+totalAmount);
}
public LoanCalculator(Cache cache) {
super();
this.cache = cache;
}
}
package com.don.test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import com.don.bean.LoanCalculator;
public class DONTest {
public static void main(String[] args) throws Exception {
BeanFactory factory=new XmlBeanFactory(new ClassPathResource("com/don/common/application-
context.xml"));
LoanCalculator lc=(LoanCalculator)factory.getBean("loanCalculator");
lc.calIntrest(20000,5,"Hyderabad");
}
}
Internationalization
Internationalization is the process through which application will display the content specific to the locale
from where user is accessing the application.
To make any application fully Internationalized we have to work on three areas-
1. Content Internationalization
3. NLS programming
When we are storing any data in file or data base we store it with some character encoding like ASCII or
UTF-8.
To read the same content from the file or data base we have to read it with same encoding which are
used in storing the data otherwise we will get a junk data.
ASCII character set use 8 bytes of character set to display the character.
That is total 256 character can be displayed.
When our data is saved with ASCII character set then our data reader application has also to use ASCII
character set to read it.
We know that data are stored in binary format and ASCII character set reads the data by grouping 8 bits.
Let’s see how to read 5 in ASCII-
Binary form of 5 is 101
It is stored in database as bits- 00000101
Now to read the data through ASCII it will group the 8 bits together and then form the corresponding
character.UTF-8 is also a character set encoding it stores and read the data by grouping 16 bits. This
character set will store 32768 bits so it will support maximum forms of data. Today UTF-8 is used very
frequently.
NLS programming is known as native language support programming.
To read the data specific to locale we have to develop NLS programs for reading that data. NLS program
use the same character set for reading the data which is used in storing the data.
Here we are just doing content internationalization.
Internationalization is supported by J2EE programming.
But there are lots of problem with it.
Let’s discuss the internationalization in J2EE.
Let’s suppose we have to display “Welcome to Internationalization” in different languages specific to
locale.
To display the message we cannot hard code it in JSP instead of we create the properties file for different
locale and store the message in it as a key and their respective language format message as a value.
Let’s suppose
MessageBundle.properties
Greeting=Welcome to java internationalization
MessageBundle_fr_FR.properties
Greeting=Bienvenue à l’internationalisation java
JSP :-
<html>
<head/>
<body>
<%
InputStream is=new FileInputStream(new File(“path where file is stored”));
Properties props=new Properties();
Props.load(is);
String message=Props.getProperty(“key”);
System.out.println(message);
%>
</body>
In the above program we have to write the logic for reading the file and storing it in properties collection
and then we will retrieve the message according to locale.
But we do not have to write all the logic because J2EE has provided a class called ResourceBundle
which will read the properties file and store it in properties collection based on base name and the locale
we have specified.
To read the MessageBundle_fr_FR.properties file we have to pass the base name of properties file that is
MessageBundle and we have to set the locale as fr_Fr then it will read the message in French.
<%
ResourceBundle bundle=ResourceBundle.getBundle(“MessageBundle”,Locale.France);
System.out.println(bundle.getString(“Greeting”));
%>
O/P
Bienvenue à l’internationalisation java
getBundle(“baseName”,locale) when we pass the baseName and locale it goes to the properties file
respective to the locale if it is not found then it will throws an exception.
In the above application we have to write the servlet logic in JSP page it means JSP programmers have
to know the servlet programming also it seems to be difficult.
To solve this problem we should not write the servlet code in JSP to use internationalization, we should
write a servlet class and write the logic in service method for reading the properties file specific to the
locale and make it as properties collection form and pass it to the JSP page. To get the request and
process it in JSP page using JSTL tag
<c:out>.
But now in an application we above to write many servlet which will do the same then we have to
duplicate the logic in all the servlet which will create big problems like if any changes made in the
properties file names then we have to modify the entire logic in each and every servlet. It creates big
maintenance problem.
To solve the above problem we can use Filter. Filter is used to perform preprocessing and postprocessing
operation on resource like HTML or JSP or Servlet.
Now we write the logic for reading the properties file specific to the locale using ResourceBundle class in
doFilter() method and then forward to the resource(JSP).
When request comes first doFilter() method of Filter is invoked then according to the locale of the
client(comes with browser) Filter will perform the operation and forward the request to resource.
Now by applying the above approach we can eliminate the duplication of code among servlets.
Now we can use session object and CacheFilter to make the filter more efficient.
Now we have to create one ResouceBundle object for reading one properties file for one locale. It means
for every properties file specified to the locale we have to create ResourceBundle. It is the biggest
problem now.
To solve this problem Spring gives ResourceBundleMessageSource class which will read the entire
properties file at once and stores it in properties collection.
By using ResourceBundleMessageSource for each and every properties file we not need to create
separate ResourceBundleMessageSource, one ResorceBundleMessageSource will read the entire
properties file.
There are two properties in ResourceBundleMessageSource class basename(for reading one property
file) and basenames(for reading multiple property file) which are of type List<String>.
We will pass the base name of the properties file as a value.
Let’s see an example-
Properties files-
MessageBundle.properties
Greeting=Hello Jhon
MessageBundle_fr_FR.properties
Greeting=Hello Jhon(french)
MessageBundle_ja_JP.properties
Greeting=Hello Jhon(Japnese)
O/P
Hello Jhon(French)
getMessage(“String key”,object[], locale) method will take three
parameter based on key and locale it will gives us out put if we use locale as JAPAN in above
getMessage() method then it will gives
Hello Jhon(Japnese) as O/P
Now we can see that for different Properties file specific to the locale we have not to create multiple
ResourceBundleMessageSource object only one object is required.
Now if any changes made in the properties file while running the application then
ResourceBundleMessageSource will not show that changes because it will read the file in starting and
does not reloade it while running the application. This is the problem with
ResourceBundleMessageSource.
To solve the above problem spring has given one more class called
ReloadableResourceBundleMessageSource. It will reload the properties file at every time interval
specified in it. So by using this run time changes made in properties file will also be seen.
We know base class reference can hold the object of derived class.
Now if we use MessageSource interface in our class then spring will violate its one of the biggest principle
called non-invasive.
Hence we can see that BeanFactory will not support the internationalization.
In spring we can create IOC container in two ways-
1. BeanFactory
2. ApplicationContext
BeanFactory
BeanFactory factory=new XmlBeanFactory(new ClassPathResource(“application-context.xml”));
When we create IOC container with BeanFactory first ClassPathResource goes to the physical Xml bean
configuration file it reads that file and store it in resource object and gives it to XmlBeanFactory.
Now XmlBeanFactory will check the xml file is welformed or not then it check its validation if both are
passed then it will create an empty IOC container and place the xml file as in memory metadata.It will
starts creating the object of bean when the bean is requested.
That’s why it is called as lazy initializer.
ApplicationContext
ApplicationContext context=new ClassPathXmlApplicationContext(“application-context.xml”);
When we create the IOC container with ApplicationContext first ClassPathXmlApplicationContext will go
to the physical xml bean configuration file reads it and load it by creating IOC container as in memory
metadata. Now ApplicationContext will read the bean definition one by one and creates the object for the
bean whose scopes are singileton. It means before referring to the bean whose scopes are singileton it
will create the object.
That’s why it is called as eagerly initializer.
BeanFactory VS ApplicationContext
As ApplicationContext creates the object while creating the IOC container it will go through all the bean
definition so once it creates the object it will not throw exception at run-time.
While BeanFactory will only checks welformness and validation.
As it does not create the object while creating the IOC container it does not go through the bean definition
without any request so when we request for bean object then it will reads the bean definition and creates
the object if bean definition has some error then it will throw run-time exception.
It means ApplicationContext IOC container gives prof that it will not throw exception while running. If any
error exist in bean definition then it will not create the IOC container.
Spring will support the internationalization through ApplicationContext. It contains the
ResourceBundleMessageSource and ReloadableResourceBundleMessageSource.
Spring has provided method called getMessage(—) which will read the message through
ApplicationContext like following-
Place holder
Now we can use place holder in properties file like following:
Error.properties
firstName={0} should cannot be empty
ApplicationContext context=new ClassPathXmlApplicationContext(“application-context.xml”);
context.getMessage(“firstname”,new object[]{“First Name”},Locale.getDefault());
O/P
First Name cannot be empty
We can initialize the place holder at run time through object array.
Now class A wants the functionality of B then there are two ways to get it one is inheritance and
another one is composition. Composition is recommended so attribute of type B is declared in
class A. Now A should not create the object of B because it will get tightly coupled with B. So
we should tell the spring about our classes through spring bean configuration file by declaring A
and B as bean
class Circle
{
public final float pi=3.14;
public float radius;
public float area()
{
return pi*radius*radius;
}
}
Now let’s suppose there are multiple circles like C1,C2,C3. All circles have different radius.Now
I want area of C1 whose radius is 5cm
class C1
{
private Circle circle1;
public void getArea()
{
circle1=new Circle();
circle1.radius=5;
float area=circle1.area();
System.olut.println(area);
}
}
class C2 {
private Circle circle2;
public void getArea()
{
circle2=new Circle();
circle2.radius=10;
float area=circle2.area();
System.out.println(area)l;
}
}
Now in the above application we can see that we require different objects for different Circles
like C1 and C2 because radius of different circle will be different.Now for calculating the area of
circle all user needs separate object.Now let’s see if we permit only one object of Circle to all the
user then what happens
Now let’s suppose when C1 starts executing after setting the value of radius as 5 with circle
object thread switching happens and C2 get chance to execute. C2 set the value of radius as 10
and execute after C2 execution C1 again starts to execute from where it has left the execution
means after setting the value of radius as 5 but it’s value is overridden by C2 so when it execute
it gives wrong results for him.It means data inconsistency will happen if we use only one object
of a class which contain non-sharable attribute.For sharable attribute it is fine to use one object
like in above application pi value is same for all the circle. It means it is common to all then it
should be declared as attribute.
Now in the above configuration file we can see that scope of C1 is singleton by default and scope
of Circle is prototype. We need multiple objects for the Circle so we have declare its scope as
prototype.Now let’s create the bean factory and calls the bean
This time after checking the scope of bean spring will goes to IOC container and checks weather
object of c1 is there or not as it is there IOC container will just return it to us. It will not create
the new object. It means c==c1 is true. Now in this case Circle is also behaving like singleton but
actually its scope is prototype. By doing this we are forced to use same object of Circle which
leads to data inconsistency. Now in this situation we should tell the spring to not perform the
dependency injection.To solve this problem spring has given the concept called lookup-method.
Now let’s see another example
Now create the IOC container and call the bean in test class
Now when factory.getBean(“radio”) is called spring will go to the IOC container and checks the
bean Definition in metadata, as it is there it reads the bean definition while reading it encounter
that Radio is an abstract class. But we have written an attribute called lookup-mehod in the radio
bean configuration. Now spring will understand that I have to lookup for the method whose
name is lookupReciver and goes to the bean called reciver10Hz. Create the object of bean
reciver10Hz. Now created bean is given to the lookupReciver by creating the object of Radio.
Note:-IOC container will only create the object of abstract Class (bean) when we have
configured lookup-method attribute.
Actually IOC container will do the following when it is asked for lookup-method injection.
First it will create a proxy class like following-
class Radio$Proxy extends Radio
{
public IReciver LookupReciver
{
IReciver reciver=factory.getBean(“reciver10Hz”,IReciver.class);
return reciver;
}
}
While overriding the LookupReciver method it will call the bean definition of those bean which
are configured in configuration file bean=”reciver10Hz” now object of bean reciver10Hz is
created and stored in the reference reciver.
Now IOC will create the object of Radio$Proxy class and store it as radio in the IOC container
and return its reference to us. Now when we call the listen method of Radio class with reference
radio actually we are calling the Radio$Proxy class method listen. In this way Method injection
is actually processed.
Method Replacement
Replacing the logic of existing method with new logic without modifying the existing method
logic is known as Method Replacement. It can be done by overriding the existing method with
new logic.
class A
{
public void m1()
{
System.out.println(“I M m1 in A”);
}
}
class B extends A
{
public void m1()
{
System.out.println(“I M m1 in B”);
}
}
Now by getting the reference of B any one can use the change logic of m1(). But in real time
environment there is no guarantee that change logic will full fill the requirement, then returning
to the old logic again we have to pass the old class refrence it means again we have to go through
all the testing process which is costlier. It means to get the old results again we are spending time
and money which seems to be very bad approach. To solve the above problem spring comes with
a concept called Method Replacement.
class Planfinder
{
public String[] findPlans(int age,String gender,int premium,String coverage)
{
return new String[]{“pl1”, ”pl2”};
}
}
Now let’s suppose there is some bug in the above method logic. But it is prohibited from
modifying that logic to make the method bug free due to some business purpose. In this case we
can use method overriding concept but again it will become more expensive modification if new
logic also have bug. In this situation we should use method replacement concept of spring. To
use the method replacement first we have to create a replacer class by implementing from
MethodReplacer interface provided by spring. Now we have to override the reimplement()
method bypassing same method name which is to be replaced, the arguments which is with that
method and the target object.
Now to tell the spring about our classes and the method which is to be replaced we have to
configure the bean file
class Test
{
public static void main(String[] args)
{
BeanFactroy factory=new XmlBeanFactory(new ClassPathResource(“application-context.xml”));
PlanFinder pf=(PlanFinder)factory.getBean(“planFinder”);
Pf.findPlan(20,”male”,2000,”in_coverage”);
At run time Spring will create the PlanFinder$proxy class by extending from PlanFinder.
Now override the findPlan(–) method.
Since it is created by IOC container at run time then IOC container will have reference of it as
factory, so in the findPlan () overridden method it will create the object of FindPlanReplacer
bean by calling factory.getBean(“findPlanReplacer”) and by getting the object of
FindPlanReplacer it will call the reimplement(–) method because this method is known to IOC
container because we have implemented FindPlanReplacer from MethodReplacer interface.
Now reimplement(–) will return the plan by processing it based on the type. At last findPlan(–)
method of PlanFinder$proxy return the plan to our class. Now when we invoke the findPlan()
method with the object returned by IOC it will actually call the findPlan() method of
PlanFinder$Proxy class because actually spring will create the object of PlanFinder$proxy class
and store it in IOC container with planFinder name. so when we request it will give the reference
of PlanFinder$Proxy class not that of PlanFinder.
In this way we can see that without touching the logic of findPlan(–) method spring has replaced
that method with our method logic by using Method Replacement technique.
Property Editors
In spring when we configure a class as spring bean, we can inject all the dependent attributes of
the bean via setter or constructor injection. Let’s see in details-
class Person
{
private int id;
private URL url; //object type
private Date date; //object type
private File image; //object type
public void setId(int id)
{
this.id=id;
}
public void setUrl(URL url)
{
this.url=url;
}
public void setDate(Date date)
{
this.date=date;
}
public void setFile(File image)
{
this.image=image;
}
Now in the above configuration file we can see that to inject the value of object type of URL,
File, Date we have to configure the bean for that type.
In this way we can see that to inject the value of object type we have to write more number lines
in configuration file which is time taking
and it will be very difficult in managing it. It also makes the configuration file complex in
understanding.
To avoid these problems spring has provided some PropertyEditor for primitive types and for
frequently use object type like File, Date, URL etc.
It means we can configure the Person class as follows –
<bean id=”person” class=”Person”>
<property name=”id” value=”105”/>
<property name=”url” value=”https://www.google.com/”/>
<property name=”date” value=”14/11/1990”/>
<property name=”image” value=”d:/vv.jpg”/>
</bean>
Now we can see that we have injected the primitive type as well as object type directly as a value
in Person.
Let’s see how spring will inject these values.
Whenever we pass the value spring will take it as String by default.
Now when we pass the value 105 to id which is of integer type the IOC container will first goes
to the respective bean class and checks the attributes type as it is primitive type it goes to the
PropertyEditor Registry inside the IOC container looks for the Primitive type PropertyEditor
object and calls the appropriate PropertyEditor ( logic for converting the value from String type
to primitive type is written ).
Now PropertyEditor will set the converted value to that class in this way IOC container will
inject that value.
Similarly for Object type like Date, URL, File when we pass the value directly the IOC container
take it as String and goes to the attribute and match the type of attribute as it does not match
because attributes are of Object type then IOC container will go to the PropertyEditor registry
and looks for the PropertyEditor object and
then calls the appropriate PropertyEditor in which logic for converting the String type to the
appropriate object type is written. PropertyEditor will set the converted value in this way IOC
container will inject the value.
Now we can see that by providing PropertyEditor for Primitive type and for some Object type it
has helped a lot in minimizing the configuration file.
But for injecting any object type spring has not given the PropertyEditor.
Now to inject our own object type we have to configure that object type as bean. This will leads
to a large configuration file.
Now to solve this problem Spring has given the facility to create CustomPropertyEditor. To
create CustomPropertyEditor we have to extend CustomPropertyEditor from
PropertyEditorSupport class and we have to override setAsText(String value) method. In the
setAsText() method we will write the logic for converting the value to required type and pass it
as argument to the setValue() method.
class A
{
private B b;
public void setB(B b)
{
this.b=b;
}
}
class B
{
private int I;
public B(int i)
{
this.i=i;
}
Application-context.xml
<bean id=”a” class=”A”>
<property name=”b” value=”10”/>
</bean>
class Test
{
public static void main(String[] args)
{
BeanFactory factory=new XmlBeanFactory(new ClassPathResource(“Application-context.xml”));
A a=(A)factory.getBean(“a”);
Now when we call getBean(“a”) then factory will go to the IOC container and looks for the bean
definition of “a” inside the metadata
as it is found then it checks the scope of the bean as it is singleton it checks wether the object for
the given bean is already created or not as it is not created because it is requested for first time so
it will start creating the object while creating the object it see the property attribute name and
value for that attribute it goes to the bean class and finds the attribute by its name try to inject
that value in setter of that attribute. But for this it will match the attribute type and the value type
which is to be injected as value is of String type and attribute is of Object type it will not inject.
Now IOC container will go to the PropertyEditor Registry where all predefined PropertyEditors
are stored. It starts searching by for the PropertyEditor whith the object type which is to be
injected. As it is not found spring will through an exception as no appropriate convertor or
strategy found.
Now to make our CustomPropertyEditor registered inside the propertyEditorRegistry in IOC
container we need registry.
To get the registry we have to implement our registrar class from spring given interface called
PropertyEditorRegistrar and we have to override the a method called
registerCustomEditors(PropertyEditorRegistry registry).
Now in overriding the above method we have to register our CustomPropertyEditor by calling
registerCustomEditor() through registry.
Class CustomPropertyEditorRegistrar implements PropertyEditorRegistrar
{
Public void registerCustomPropertyEditors(PropertyEditorRegistry registry)
{
registry.registerCustomEditor(B.class,new CustomPropertyEditor());
}
}
While calling the registerCustomEditor() we have to pass the type of object in which value is to
be converted and the CustomPropertyEditor object.
In the above registrar class we have to register the CustomPropertyEditor in the
PropertyEditorRegistry of IOC container.
BeanFactory has not any method for modification in IOC container. To modify the IOC
container there is an interface Called ConfigurableListableBeanFactory which has method to
make the internal changes in IOC container. addPropertyEditorRegistrar() is such a method
which can register the CustomPropertyEditorRegistrar as an object in PropertyEditor Registry.
To use that method we have to type cast the factory to ConfigurableListableBeanFactory like
following-
BeanFactory factory=new XmlBeanFactory(new ClassPathResource(“application-context.xml”));
ConfigurableListableBeanFactory clbf=(ConfigurableListableBeanFactory) factory;
Clbf.addPropertyEditorRegistrar(new CustomPropertyEditorRegistrar);
The journey to spring annotation has been started in spring 2.0. It has added @Configuration,
@Required, @Repository annotations. Along with this it added support to declarative and annotation
based aspectj AOP.
In spring 2.5 it has added few more annotations @Autowired, @qualifier and @Scope. In addition it
introduced stereotype annotations @Component, @Controller and @Service.
In Spring 3.0 few more annotations has been added like @Lazy, @Bean, @DependsOn etc. In addition
to spring based metadata annotation support, it has started adoption JSR-250 Java Config project
annotations like @PostConstruct, @Predestroy, @Resource, @Inject and @Named etc.
Let’s explore the above annotations with example-
AppConfig.java
@Configuration
public class AppConfig {
@Bean
public MyService myService()
{
reutn new MyService();
}
}
MyService.java
public class MyService {
public void doSomething()
{
System.out.println("Some thing is done here");
}
}
Now while creating the core Container, instead of using BeanFactory, we need to create it using
AnnotationConfigApplicationContext by passing the configuration class as input.
ConfigurationTest.java
public class ConfigurationTest {
public static void main(String[] args)
{
ApplicationContext ctx=new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService=ctx.getBean(MyService.class);
myService.doSomething();
}
}
In spring 2.0, it has introduced an annotation @Required and dependency check has been completely
removed in 2.5. Using @Required annotation we ca make, a particular property has been set with value
or not.
Person.java
import org.springframework.beans.factory.annotation.Required;
public class Person {
private int id;
private String name;
@Required
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "Person [id=" + id + ", name=" + name + "]";
}
}
We can use @Required on a setter level to mark it as mandatory. Simply using @Required annotation
will not enforce the property checking, we also need to register an
RequiredAnnotationBeanPostProcessor in the configuration file as shown below
application-context.xml
<beans>
<bean id="person" class="com.anno.required.Person">
<property name="id" value="101"/>
<property name="name" value="Jhon"/>
</bean>
<context:annotation-config/>
(OR)
<bean
class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
</beans>
RequiredTest.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Requiredtest {
public static void main(String[] args) {
ApplicationContext context=new
ClassPathXmlApplicationContext("com/anno/required/annotation-context.xml");
Person person=(Person)context.getBean("person");
System.out.println(person);
}
}
In annotation based approach we can can use @Autowired at four different level in a class-
1. Attribute level
2. Setter Level
3. Constructor Level
4. Arbitrary method level
Attribute Level
Robot.java
package com.ano.autowire;
import org.springframework.beans.factory.annotation.Autowired;
public class Robot {
//@Autowired annotation is used at attribute level
@Autowired(required=false)
private Sensor sensor;
public void initialize(Sensor sensor)
{
this.sensor=sensor;
}
public String toString() {
return "Robot [sensor=" + sensor + "]";
}
}
Setter Level
Robot.java
package com.ano.autowire;
import org.springframework.beans.factory.annotation.Autowired;
public class Robot {
private Sensor sensor;
//@Autowired annotation is used at Setter level
@Autowired(required=false)
public void setSensor(Sensor sensor)
{
this.sensor=sensor;
}
public String toString() {
return "Robot [sensor=" + sensor + "]";
}
}
Constructor Level
Robot.java
package com.ano.autowire;
import org.springframework.beans.factory.annotation.Autowired;
public class Robot {
private Sensor sensor;
//@Autowired annotation is used at Constructor level
@Autowired(required=false)
public Robot(Sensor sensor)
{
this.sensor=sensor;
}
public String toString() {
return "Robot [sensor=" + sensor + "]";
}
}
If there are more than one constructor then we can annotate only one constructor
with@Autowired(required=”true”) and remaining constructor should be annotated
with@Autowired(required=”false”).
Arbitrary method level
Robot.java
package com.ano.autowire;
import org.springframework.beans.factory.annotation.Autowired;
public class Robot {
private Sensor sensor;
//@Autowired annotation is used at Arbitrary method level
@Autowired(required=false)
public void initialization(Sensor sensor)
{
this.sensor=sensor;
}
public String toString() {
return "Robot [sensor=" + sensor + "]";
}
}
Sensor.java
package com.ano.autowire;
public class Sensor {
private String type;
public void setType(String type) {
this.type = type;
}
public String toString() {
return "Sensor [type=" + type + "]";
}
}
application-context.xml
<beans>
<bean id="robot" class="com.ano.autowire.Robot"/>
<bean id="sensor" class="com.ano.autowire.Sensor">
<property name="type" value="Infrared"/>
</bean>
<context:annotation-config/>
(OR)
<bean
class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
</beans>
Robot.java
package com.annon.qualifier;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Robot {
private Chip chip;
@Autowired
@Qualifier("myChip2")
public void setChip(Chip chip)
{
this.chip = chip;
}
public String toString()
{
return "Robot [chip=" + chip + "]";
}
}
Chip.java
package com.annon.qualifier;
public class Chip {
private int id;
private String manufacturer;
public void setId(int id)
{
this.id = id;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public String toString()
{
return "Chip [id=" + id + ", manufacturer=" + manufacturer + "]";
}
}
application-context.xml
<beans>
<bean id="robot" class="com.annon.qualifier.Robot"/>
<bean id="chip1" class="com.annon.qualifier.Chip">
<property name="id" value="10"/>
<property name="manufacturer" value="Intel"/>
<qualifier value="myChip1"/>
</bean>
<bean id="chip2" class="com.annon.qualifier.Chip">
<property name="id" value="20"/>
<property name="manufacturer" value="ADM"/>
<qualifier value="myChip2"/>
</bean>
<context:annotation-config/>
</beans>
In the above Robot class only the bean whose qualifier value=”myChip2” will be injected into Robot class
chip attribute. In this way indirectly by using @Qualifier we able to perform “byname” injection.
Working with stereotype annotations
In addition to @Repository annotation from Spring 2.5 we have three more annotation by which it can
make a class as spring bean. It means there are four stereotype annotations. They are-
1.@Component:- This is more generic stereotype annotation to manage any component by spring,
whereas other annotations are specialized for specific use cases.
2.@Repository:- This is used for exposing the DAO classes as spring bean.
3.@Service:- The service layer classes are annotated with this annotation to expose it as spring bean.
But, in current release of the spring there is no impact of using it other than exposing that class as spring
bean.
4.@Controller:- When we mark the class by using this annotation then it will be exposed as spring MVC
Controller to handle form submissions.
In spring Core/Spring jdbc applications we can use @Component, @Service or @Repository where as
@Controller can be used only in a Spring MVC application.
Toy.java
package com.anno.stereotype;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("toys")
public class Toy {
public void play()
{
System.out.println("paly Music..");
}
}
In the above application instead of @Component we can use @Repository or @Service where there will
no effect on end result. Now by annotating the “Toy” with@Component(“toys”) it will be exposed as spring
bean with the id “toys”.
By default Spring will take the class name as id of the bean. Here, we have specified “toys” in annotation
itself that’s why it will take “toys” as bean id.
Now in order to detect the stereotype annotations we need to use the tag <context:component-scan base-
package=”Pakage Name Of The Class”/> in spring bean configuration file as shown below.
application-context.xml
<beans>
<context:component-scan base-package="com.anno.stereotype"/>
</beans>
StereotypeTest.java
package com.anno.stereotype;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class StereotypeTest {
public static void main(String[] args) {
ApplicationContext context=new
ClassPathXmlApplicationContext("com/anno/stereotype/application-context.xml");
Toy toy=(Toy)context.getBean("toys");
Toy toy1=(Toy)context.getBean("toys");
toy1.play();
System.out.println(toy1==toy);
}
}
Singleton
Singleton class:-
Any class whose only one object can be created by other class is known as singleton class.
(OR)
A class which permit only one object of its class to other class is known as singleton class.
Let’s suppose there is a class A
class A
{
}
And class B
class B
{
}
Now ‘A’ wants to be called as singleton class and ‘B’ wants to use the functionality of class A.
In this case ‘A’ has to tell the ‘B’ to create only one object of him, but there is no guarantee that
B will create only one object of ‘A’, so in this case A should not allow B and others who wants
to use the functions of A to create the object. To protect A’s objects to be created by others A
should make there default constructor as private.
class A
{
private A()
{
}
}
Now no one can create the object of A except A itself. To create the object of A, it uses the
method in which it is going to create the object. We know that if a method is creating the object
of a class then it is known as factory method so class A will create the object in factory method.
class A
{
private A()
{
}
public A createA()
{
A a=new A();
return a;
}
}
Now class B and other classes who wants to use the functionality of A can get the object of A by
accessing the factory method createA(). To access createA() again B and other classes require
object of A. Now to provide the object to other classes A has to make the factory method as
static factory method so, other can access their method by using class name.
class A
{
private A()
{
}
public static A createA()
{
A a=new A();
return a;
}
}
Now other class can access the factory method createA() By using class name A
class B
{
A a1=A.createA();
}
But now the problem is that when B again call the createA() then another object of A will be
created. To avoid this A has to keep the track of creation of its object by storing in an attribute of
type A.
class A
{
private A instance;
private A()
{
}
public static A createA()
{
A a=new A();
return a;
}
}
Now we know that static method cannot access non-static attribute without object creation, so
make the attribute which keeps the reference of object as static and make a conditional statement
like following. Inside factory method.
class A
{
private static A instance;
private A()
{
}
public static A createA()
{
If(instance==null)
{
instance=new A();
}
return instance;
}
}
Now when first time B will call the createA() method then control goes to createA() method
checks if instance is null or not at this time it will be null then go inside the if block and creates
the object of A and stores it in instance variable. When second time creteA() will be called
control goes to check the if condition at this time instance is not equal to null then it will return
the same object which is created during the first call of createA(). Now we can see that in any
case B can get only one object of A. But in class B calling method createA() gives the perception
that each time a new object is created.
class B
{
A a1=A.createA();
A a2=A.createA();
}
Here a1== a2
Now instead of createA() if we use getInstance() then it will give the perception that B is getting
the object not creating.
class A
{
private static A instance;
private A()
{
//No-op
}
public static A getInsatnce()
{
If(instance==null)
{
instance=new A();
}
return instance;
}
}
Now we can say the above class is singleton, but it is singleton in multithreading environment or
not we have to check. Let’s suppose there are two threads t1 and t2 both wants to use the
functionality of A simultaneously.
class MyThread implemnts Runnable
{
run()
{
A a=A.getInstance();
}
}
class Test
{
public static void main(String[] args)
{
MyThread mt=new MyThread();
Thread t1=new Thread(mt);
Thread t2=new Thread(mt);
t1.start();
t2.start();
}
}
class A
{
private static A instance;
private A()
{
//No-op
}
public synchronized static A getInsatnce()
{
If(instance==null)
{
instance=new A();
}
return instance;
}
}
This synchronized keyword will permit only one thread to execute at a time it means it will lock
the monitor for other threads while it is executed by one thread after execution of one thread
another thread will get chance. In this case any changes done by a thread will be visible to all the
threads.
When a thread invokes synchronized method it will acquires an intrinsic lock for that method
object. When an intrinsic lock is acquired by one thread other threads which want to access that
methods are locked until the acquired thread will release the lock.
Now let’s suppose t1 will invokes getInstance() then it will acquire intrinsic lock to the object of
that method after returning the object to t1 intrinsic lock will be released when t2 will invokes
the getInstance() method it will acquire the intrinsic lock to the object of that method but for t2
instance will not null in this case t2 will get the same object in return which was created earlier.
In this way we see that by writing synchronized keyword in factory method class A becomes
singleton in multithreading environment also.
Now let’s suppose there is a class C which has implemented the Cloneable interface then class C
has got the right to override the clone method of object class. Let’s see-
class C implements Cloneable
{
Object clone()throws CloneNotSupportedException
{
return super.clone();
}
}
Now suppose singleton class extends the class C accidently then class C can create the clone of
object of singleton class like following
class C
{
A a=A.getInstance();
A a1=(A)a.clone();
}
Now when any class try to make the clone of singleton class object then singleton class will
throws an exception clone of object is not supported. Now the above Class A can be called as
singleton class.
Application2
There are two web application Application1 and Application2 deployed in a server Application1
has Servlet1 calls the getInstance() method of singleton class A similarly Application2 has
Servlet2 which do the same now in this situation when Servlet1 calls the getInstance() method
first time the object of the singleton class A is created and given to the Servlet1. But when the
Servlet2 calls the getInstance() method first time then what will happen is singleton class is
going to return the same object which is created by Servlet1 or new object is created. If new
object is created then there will be two objects of singleton class in JVM. If it is possible then
what we know the concept of singleton class is wrong.
To solve this problem refer to ClassLoader Section comming soon.
package com.sf.beans;
import java.util.Calendar;
public class Alarm
{
private Calendar time;
public void setTime(Calendar time)
{
this.time=time;
}
public void ring()
{
System.out.println("Ringing :"+time.getTime());
}
}
To create the object of Calendar class we have to tell the spring to call the static factory method
of Calendar class. Static factory method contains the logic for creating the object of this class. To
tell the spring to call the static factory method of Calendar class we need to write an
attribute factory-method=”getInstance” at calendar bean tag level like the following.-
configuration file
<bean id="cal" class="java.util.calendar" factory-method="getInstance"/>
<bean id="alarm" class="com.sf.beans.Alarm">
<property name="time" ref="cal"/>
</bean>
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import com.sf.beans.Alarm;
public class AlTest
{
public static void main(String[] args)
{
BeanFactory factory=new XmlBeanFactory(new ClassPathResource("application-context.xml"));
Alarm alarm=factory.getBean("alarm",Alarm.class);
alarm.ring();
}
}
Types Of IOC
IOC is a principle. IOC will collaborate the object. Collaborate means manage the object by
injecting one object into another. IOC will manage the life cycle of the object. Since spring
container can also collaborate the object and manage the life cycle of the object so it is called as
IOC container. There are two ways using which we can collaborate objects.
IOC is of two types, again each type is classified into two more types as follows-
1. Dependency Lookup
a) Dependency Pull
b) Contextual Dependency lookup
2. Dependency Injection
a) Setter Injection
b) Constructor Injection
Dependency Lookup-
It is very old technic which is something exists already and most of the J2EE applications use. In
this technic if a class need another dependent object, it will write the code for getting the
dependency. Again it has two variants as said above.
a) Dependency Pull
If we take J2EE web application as example, we retrieve and store data from database for
displaying the web pages. So, to display the data our code requires connection object as
dependent, generally the connection object will be retrieved from a connection pool. Connection
pool are created and managed by application server. Below diagram shows the same-
Our component will look up for the connection from the pool by performing a JNDI lookup. it
means we are writing the code for getting the connection indirectly we are pulling the connection
from the pool. So, it is called dependency pull.
pseudo code
ServletCo
nfig will be injected into servlet by the container. Now the container will pushes the config
object by calling the init method of the servlet. Until our code implements from servlet
interface,container will not pushes the congig object, this indicates servlet interface acts as a
contract between we and our servlet . that’s why it is called Contextual dependency lookup.
Dependency Injection
The new way of acquiring the dependent object is using setter injection or constructor injection
1.Setter Injection
In setter injection if an object depends on another object then the dependent object will be
injected into the target class through the setter method that has been exposed on the target classes
as shown below-
package com.si.bean;
class Car
{
private Engine engine;
public void setEngine(Engine engine)
{
this.engine=engine;
}
public void start()
{
engine.start();
}
}
}
package com.si.bean;
class Engine
{
private int engNo;
public void setEngNo(int engNo)
{
this.engNo=engNo;
}
public void engStart()
{
System.out.println("Engine starts");
}
}
In above application ‘Car’ needs the object of ‘Engine’ it means ‘Car’ is the target class in which
the dependent object of ‘Engine’ will be injected by calling the exposed setter method.If we want
our class to be managed by spring then we have to declare our classes as spring beans in spring
bean configuration file as follows-
application-context.xml
<beans>
<bean id="car" class="com.si.bean.Car">
<property name="engine" ref="eng"/>
</bean>
<bean id="eng" class="com.si.bean.Engine">
<property name="engNo" value="E1"/>
</bean>
</beans>
2.Constructor Injection
In this technic instead of exposing a setter, your target class will expose a constructor, which will
take the parameter as our dependent object. As our dependent object gets injected by calling the
target class constructor, hence it is called constructor injection as shown below-
package com.si.bean;
class Car
{
private Engine engine;
public Car(Engine engine)
{
this.engine=engine;
}
public void start()
{
engine.start();
}
}
package com.si.bean;
class Engine
{
private int engNo;
public void setEngNo(int engNo)
{
this.engNo=engNo;
}
public void engStart()
{
System.out.println("Engine starts");
}
}
In target class ‘Car’ we have declared constructor in which attribute ‘engine’ is of dependent
type ‘Engine’ is declared as parameter in it. Now to tell the spring to manage the dependency
again we have to declare ‘car’ and ‘Engine’ as bean in Spring bean configuration file like
following-
application-context.xml
<beans>
<bean id="car" class="com.si.bean.Car">
<constructor-arg ref="eng"/>
</bean>
<bean id="eng" class="com.si.bean.Engine">
<property name="engNo" value="E1"/>
</bean>
</beans>
Now create the IOC container and test the application as below-
package com.si.bean;
class CarTest
{
public static void main(String[] args)
{
BeanFactory factory=new XmlBeanFactory(new ClassPathResource("application-context.xml"));
Car c=(Car) factory.getBean("car");
c.start();
}
}
O/P
Engine starts
In both setter injection and constructor injection we are asking the ‘Car’ object from IOC
container it will give us by injecting ‘Engine’ class object. So, when we call star() method of car
class it will goes there and call EngStart() method of Engine class. Hence, we see that we have
not created the Engine class object it is created by spring and injected into the Car class object
either by setter or constructor.
Strategy Pattern
Strategy pattern lets us build software as loosely coupled collection of interchangeable parts, in
contrast with tightly coupled system. This loosely coupling makes our software much more
flexible, extensible, maintainable and reusable.
Strategy pattern recommends mainly three principles every application should follow to get loose
coupling benefits-
1. Inheritance:- Inheritance is the process of extending one class from another class to get its
functionalities. Using inheritance we always express relation between two classes as IS-A
relationship.
2. Composition:- A class will hold reference of other classes as attributes inside it.
Composition always hold reference of other classes as attributes inside it.
When should we use Inheritance?
In an application there are number of classes if any class needs all the functionalities of
any one class then we should use inheritance.
When a class can be used as substitute to other class i.e when a class is an another class
type then we can use inheritance.
Let us see an example:-
class A
{
public void m1()
{
//some business processing logic
}
public void m2()
{
//some other business processing logic
}
}
In above application ‘A’ has two functions m1 and m2 which will perform two different business
operation. Now let’s suppose there is a class ‘B’ which needs both the business functions of ‘A’
then in this situation ‘B’ should extend ‘A’ to get all the functionality of ‘A’ as follows-
class B extends A {
B b=new B();
public void m3()
{
b.m1();
b.m2():
}
}
Now let’s suppose there is one more class ‘C’ in this application which also needs all the
functionality of class ‘A’, then ‘C’ can either extends ‘A’ or ‘B’ because here ‘B’ has also has
the functionality of ‘A’. In this case B acts as substitute for ‘A’. i.e ‘B’ acts as type ‘A’ for ‘C’ in
this situation also we can go for inheritance as follows-
class C extends B
{
C c=new C();
public void m4()
{
c.m3();
}
}
From above discussion we understand that we should go for inheritance only when all the
behaviors(methods) of our base class can be commonly shareable across all the derived classes.
Drawbacks of Inheritance
1. In real time there are not many use cases design which support inheritance.
Let’s suppose in an application there are three classes A, B and C. If A needs all the functionality
of B then we use inheritance, but when A also needs all the functionality of C then we cannot use
inheritance because it becomes multiple inheritance and java or most of the programming
language does not support multiple inheritance.
2. Inheritance makes the classes fragile in an application. Fragile means easily breakable.
Example:-
class A {
public void m1()
{
//some logic
}
}
class B extends A
{
public void m1()
{
// some overridden logic
}
}
class C extends A
{
public void m1()
{
//some overridden logic
}
}
Let’s suppose above three classes class ‘A’, ‘B’ and ‘C’ are developed by three different
developer in a project. Class ‘B’ and ‘C’ overriding the method m1() in there respective classes.
In above application class B uses the functionality of A and class C also uses the functionality of
A.
Now at any point of time if developer of class ‘A’ felt return type of method m1() needs to be
changed and has modified from void to int as below-
class A {
public int m1()
{
//some logic
}
}
Now the class ‘B’ and class ‘C’ both gives compilation error because of duplication of method
m1().
When we are overriding the super class method and sub-class method signature should be
same.But here in the super class for the method m1() return type is int and in sub-class the return
type is void, so it is not a valid overriding.
Even it is not a valid overloading, because parameters of super class method m1() and paramters
of sub-class methods are same. It means we have two methods with same name in the same class
which is not allowed. so it results in compilation error.
Here the change in the super class will not just break the sub-class even the classes using the sub-
class also will get affected and all the components using our sub-classes need to undergo
changes. It results in high maintenance cost and chances of increasing the bugs will also be more.
We can see that if we use inheritance in above application then without touching the Class ‘B’
and ‘C’ they are breakable i.e change in one class affects the other dependent class.
Suppose ‘Engine’ is not fully developed then ‘Car’ cannot use the functionality of ‘Engine’, at
that time for testing ‘Car’ developer has to make ‘MockEngine’ and extends Car from it.
MockEngine can test only one condition or function of the Car at a time. It means whole Car is
not tested in single sort. For testing all the condition of Car developer has to modify the
MockEngine code with respect to Car testing function each and every time. It is very difficult
,which shows that testing with inheritance is very very difficult. All the above problems with
inheritance cannot be solved within inheritance
Composition
When in an application one class needs some functionality of other class then we use
composition. Composition means by using attributes of the class whose functionality is needed.
Example:-
class A
{
B b=new B(); ( Using the attributes of B)
void m1()
{
b.m2();
}
}
class B
{
public void m2()
{
//some business logic
}
public void m3()
{
//some business logic
}
}
In the above exampleclass ‘A’ needs only the m2() method of the ‘B’ so, we have created
the object of B in A and by using that object ‘A’ can get the required m2() functionality from
B.
If there is another class ‘C’ in the application and ‘A’ wants some functionality of C also
then through composition A can get the required functionality from C
Problem With Composition
class A {
B b;
public void m1()
{
b=new B();
b.m2();
}
}
class B
{
public void m2()
{
//some business logic
}
}
In the above application ‘A’ uses the functionality of B through composition. Here class ‘A’
depends on class B. It means if any changes occurs in Class B then we have to change the code
of class A. If class B is removed then class A gives compilation error. In this way we can say that
through composition classes gettightly coupled.
Problems in composition can be solved through interface
2.Always design to interface, never code to implementation-
For getting the functionality of one class from another class do not use direct concrete class
attributes, in between use interface to get functionality.Let’s see an example-
class A
{
IB b;
public void m1()
{
b=new B();
b.m2();
}
}
interface IB
{
void m2();
}
class B implements IB
{
public void m2()
{
//some business logic
}
}
Now at any point if we want to use the functionality of another class ‘C’ then just implement that
class from interface ‘IB’ through IB refrence use the functionality of Class C without changing
any code (almost zero changes) in A.
class C implements IB {
public void m2()
{
//some business logic
}
}
class A
{
IB b;
public void m1()
{
b=new C();
b.m2();
}
}
In above application we can see that by using interface we achieve loose coupling i.e whenever
we want to switch from one class to another class we can switch by almost zero changing in
code.
Let’s understand the benefits of composition by taking a real time use case-
Let’s suppose a client wants an e-commerce website to attract the customer he comes with an
idea of providing additional features like getting temperature of any area other than shopping.
Developer listen the requirement of client and take three months duration to complete this
project.
Now developer starts developing the application, first he prepare the request form with jsp in
which customers input their required area zip code to find the temperature of that area. Whatever
be the request comes from jsp goes to Servlet, in Servlet developer has written the logic for
handling the request by overriding the service method.
Now to give the temperature of particular area servlet cannot get it from database, because
database does not contain the temperature of any area. To get the temperature of any area
developer also cannot write the code for satalite to fetch the temperature.
To help the developer client takes the help of third party like IBM which have WeatherFinder
hardware. This WeatherFinder hardware can get the temperature from satalite by transmission of
signal. To use that hardware IBM has given API. To make the job easy for developer Client buy
WeatherFinder machine from IBM. Now developer use the API given by IBM to communicate
with that machine and get the temperature from satalite indirectly.
At present Client get satisfied by this application, but after some time client finds that IBM
WeatherFinder machine is too costlier for him because of hiden terms and condition. He starts
searching for another similar service provider and finds Oracle is providing similar machine
WeatherReporter.
Now Client calls his developer and tells about his problem. Client asks his developer to switch
from IBM WeatherFinder to Oracle WetherReporter . Developer tells the client that it will take
three months to switch from IBM to Oracle and it will costlier than using IBM product. Client
starts screaming on developer how you had developed the code that it becomes so difficult to
switch
Above approach makes servlet tightly coupled with IBM API that’s why it is very difficult for
developer to switch from IBM to Oracle.
To overcome the tightly coupled problem developer starts creating interface and its
implementation class like following-
Now to switch from IBM to Oracle developer has to do small change in WeatherFinderServlet
instead of writing IBMWeatherFinderImp write OracleWeatherReport that’s all. By doing this
we can achieve loose coupling and problem will solved in very less time and cheaply.
3. Code should be open for extension and should be closed for modification-
Let’s say a new Car came, and it uses a different drive technic, now we don’t need to modify the
default Drivable class rather we can create one more implementation of the IDrivable interface
and can set it as a reference to drivable reference. If we modify the existing code the chance of
increasing the bugs would be more, rather than our design should be flexible enough to plug-in
new implementations when required, our earlier design depicts the same.
Using IDRef
In some cases a bean wants to use the id of another bean, so how to inject “id” of a bean into
another bean, here we need to use idref.
In spring every time dependency injection will not give us required results, because injection of
bean or value to another bean will give us only static value. It means when we want any value at
run time (dynamically) it will not possible through dependency injection. To get dynamic value
we have to pull the value.
For example Car needs an Engine to run, to use Engine inside Car we can inject Engine ito the
Car, but we don’t want to inject rather we want to pull, to pull we need the id of the Engine
inside the car. so we are injecting the id of the Engine into the Car as shown below-
package com.idref.bean;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class Car {
private IEngine engine;
private String engineId;
public void setEngineId(String engineId) {
this.engineId = engineId;
}
public void drive()
{
BeanFactory factory=new XmlBeanFactory(new ClassPathResource("com/idr/common/application-
context.xml"));
engine=(IEngine) factory.getBean(engineId);
engine.start();
}
}
package com.idref.bean;
public interface IEngine {
void start();
}
package com.idref.bean;
public class HondaEngine implements IEngine {
public void start() {
System.out.println("Honda Engine is Started");
}
}
package com.idref.bean;
public class FiatEngine implements IEngine {
public void start() {
System.out.println("FiatEngine Is Started");
}
}
In the above Spring bean configuration file for property “engineId” we have passed the value as
“hondaEngine” which will work by injecting the “HondaEngine” bean into Car. But, there is a
problem with the above piece of code. The problem here is we are passing the engineId
“hondaEngine” as a value into the car, if the bean id has been changed let’s say “hondaEngine”
to “hondaEngine1” then it would be difficult to track and change the value as the property is
configured as value.
In real time application developer will not be able to understand upon looking into configuration
whether to modify or not as it looks like a simple value. By mistake if developer change the
property value which looks like as general value without considering the bean Id of other beans
then IOC container will give run time exception.
In this case Spring will try to create the IOC container even the configuration is inconsistent,
which will results in an runtime exception while getting the Engine using
factory.getBean(“engineId”).
To avoid the above problems it is recommended to pass the id of another bean as value using
<idref> tag. “ref” means reference to an id of another bean. Below configuration shows the
same-
application-context.xml
<?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="car" class="com.idr.bean.Car">
<property name="engineId" ><idref bean="hondaEngine"/></property>
</bean>
<bean id="hondaEngine" class="com.idref.bean.HondaEngine"/>
<bean id="fiatEngine" class="com.idref.bean.FiatEngine"/>
</beans>
With the above Spring bean configuration file while creating the Car bean in the IOC container,
it checks if any bean with id as “hondaEngine” exists if found then only creates the Car object
and inject the value “HondaEngine” into the car. Otherwise will stop creating the object and
throws an exception.