Class Is A Unit Which Encapsulates The Data and Logic To Process That Data
Class Is A Unit Which Encapsulates The Data and Logic To Process That Data
Class Is A Unit Which Encapsulates The Data and Logic To Process That Data
Class is a unit which encapsulates the data and logic to process that data.
In Procedure-oriented languages data and logic processing them is not properly utilised and we
don’t have proper control who can access this data. In procedural languages if each function demands
same data we need to pass it as arguments to each function.
Also if we want to implement object oriented methodologies in procedural language we need to write
very difficult code itself. because these doesn’t provided support for OOP principles.
Note : JVM is an executable program. Which is launched using java command. Each Java command
create one instance of JVM and has different address space.
JVM needs all classes into object format before execution so byte code is loaded into Class class object
which hold byte code information. A Class-loader loads the byte code into JVM memory from theFile
System.
hashCode() - it computes a unique hash value for a given input. It will never computes same hash
value for different set of values.
And for same values it will always computes same hash value.
To make it work properly we need to override this method so it will keep the contract that for same
content same hash code should be generated.
To create hashvalue multiple a number with a prime no .it will always generate different no.
equals()– it is used to compare content and even the class type of objects as well.
i.e. it uses both hashcode() and classtype to prove equality.
If class types or content of two objects are not same then it will return false, other wise true.
But Object class’s implementation of equals will compare hashcodes only and alwaysreturn
false.
[Type here]
2
Page 2
So always two objects will be treated as different as the default hashcode returns different
hashcode even the content is same.
Thus To make it work properly we need to override this method so it will keep the contract that
same classtype and same content will only return true.
== operatorIt always compares memory references of two objects , if both operand objects are same
then only return true.
Exception is means of reports system failure that is encountered during execution of a program.
Checked Exceptions :
Are also called Recoverable exceptions i.e. their some alterative solution we can use to
maintain normal flow of execution when we encounter any checked exception.
For checked exceptions Java Compiler forces us to handle these exception and provide some
alternative flow of execution.Either we need to handle exception by surrounding the corresponding
code in try catch or use throws to tell Compiler I am not interested to handle this exception or I don’t
know how to handle it, instead my caller method would take care about it.
Un-Checked Exceptions :
Are also called non-recoverable exceptions i.e. their no alterative solution we can use to
maintain normal flow of execution when we encounter any unchecked exception.
Compiler doesn’t care for un-checked exception as there is no way to recover from them, we need to
terminate the application only.
Note :
We can catch both checked and unchecked exceptions and handle them.
[Type here]
3
Thread
A thread is a small logical independent part of execution that can run
simultaneously/parallel.It is a unit of work.
By default JVM follow sequential execution , that is each line is dependent to previous line. But if we
have independent codes, write this independent code in a thread.
JVM can’t know whether it should follow normal flow or multithreaded flow we need to tell JVM by
telling that my program has these independent part of same program by writing in Thread class.
Thread Vs Runnable
Implementing Runnable doesn’t makes a class as a thread , so we can’t directly start it, rather we need
to pass this class object to thread constructor and then we can callstart() on it..
But extending Thread class makes our class as a thread and we can directly call start() on it.
When we call start method on a thread it won’t start execution rather it moves to Ready-State i.e.
Thread Scheduler can select it for execution.
We can’t directly give the source code or byte codes in directory form because has following problems
:
1. Client don’t have technical knowledge so source code will increase complexity for him thus we
need to hide these from him.
2. If we give him directory of byte code he may accidently delete or modify byte code or he may
change the directory structure like delete packages , then application will crash.
3. Even we ensure no one would modify , it is difficult to client to set class path and identify which
is Entry point to execution ,if new release of application is released all this info might
change.this is overhead for him.
4. Also jar guarantees it integrity by jar sign certificates.
Thus we need to give him a single file which is secure from these threats.
Also In jar manifest file developer can write all configuration information to run the application
so that client will have ease of using it by directly clicking it or using following command.
Java –jargame.jar
Note : in this commad classpath will not work. Because jre will never checks classpath for this
command.
Page 4
Jar –cvfm game.jar appinfo.txt com
Appinfo.txt
Main-Class: com.ej.test.Game
Class-Path: ./lib/drawbox.jar
Manifest.mf
Manifest-Version: 1.0
Created-By: 1.8.0_72 (Oracle Corporation)
Main-Class: com.ej.test.Game
Class-Path: ./lib/drawbox.jar
ClassNotFoundException vs NoClassDefinitionFoundError
Class Loader
JVM needs all classes into object format before execution so byte code is loaded into Class class
object which hold byte code information. A Class-loader loads the byte code into JVM memory from
the File System.
A class loader is a java class which is requested by JVM to load byte code of data in JVM Memory. Class
loader will reads the byte code from physical memory location and creates a class definition object
having all information about that class in it (i.e. constructors,fields,methods).
Java has provided three class loaders but we can also design our own classloaders.
Each of these class loader loads byte code from specific physical locations.
These are in a hierarchical manner.
Bootstrap classloaderloads the classes which are necessary to run a basic java class i.e.
it loads classes which are shipped as part of java release ( java.lang, java.util, java.net etc. package )
like rt.jar, i18n.jar.
Bootstrap class loader is written in Native languages like C and C++ so that it can be a direct Machine
executable form so that it can directly run on OS. That’s why it is also called Native Class Loader.
Bootstrap classloader loads classes from JRE/lib directory.It will loads the classes form rt jar or i18n
jar but not loads classes from jar that we have placed in this directory.
A system property is property that can be shared between classes loaded in that JVM
instance.
It will never loads .class file directly rather it loads classes which are in jar file.
But the default class path is current working directory (represented as . ). When we set
class path it is overwritten and then it will not loads from default class path.
System class loader always prefers .class files for loading rather jar files . SO to load classes
from jar files we need to pass jar file name also as classpath.
Like –cp D:work/lib/game.jar
All three class loaders works in an integrated way they are not independent.
[Type here]
6
1. Principle of Delegation
2. Principle of Visibility
3. Principle of Uniqueness.
1. Principle of Delegation
WheneverJVM request to load a class it will request the class loader with least in
hierarchy(System class loader) to load the class.
After getting request System class loader, classloader will checks whether class is already
loaded or not i.e. it is in class loader cache, otherwisedelegates that request to parent class
loader (Extension class loader) and again that will delegates to its parent class loader. But
Bootstrap classloader don’t have any parent to delegate, so it will search whether it is in java
shipped classes or not , if it can’t load the class it will pass to the child (Extenesion loader) ,
Extension class
loader will check in ext directory and java.ext.dirs pointed location if finds then load otherwise
go to child(System class loader), System class loader will check in classpath locations ,if find
then load otherwise throws exception NoClassDefFoundError or ClassNotFoundException.
if a class/jar is available in parent classloaders location, it never can load that class.
2. Principle of Visibility
A classloader can see/refer the classes which are loaded by either itself or paren
classloader of it but it can’t see classes loaded by same level classloaders(Siblings) or its
child.
[Type here]
7
Game.java
{
Drawbox db = new Drawbox();
}
Drawbox.java
{
……………………..
……………………..
}
Game is loaded by system classloader and Drawbox by extension class loader then ok.
But if Game is loaded by extension classloader and Drawbox by system class it will
throw exception.
3. Principle of Uniqueness
If a class is already loaded by any classloader in the hierarchy, no other classloader will load
the class again in jvm memory i.e. only one copy of class definitionwill reside in JVM memory.
Principle of uniqueness works on top of principle of delegation. If we request another class loader to
load the class again the request will be delegated and the classloader will returns the reference from
class loader cache.
Game is loaded by system class loader and Drawbox by extension class loader then ok.
But if we again want to load Drawbox by another class loader (System class loader) and
by setting classpath to drawbox.jar then also it will load the drwabox class using
Extension class loader as the request is delegated to extension classloader and it
extension’s cache it was already available.
[Type here]
8
Loading
The physical location of the byte file will be identified and byte code of that class will be
will be read from physical memory location and placed into byte array but it is not dumped into class
definition object. If the class file is not available it will raise exception before class is loaded into JVM
memory.
Linking
In this phase the loadedbyte code will be verified whether it is proper or not and memory
for it will be allocated and finally all external class references are resolved and the classes
will load . It has 3 stages.
1. Verifying–
performs some series of checks whether the class is in proper executable format
or not,if this checks fails then class won’t be loaded.
i. JRE version and Byte code version(compiled) is compatible or not.
ii. Byte code Integrity check (Byte code is corrupted or not ) by comparing
byte code checksum and computed checksum.
iii. Jar integrity check:jar signing is sealed or opened.
2. Preparing-
After Verifying the byte code will be converted into class construct and
basic memory for representing class is allocated, attributes and methods
of the class will be identified i.e. skeleton(schema) of class is generated.
variables and methods have been provided memory.
3. Resolving-
[Type here]
9
Initialization
Class is initialized using static initializer blocks and now fully constructed.
Class.forName(“ROBOT”,false,classLoaderRef);
Classification of Classes
Classes are divided into following types.
POJO (Plane Old Java Object)
Java Bean
Bean/Component
POJO (Plain Old Java Object)
-----------------------------------------
If a class is not referring to any other third party vendor provided classes and it can be compilable and it can
be executable in underlying JDK then that class is called POJO class.
Java Bean
---------------
When a class contain attribute with accessor method and class should not contain any other method then that
classes is called Java Bean
Bean/Component
--------------------------
The classes which are may or may not contain data (attribute) and the methods are carrying the logic of
Business those classes are called Component classes.
Managing dependency between the classes within the application is Spring Core. Several classes will be there,
every component classes refer to each other because they are dependent on each other.
Note: Many of the time POJO or Component classes are talk to any other classes but Java Bean will not talk to
any other classes.
Q. Why Strategy Design Pattern say that don’t use Inheritance? What are the drawback of
inheritance?
Answer :
Limitation 1
Most of the time a class don’t want to use all the behaviour of another class wanted to use few of the
behaviour of another class in such case if we use inheritance unnecessary methods also gets inherited
to our class that’s why most of the time we are using composition.
Limitation 2
If multiple classes want to use the functionality of one class in such case one class extended from
multiple classes but many of the programming language not support multiple inheritance that’s why
use composition don’t us inheritance.
Limitation 3
[Type here]
11
If we use inheritance component of the application will become fragile so don’t use inheritance rather
use composition.
What do you mean by fragile?
A class is extending from another class overriding the method through inheritance in this case if any
change in super class will effect to the sub class it ensure to modify in sub class also but in such case
not only sub class will be effected rather all the classes those are refer to sub class also get effected.
This is called fragile.
How fragile problem will solved when we go for composition?
Answer ->
class A{
public int m1(){
}
}
class B{
A a;
a=new A();
int i=a.m1();
}
class C{
B b;
b=new B();
int i=b.m1();
}
In this case if return type of class A is change int to float it will effect to class B but it is manageable by
type casting the return type of int like int i(int)=a.m1(); but it will not effect of any other referring
classes.
Limitation 4
Testability will not be possible when we go for Inheritance, it will be easy when we go for
composition.
SDP Example
In This example of we are trying to write a message in converted form to display end-user.
We have two converted forms of message: HTML form and PDF form.
MessageWriter class is our component class responsible to write converted message. So it must
contain the logic for writing a message only.
Interface IMessageProducer
[Type here]
12
{
String convertMessage(String message);
}
Our MessageWriter needs MessageProducer object to convert the message and write the message.
Thus we have to create the MessageProducer object in MessageWriter.
Class MessageWriter
{
Private HtmlMessageProducermessageProducer; // Line 1
SOP(convertedMessage);
}
Our Test Class will supply the message to write. Hence we need MessageWriter object in test class.
[Type here]
13
Class Test
{
Public static void main(String[] args)
{
MessageWriter messageWriter = new MessageWriter(); // Line 3
messageWriter.writeMessage(“Welcome to Strategy Design Pattern”);
}
}
Note:
If we create object of another class in our class, our class became tightly coupled because –
1. Our class is exposed with name of other class.
2. To create object our class must know the intantiation process of that class.
At Line 2 & 3to create object our class must know the intantiation process of MessageWriter
&HtmlMessageProducer and we are creating the object thus our class is Tightly-Coupled with
corresponding class.
if we want to switch from Html form to Pdf form we need to change the line 1 to
private PdfMessageProducer messageProducer = null;
and Line 2 to
messageProducer = new PdfMessageProducer();
But switching from one to another converted form we need to modify the source code which is
expensive practise i.e. we should recompile the source code, retest,repackage,redeploy and restart
server etc.
Class MessageProducerFactory
{
Public static IMessageProducer createMessageProducer(String type)
{
If( type.equals(“html” ) )
{
messageProducer = new HtmlMessageProducer Impl();
}
Else
{
messageProducer = new PdfMessageProducer Impl();
}
[Type here]
14
}
}
Now our MessageWriter class will ask MessageProducerFactory to get MessageProducer object.
Class MessageWriter
{
Public void writeMessage( String message)
{
IMessageProducermessageProducer = null;
messageProducer = MessageProducerFactory.createMessageProducer(“html”)
String convertedMessage = messageProducer.convertMessage(message);
SOP(convertedMessage);
}
This approach is called Object-pulling i.e.don’t create object itself ask some other class (Factory class) to
provide object you need.
But in this approach we are still referring to logical name of messageproducer object. Thus if we want to
change implementation from html to pdf we need to modify MessageWriter class again.
Someone has to inject our dependencies (provide as an input) if that class wants to use our class.
In this approach we need a setter or constructor for dependent attribute of our class so that whoever needs
MessageWriter will set dependency and can call writeMessage() method.
Class MessageWriter
{
Private IMessageProducermessageProducer;
[Type here]
15
SOP(convertedMessage);
}
Test class needs to use MessageWriter So it need to create MessageWriter Object and Manage its dependency.
Class Test
{
Public static void main(String[] args)
{
messageWriter.setMessageProducer(messageProducer);
messageWriter.writeMessage(“Welcome to Strategy Design Pattern”);
}
}
Why our test class should create objects it should get them using some factory class by supplying logical
classnames only.
We should write all fully-qualified class names in an external file(properties file) so that by sing logical class
name we can get actual class name;
The benefit here is we can change class names without restarting the server and this migration from
HtmlMessageProducer to PdfMessageProducer won’t affect business of client.
App-classes.properties
messageWriter.class = com.sdp.beans.MessageWriter
messageProducer.class = com.sdp.beans.HtmlMessageProducer
Class AppFactory
{
[Type here]
16
className = props.getProperty(logicalClassName);
obj = Class.forName(logicalClassName).getInstance();
return obj;
}
}
Class Test
{
Public static void main(String[] args)
{
MessageWriter messageWriter =
(MessageWriter)AppFactory.createObject(“messageWriter.class”);
IMessageProducer messageProducer =
(IMessageProducer)AppFactory.createObject(“messageProducer.class”);
messageWriter.setMessageProducer(messageProducer);
messageWriter.writeMessage(“Welcome to Strategy Design Pattern”);
}
}
This approach is well good and make our application fully independent and manageable but this works only iff
all our class needs same implementation( either HtmlMessageProducer or PdfMessageProducer).
But in many cases our application demands both HtmlMessageProducer or PdfMessageProducer then it would
be difficult to manage but the possible solution is
App-classes.properties
[Type here]
17
messageWriter.class = com.sdp.beans.MessageWriter
messageProducer1.class = com.sdp.beans.HtmlMessageProducer
messageProducer2.class = com.sdp.beans.PdfMessageProducer
Class Test
{
Public static void main(String[] args)
{
MessageWriter messageWriter =
(MessageWriter)AppFactory.createObject(“messageWriter.class”);
IMessageProducer messageProducer1 =
(IMessageProducer)AppFactory.createObject(“messageProducer1.class”);
IMessageProducer messageProducer2 =
(IMessageProducer)AppFactory.createObject(“messageProducer2.class”);
……..
……..
}
}
Doing so our Test Class is Managing Dependencies of other classes( setting messageProducer Object to
MessageWriter ) then also our Test Class will become Tightly-Coupledandwe should remove this code from
Test class then only our Test class will become fully loosely-coupled.
But now some has to care about providing MessageProducer object toMessageWriter.
AppFactory should care about manage this dependencies. But we have to write the code for managing
dependencies some where else to make all our Java classes Loosely coupled ( i.e. inside some configuration file)
and then use that configuration file to create objects and manage the dependencies but writing this code by
own ,it seems to boiler plate code.
Spring can do this dependency management for us and won’t need to write boiler plate code.
We just need to tell Spring Core, for which classes we want objects and manage dependencies.
Each class for which spring creates objects or manages dependencies, that class is called Spring Bean.
We should tell spring core about classes for which it should care about in a particular file format i.e. XML or
Properties etc.
Managing the dependencies and Object creation is done by BeanFactory class of Spring Core.
[Type here]
18
BeanFactory is an interface. It has many Implemententations like XMLBeanFactory and PropsBeanFactory ( for
Xml file and properties files as configuration)etc.
<beans>
<bean class=”com.fs.beans.MessageWriter” id = “messageWriter”></bean>
<bean class=”com.fs.beans.HtmlMessageProducerImpl” id = “htmlMessageProducer”/>
<bean class=”com.fs.beans.PdfMessageProducerImpl” id = “pdfMessageProducer”/>
</beans>
Class Test
{
Public static void main(String[] args)
{
BeanFactory factory = new XMLBeanFactory( new
ClasspathResource(“com/fs/common/application-context.xml”));
Here XMLBeanFactory requires input stream for Spring bean configuration file. It don’t know whether
the inputstream is from Absolute path or relative path location.
A possible solution for this problem may be like we can create AbsolutePathXMLBeanFactory and
RelativePathXMLBeanFactory classes but creating two classes only for pointing file path is not a good solution.
And there may be another Factory classes implementations,for those also we need to create two classes for
each.
[Type here]
19
Thus to differentiate b/w configuration file loading from relative path and Absolute path, Spring has
provided two classes.
BeanFactoryfirst checkwhether the Spring Bean Configuration File is well-formed xml documentif it is
not spring will throw exception.
Now BeanFactorychecks Validityof the xml document with Spring DTD file.
Welformness – ensures everyone can read it or not as it is following all xml syntax.
Validity - ensures whether xml document contains Spring understandable tags and with same
structure spring provided.
After this BeanFactorycreates a logical memory area inJVM memorywhich is called IOC container.
IOC container has two parts.
1. Metadata
2. Bean ID-Object Map( Logical Memory Map).
IOC term is not given by Spring People. IOC is a J2EE principle which talks about Object Collaboration
and Life Cycle Management for these objects.
Object Collaborationis like managing dependencies.
BeanFactory loads theSpring Bean Configuration Fileinto it as Metadata. Spring Core will use this
metadata information to create object of required bean.
Whenever we call getBean(“bean id/name”)on beanfactory object , it first checks whether referenced
bean object is available in Logical Memory Map. If it is available it will return a reference to it. Otherwise it
will go Metadata and searches for the referenced bean definition and get its classname and creates object of
corresponding class and put it into Logical Memory Mapand returns reference to it.
<beans>
<bean class=”com.fs.beans.MessageWriter” id = “messageWriter”>
<property name = “messageProducer” ref=”htmlMessageProducer” ></ property >
</bean>
<bean class=”com.fs.beans.HtmlMessageProducerImpl” id = “htmlMessageProducer”/>
[Type here]
20
</beans>
Here property tag is used to manage dependency of MessageWriter object i.e. Setting value of
messageProducer attribute using HtmlMessageProducer reference.
Note : MessageWriter class Must have the setter for messageProducer attribute.
SOP(convertedMessage);
}
<beans>
<bean class=”com.fs.beans.MessageWriter” id = “messageWriter”>
<constructor-arg ref=”htmlMessageProducer” ></ constructor-arg>
</bean>
<bean class=”com.fs.beans.HtmlMessageProducerImpl” id = “htmlMessageProducer”/>
<bean class=”com.fs.beans.PdfMessageProducerImpl” id = “pdfMessageProducer”/>
</beans>
IOC:
[Type here]
21
IOC stands for Inversion of Control.IOC is a design principle which talks about Object
Collaboration and Life Cycle Management for these objects.
Object Collaborationis like managing dependencies(maki one object available to use in some
other object).
IOC container is a logical memory area inJVM memory.
IOC container has two parts.
1. Metadata
2. Bean ID-Object Map( Logical Memory Map).
Spring provided two ways to manage dependencies Dependency Pull and Dependency Injection.
1. Dependency Pull:
Dependency pulling is old way of managing dependencies.
In dependency pull
2. Dependency Injection:
[Type here]
22
Prefer Constructor-Injection If
Prefer Setter-Injection if
1. Target class doesn’t needs dependent object to be used inside its constructor.
2. Dependencies are optional.
3. We have cyclic dependencies.
Why we use XML file as configuration file in spring IOC and Servlet Container and why we can’t use
Excel file?
Answer: Xml file is portable across platforms and languages (Inter-Operability). Any programing
language that can read files can use XML file, While XLS file will made our Java application dependent
on windows platform and if we have to change window to linux platform we should use linux-specific
excel file format. And this breaks JAVA’s WORA principle.
Collection-Dependency Injection
It is about “How to create collection objects and populate them with some values using spring
and then inject as dependencies in target class object”.
We can create collection objects as beans but we can’tpopulate these collection objects using spring
because we need to follow either setter-injection or constructor-injection to populate the collection object.
[Type here]
23
But Collection framework implementation-classes doesn’t have any constructor or setter method to
populate values.
i.e. <bean id=”list” class=”java.util.ArrrayList”/>will create an empty arraylist bean with no values.
List DI
A list is collection of values with preserved insertion order.
Set DI
[Type here]
24
Map DI
A Map is collection of entries. Each entry has one key and one value. These keys and values can be of
any type.
[Type here]
25
[Type here]
26
Or
<map key-type=”java.lang.String” value-type=”java.lang.String”>
<entry key=”ram” value=”c”></entry>
<entry key=”Shyam” value=”c++”></entry>
<entry key=”Mohan” value=”Java”></entry>
</map>
Properties DI
A properties is collection of properties. Each propertyhas one key and one value. These keys and values are
String.
<props>
<prop key=”ram”>C</prop>
<prop key=”Mohan”>C++</prop>
<prop key=”Roy”>Java</prop>
</props>
Util NameSpace
Came into picture in spring 2.0 version.
1. We can’t customize the implementation class for collection using normal <list>/ <set> etc tags.
2. We can’t create collections as individual bean using normal <list>/ <set> etc tags. Because these
collections are anonymously created and injected for particular property.
We can’t reuse any prepopulated collection to inject into some other target bean using normal
Collection DI tags.
<value>C++</value>
<value>Java</value>
</util:list>
<bean id=”course” class=”Course”>
<property name=”subjects” ref=”subjectList”>
</bean>
Similarly
<util:set id=”subjectList” set-class=”java.util.HashSet” value-type=”java.lang.String”>
<value>C</value>
<value>C++</value>
<value>Java</value>
</util:set>
And
And
<util:properties id=”subjectList”>
<prop key=”C”>Bala<prop>
<prop key=”C++”>Raju</entry>
<prop key=”Java”>Naagu</entry>
</util:properties >
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.1.xsd">
<beanid="course1"class="com.cdi.beans.Course1">
<propertyname="subjects"ref="subjectList"/>
<propertyname="faculties"ref="facultyList"/>
<propertyname="facultyOfSubject"ref="facultyOfSubjectList"/>
<propertyname="subjectToppers"ref="subjectToppersList"/>
</bean>
<util:listid="subjectList"list-class="java.util.Vector"value-type="java.lang.String">
[Type here]
28
<value>C</value>
<value>DS</value>
<value>OS</value>
</util:list>
<util:setid="facultyList"set-class="java.util.HashSet"value-type="java.lang.String">
<value>Bala</value>
<value>Nagu</value>
<value>Subbu</value>
</util:set>
<util:mapid="facultyOfSubjectList"map-class="java.util.HashMap"key-
type="java.lang.String"value-type="java.lang.String">
<entrykey="C"value="Bala"/>
<entrykey="DS"value="Nagu"/>
<entrykey="OS"value="Subbu"/>
</util:map>
<util:propertiesid="subjectToppersList">
<propkey="C">Vivek</prop>
<propkey="DS">Tiwari</prop>
<propkey="OS">Kumar</prop>
</util:properties>
</beans>
Bean Alias
Apart from Primary name(Bean id) providing alternative names to our bean, is called Bean Aliasing.
Purpose of Bean Aliasing
1st purpose –
To provide our own customized and programmer-friendly names without restrictions to
follow Java Naming Conventions.
When we provide Id for a bean we have to follow Java identifier Naming Conventions.
Due to these restrictions we can’t provide beans ids like – 1stAddress or office-address, 505-5th
Floor etc.
But we can provide our own conventional and user-friendly names using Bean Aliasing.
2ndpurpose –
When we want to switch from one bean definition to another bean definition in our
application, we need to change the entire configuration file and wherever we used bean1 reference, change
it to bean2 reference. This task is complicated and even there are chances of changing some other beans
configuration also.
That’s why bean aliasing came into picture rather than changing all bean references,
Simply provide bean1 as an alias of bean2, now both bean1 and bean2 are same.
Whenever we want the previous configuration just remove the alias tag and old configuration is back.
Suppose we are amazon people, we are providing deliveries in cities using Bluedart courierbecause it has
good service network in metropolitan cities.But it don’t have network in remote cities and towns, then we need
DTDC Transport Servicesto do business inin remote cities and towns. All things were good and we are doing
our business at efficient level.
Our OrderManager Class decides whether to use Bluedart courier or DTDC Transport Servicesdepending on
Zip code of shipping address.
publicclass OrderManager {
private IParcel bluedartParcel;
private IParcel dtdcParcel;
<beanid="address"class="com.asa.beans.Address">
<propertyname="addressLine1"value="505,5th floor"/>
<propertyname="addressLine2"value="Maitrivanam"/>
<propertyname="city"value="Hyderabad"/>
<propertyname="state"value="TS"/>
<propertyname="zip"value="500018"/>
<propertyname="country"value="India"/>
</bean>
<beanid="order"class="com.asa.beans.OrderManager">
<propertyname="bluedartParcel"ref="bluedartParcel"></property>
<propertyname="dtdcParcel"ref="dtdcParcel"></property>
</bean>
<beanid="bluedartParcel"class="com.asa.beans.BluedartParcelImpl"/>
<beanid="dtdcParcel"class="com.asa.beans.DTDCParcelImpl"/>
[Type here]
30
But due to some earth-quick Bluedart Courier’s infrastructure is destroyed and they need at least one
month to recover from it. So our business in Metropolitan cities will suffer now
.
To prevent this we came up with a solution that ask DTDC Transport to deliver orders in metropolitan
cities also until Bluedart Courier’s infrastructure is completely recovered.
But again for recovering previous version we need to change the source code which is costly.
Let’s change our spring bean configuration file for this purpose.
Find bluedartParcel and replace with dtdcParcel.This can work for a while. But problem
occurs when we want the previous configuration back because there is no way to find out actual
dtdc references and manipulated dtcd references.
For better understanding this example check Amazon Shopping app project in STS workspace.
[Type here]
31
When we define a bean we can define alias names also within same bean tag.
We can provide any no. of aliases separated by delimiter coma(,).
Problem here is we can’t include delimiter coma in alias name. Spring will treat it as delimiter.
Here also bean addresshastwo aliases – 505and 5th floor. But instead of 505 and 5th floorastwo
different alias we want both as one“505,5th floor”.
publicclassPerson {
privateintid;
private String name;
private String fatherName;
<beanid="person"class="com.cc.beans.Person">
<constructor-argvalue="10"/>
<constructor-argvalue="ramesh"/>
</bean>
Output : Person [id:0,name:10,fatherName:ramesh]
Because Spring treats each value as String value and then try to find matching conditions if
match is not there then it will cast the value to use available conditions.
I.e. if there was only one constructor with int arg , spring will first try to find String arg
constructor otherwise cast value to int and use int arg constructor.
<beanid="person"class="com.cc.beans.Person">
<constructor-argvalue="10" type =”int”/>
<constructor-argvalue="ramesh"/>
</bean>
publicclass Product {
privateintid;
private String productname;
privatefloatprice;
[Type here]
33
@Override
public String toString() {
return"Product [id=" + id + ", productname=" + productname + ", price=" +
price + "]";
}
}
<beanid="product"class="com.cc.beans.Product">
<constructor-argvalue="10"/>
<constructor-argvalue="mobile"type="int"/>
</bean>
Here Spring tries to search both values as String and search constructor with first argument String,
second constructor looks suitable according to first value but we cant cast “mobile” into double.
Even we specify the type correctly it can’t inject.
Eachtime someone is writing configuration ,he need to check argument order in Java class. It is not good
approach.
<beanid="product1"class="com.cc.beans.Product">
<constructor-argvalue="10"/>
<constructor-argvalue="mobile"index="0"/>
</bean>
Or
<beanid="product1"class="com.cc.beans.Product">
<constructor-argvalue="10" index="1"/>
<constructor-argvalue="mobile"/>
</bean>
[Type here]
34
@ConstructorProperties({"name","capacity"})
public Warehouse(String name, longcapacity) {
super();
this.name = name;
this.capacity = capacity;
}
@ConstructorProperties({"name","id"})
public Warehouse(String name,intid) {
super();
this.id = id;
this.name = name;
}
@Override
public String toString() {
return"Warehouse [id=" + id + ", name=" + name + ", capacity=" +
capacity + "]";
}
<beanid="warehouse"class="com.cc.beans.Warehouse">
<constructor-argvalue="15"/>
<constructor-argvalue="Main_Warehouse"index="0"/>
</bean>
Here which constructor would be called is decided by the value provided in this tag.
<constructor-argvalue="101568522145"/>Long arg Construtor
<constructor-argvalue="101"/> Int arg Construtor
IF value is in int range then Second constructor otherwise first Constructor. But we
can’t leave our program on uncertainty.
That’s why we need to resolve this using name.
<beanid="warehouse1"class="com.cc.beans.Warehouse">
<constructor-argvalue="101"name="id"/>
<constructor-argvalue="Main_Warehouse"name="name"/>
</bean>
Purpose of @ConstructorProperties
[Type here]
35
Compiler never creates the same constructor/method argument names as we have provided in JAVA file, while
creating Byte codeCompiler shortens them as $0,$1,$2,$3 etc to reduce size of byte-code. Because this byte
code will be loaded in JVM memory.
But JVM doesn’t know the name we provided in constructor then how Spring can use these names to resolve
conflicts.
@ConstructorProperties maps the byte-code names with programmer provided names.It takes array of names
and map to constructor in order.
Inner Beans
If we don’t need any dependent object separately in our application we should not create it as
an independent bean because –
1. Size of configuration file increases and performance reduces because each bean definition is
searched in the configuration file.
2. To change the dependents properties we need to search it in whole configuration file it is time-
consuming and there are chances of errors.
Rather create the dependent as inner bean.
Bean Inheritence:
In bean configuration file we might encounter a case where most of the time bean configuration of a
bean is same for another bean, i.e. we can reuse the bean configuration of one bean fully or partly.
Rewriting the duplicate content is time-consuming and even maintenance is difficult.
When we reuse bean property configuration of one bean for another bean definition
This is called Bean inheritance.
A bean which is inheriting bean configuration is called Child Bean. And bean from it has
inherited is called Parent bean.
[Type here]
36
We can inherit the configuration from any bean to any bean. With just one Constraint:
All the Bean configuration of Parent bean must exist in Child bean’s class as attributes.
We should not inherit configuration from a bean which is in use, because if we change
configuration for parent it would be reflected in all child also.
That is why we need it to declare as an abstract bean. We can’t get object for an abstract bean from
IOC container.
If we are not gonna get object for an abstract bean we don’t need to specify the class attribute for
abstract bean.
Bean Autowiring :
Automaticallyidentifying the dependencies of one class and managing them by injecting
them into target class is called Bean Autowiring.
By Default bean autowiring is disabled.
We can create and manage dependencies via Spring IOC container but it is not done
automatically either we need to provide the dependency information to spring or should enable the Bean
Autowiring.
We can enable bean autowiring by using autowire attribute at bean tag level.
Autowire = “mode”
1. byname
2. bytype
3. constructor
4. autodetect ( deprecated from Spring 3.0 onwards )
1. ByName
It uses setter injection to inject the dependencies.
When we call getBean(“target”) then it first goes to IOC container and searches for respective bean definition. If
it finds autowiring mode as “ByName”. It first creates object of target class .To detect dependencies it first goes
to target class finds attributes which has their setters and remembers the names of such attributes. Inside In
Memory metadata searches for bean definition whose id is same as dependent attribute name, creates
dependent object and injects the dependent object in target object.
[Type here]
37
If Inside In Memory metadatathe matching bean definition is not there then returns target object with
dependent references as null.
2. ByType
It uses setter injection to inject the dependencies.
When we call getBean(“target”) then it first goes to IOC container and searches for respective bean definition. If
it finds autowiring mode as “ByType”. It first creates object of target class .
To detect dependencies it first goes to target class finds attributes which has their setters and and remembers
the Class type of such attributesInside In Memory metadatasearches for bean definition whose class type is
same as of dependent attribute class type, creates dependent object and injects the dependent object in target
object.
If Inside In Memory metadatathe matching bean definition is not there then returns target object with
dependent references as null.
If there are more then one bean definition with matching dependent class type then , IOC container get
confused and don’t inject dependency with any beans and then returns target object with dependent references
as null.
One solution for this is to remove all other bean definitions of dependent class type but it may affect other
beans as they may have using them.
To resolve this confusion we should use autowire-candidate = “false”at bean tag level. Then IOC container
don’t consider that bean for autowiring.
3. Constructor
It uses constructor injection to inject the dependencies.
When we call getBean(“target”) then it first goes to IOC container and searches for respective bean
definition. If it finds autowiring mode as “Constructor ”. Itdon’t first creates object of target class .To
detect dependencies it first goes to target class finds constructor with maximum arguments and and
remembers the Class type of such attributes.
Inside In Memory metadatasearches for bean definition whose class type is same as of dependent attribute
class type, creates dependent object and calls the constructor, creates object withinjecting the dependent
object.
If all bean definitions are not therein spring bean configuration file
Matching with max-arg constructor, then it again goes to target class and finds next constructor with
maximum arguments and repeats the same process.
If match is there then creates target object with injected dependencies otherwise If no dependent bean
definitions found then it searches for default constructor and creates the object with dependents as null. If
default constructor is not there in target class thenthrows exception. And doesn’t create any object.
If there are two constructor with same no of arguments and then it goes to Inside In Memory
metadatachoosing any one constructor at random and tries to find dependent bean definitions and creates
[Type here]
38
object with dependent injected . otherwise choose another constructor and follows the same procedure until
match found.
If there are more then one bean definition of dependent class type and autowire-candidate is notset as false
then, IOC container get confused and again finds next constructor in target class and choose that and follows
same procedure to inject the dependents.
4. autodetect
In this mode the IOC container will detect and manage dependencies using both approaches
Setter Injection and Constructor injection.
First prefers constructor injection and then Setter Injection.
If for a given class,no constructor is there then it would follow setter Injection.
Answer: Bean Autowiring is a good feature but we incorporate it in our project it creates many problems
inproject management.
In Bean Autowiring the full configuration about project components is not available at one
single central file( Spring Bean Configuration file)rather we need to check each and every
component classes to deduce dependencies between.
1. Thus if a new member is joined our team, it is very difficult to onboard on application.
2. Debugging of application will became more difficult.
3. Even working with bean autowiring modes make it more difficult.
1. byname : if someone changed the bean id whole application would be affected and
broken.
2. byType or constructor:
if we have two beans with same class type then application run on ambiguity even
though we use autowire-candidate =”false”.there may be a case where bean1 is used in some
bean and bean2 in some other and both beans needed In managing dependencies.
3. Autodetect: deprecate in 3.0
Asautodetect follow both injection strategies again deduce the
dependencies more difficult.
Answer: Because there are some cases where bean autowiring is beneficial.
Suppose we are trying new feature to introduce in our application we can’t directly
because it is not fully tested and implemented. We first completely test it at different place.
If we manually define all dependencies in configuration file , testing new feature itself is time
consuming.
Here Bean Autowiring is saviour and quite useful. And that’s why spring doesn’t removed Bean
Autowiring feature.
<constructor-arg>
<null/>
</constructor-arg>
Nested BeanFactory
IOC container can easily manage the dependencies between beans if these beans are part of same IOC
container. But If our Target bean and Dependent bean are in different IOC containers then spring can’t directly
manage dependencies. Here Nested Bean factory can into picture.
IOC container (BeanFactory ) containing Dependent bean definition is called Parent BeanFactory.
IOC container (BeanFactory ) containing Target bean definition is called Child BeanFactory .
ChildBeanFactory can inject the dependents from Parent beanFactories into its own beans but
ParentBeanFactory can’t inject the dependents from Child beanFactories into its own beans.
a,b,c x,y,z
[Type here]
40
Test Class
Child-beans.xml
<property name=”b”>
<refparent = “b”></ref>
</property>
</bean>
parent-beans.xml
//property injection
[Type here]
41
</bean>
Parent attribute in ref tag will tell IOC container to find dependent inside other(parent) IOC
container. It will never checks in Same IOC container for dependents.
Local attribute in ref tag will tell IOC container to find dependent inside same IOC container. It will
never checks in Parent IOC container for dependents.
Bean attribute in ref tag firstly checks in Same IOC container for dependents if its not there then
checks into parent IOC container.
Collection Merging
When we havean collection type attribute in parent bean with populated values.
If we want both parent collection values and child-specific collection values inside child
If we rewrite the child property collection the parent values don’t copied.
To solve this
<beanid="btech1yr1semcsc"class="com.cm.beans.Course">
<propertyname="subjects">
<listvalue-type="java.lang.String">
<value>C</value>
<value>Discrete Maths</value>
</list>
</property>
</bean>
<beanid="btech1yr1semece"class="com.cm.beans.Course"parent="btech1yr1semcsc">
<propertyname="subjects">
<listvalue-type="java.lang.String" merge="true">
<value>Data Structure</value>
<value>Operating System</value>
</list>
</property>
</bean>
[Type here]
42
IDREF
Sometimesif we use dependency injection we may have some problems because IOC container may
not properly inject the dependencies or fail to inject the dependency even in some cases we can’t use
dependency injection. i.e. when we have dynamic dependencies that is which object we want to inject
is decided at runtime.Dependency injection is useful with static dependencies.
Consider this example Car has dependent engine. But instead we create engine object in Car class
spring will create object for us and we will pull the object in car .
IEngine.java
publicinterface IEngine {
int start();
void increaseRPM();
YamahaEngineImpl.java
publicclass YamahaEngineImpl implements IEngine
{
@Override
publicint start() {
System.out.println("Started Yamaha Engine");
return 1;
}
@Override
publicvoid increaseRPM() {
System.out.println("Increasing RPM by 800");
SujkiEngineImpl.java
@Override
publicint start() {
System.out.println("Started Yamaha Engine");
return 1;
}
[Type here]
43
@Override
publicvoid increaseRPM() {
System.out.println("Increasing RPM by 500");
Car.java
publicclass Car {
privateIEngineengine;
publicvoid drive()
{
BeanFactory factory = new XmlBeanFactory(new
ClassPathResource("com/idref/common/application-context.xml"));
if(status == 1)
{
System.out.println("Started Driving Car");
}
else
{
System.out.println("Engine didn't Started");
}
publicvoid accelerate()
{
BeanFactory factory = new XmlBeanFactory(new
ClassPathResource("com/idref/common/application-context.xml"));
engine = factory.getBean(engineId, IEngine.class);
engine.increaseRPM();
<beanid="car"class="com.idref.beans.Car"/>
<beanid="yamahaEngine"class="com.idref.beans.YamahaEngineImpl"/>
<beanid="sujkiEngine"class="com.idref.beans.SujkiEngineImpl"/>
ButHere our Car class is tightly coupled with logical bean name as we are refering to the bean id if we
want to change yamaha engine to sujki engine Car should be modified.
[Type here]
44
But we can pass this as argument to method drive() and accelerate() then it would become loosely
coupled.
However we need engine in whole Car class declare it as an attribute at class level to each method can
use it. And we can pass this attribute value with either constructor or setter injection.
Here we are not injecting the object rather we are injecting id reference of dependent object.
publicclass Car {
private String engineId;
publicvoid drive()
{
BeanFactory factory = new XmlBeanFactory(new
ClassPathResource("com/idref/common/application-context.xml"));
IEngine engine = factory.getBean(engineId, IEngine.class);
intstatus = engine.start();
if(status == 1)
{
System.out.println("Started Driving Car");
}
else
{
System.out.println("Engine didn't Started");
}
publicvoid accelerate()
{
BeanFactory factory = new XmlBeanFactory(new
ClassPathResource("com/idref/common/application-context.xml"));
IEngine engine = factory.getBean(engineId, IEngine.class);
engine.increaseRPM();
<beanid="car"class="com.idref.beans.Car">
<constructor-argvalue="sujkiEngine"/>
</bean>
<beanid="yamahaEngine"class="com.idref.beans.YamahaEngineImpl"/>
<beanid="sujkiEngine"class="com.idref.beans.SujkiEngineImpl"/>
[Type here]
45
But this configuration information is not providing proper perception to any other team member
about whether I have used value="sujkiEngine" as bean id reference or a primitive value.
1. Thus if someone tries to modify the bean idsujkiEngine and change all respective links to it
he might thinks <constructor-arg value="sujkiEngine"/>is not related and won’t change it.
2. BeanFactory also treats it as valid and creates Car object because it it unable to find it as wrong
configuration.
3. But at runtime it will raise exception and leaves system at inconsistent state which cant we
reversed.
Thus spring provided a better solution to get right perception of configuration in such case.
<beanid="car"class="com.idref.beans.Car">
<constructor-arg >
<idref bean="sujkiEngine"/>
</constructor-arg >
</bean>
<beanid="yamahaEngine"class="com.idref.beans.YamahaEngineImpl"/>
<beanid="sujkiEngine"class="com.idref.beans.SujkiEngineImpl"/>
1. Now every programmer would get the full information about configuration andwhenever
he changes bean id, he will change <constructor-arg
value="sujkiEngine"/>correspondingly.
2. BeanFactory also treats it as valid and if any bean with idsujkiEnginenot match in
spring bean configuration file it will give runtime exception while creating Car Object thus
application is not left in inconsistent state.
3. No chance for runtime exception.
It talks about creating a singleton class i.e. a class which allows only one object to create per JVM
instance.
1. Hide the constructors of class so that no one can create object for our class.
2. Provide one static method to create and return object of our class.
3. Inside that method write logic to create object such that object can be created once only.
[Type here]
46
e.g.
publicclass A {
private A a;
private A() {
public A getA() {
a = new A();
return a;
}
}
This code doesn’t create a singleton class because one each call to getA() method a new
object will be createdbecause our class never knows whether it already created the
object or not .
We need to declare a static reference which can hold already created object and we can check
whether it is null or not.
Thus
publicclass A {
private A instance;
privateA() {
// no code
}
publicA getInstance() {
if( instance == null)
{
Instance = new A();
}
returninstance;
}
}
Here We have named the method as getInstance because getA name doesn’t provide right
perception rather it tells that getA would return class A.
And if we left any constructor or method without any code some other people may feel it is not
important and may remove it so always write some comment in empty block if you need them.
If we have a class and we declare that class as bean in Spring Bean Configuration File then IOC container
will create the object of that class by calling the constructor of the class but not all the class can be
instantiated using the constructor of the class so we have to inform IOC container to create the object of
that class not by calling the constructor but by calling the static method which we provide it
For Example-
CurrencyConvertor.java
class CurrencyConvertor{
private CurrencyConvertor(){}
if(instance== null){
instance=new CurrencyConvertor();
return instance;
application-context.xml
Test.java
CurrencyConvertor cc1=factory.getBean("currencyConvertor");
CurrencyConvertor cc2=factory.getBean("currencyConvertor");
CurrencyConvertor cc3=CurrencyConvertor.getInstance();
lets say if we have a class called CurrencyConvertor and we create that class as singleton and we declare
that as bean, then by default the scope of the class will be singleton only, so when we call
factory.getBean("currencyConvertor") then it will create only one object of the class by calling the
constructor of that class and if we call another factory.getBean("currencyConvertor") then the IOC
container will use the same object but if we call CurrencyConvertor.getInstance() then it will create on
more object of that class because at this time Instance=null. If we define the scope as prototype and we
[Type here]
48
call factory.getBean("currencyConvertor") 2 times then it will create 2 objects of that class i.e. my class will
act as normal class here. To make the class as singleton we define the static method of the class as
factory_method= "name of the class" at bean tag level so that when we call
factory.getBean("currencyConvertor") then it will call the getInstance method of CurrencyConvertor class
and if we call CurrencyConvertor.getInstance() then also it will call same getInstance() method of
CurrencyConvertor class but in the 2nd time as the instance will not null then it will create only one object
of the class.
so that we can use the static factory method instantiation to create the bean as singleton.
There are 2 types of trading in the share market- offline trading and online trading
There is a person who wants to do the online trading through icicidirect.com and icicidirect.com do the
trading on behalf of that person from share market from BSE or NSE. for this they provide a JSP page to the
person that which company's stock details that person wants and as the person enter the company name
the request will go to corresponding servlet and within the logic is written to get the details of the stock.
For this icicidirect.com connect to BSE and get the information about the particular stock but to get the
information about that stock it have to connect to BSE database, but BSE can not share its database
information to anyone because there are many business data stored under that database and if the details
of that database will expose to anyone then there may be a chance that they can misuse the business data
and can change the data as per their requirement, this will be too much loss of the business and there will
so much problem can occur, so BSE define its own application and define the methods in that and written
the logic in that application to connect to the database and BSE Stock Exchange perform its business
operations from this application only(like buying the stock, selling the stock, getting the current price of the
stock etc) and save that application on application server but to connect to that application that is running
on one machine other classes wants the object of that application but my servlet class can not create the
object of the application class which is running on the application server because if it will create the object
of the BSE provided application class then it needs class file of that class and if we provide the class file to
the other class then there may be chance that the other person can decompile that and see the source
code to connect to database and directly connect to the database of the BSE then there will not be any
security of the database. to avoid this problem the BSE application class should itself create the object of
the class but it can not inject the object to the class which is running on different machine and different
JVM because if it will give the object out of the JVM then object will be destroyed automatically, so to give
the object to class which is running on different machine or to share the reference of the object to other
class we use the distributed technology, so that one class which is running on one machine can
communicate to the class which is running on different machine and can share the data and the object to
each other. The application class has to be built on distributed technology either in corba or rmi or ejb or
web services, if we built the server side stock manager application using ejb technology then ejb will be
deployed in ejb container and this ejb can be accessed by other applications which are remotely located to
other machines, other applications can only access the ejb when they have the reference of ejb, but the
reference of ejb is with BSE Stock Exchange on the application server and BSE Stock Exchange has to
expose the object of the ejb so that other application can access it. So we have to bind this ejb object to
[Type here]
49
jndi registry with jndi name so that other applications can access it and once those application get the
reference of the object then using that they can call the methods and can use the functionality written as
part of the BSE stock trade application(which is the application of BSE stock exchange). This ejb is within
the jndi registry of the BSE Stock Exchange and to access this ejb in jndi registry icicidirect.com servlet class
has to write the lookup logic and this lookup is called jndi lookup.
Then we have to pass factory implementation class that is provided by the platform and then P3 url and
then pass infrared of the platform and password of the platform to the Hashtable and pass the Hashtable
to InitialContext as props and when the InitialContext has been created with these values then we have get
the stockManager object
StockManager sm=context.lookup(“bse/sm”);
where bse/sm is the jndi name of the object which we have binded the jndi registry.
Now the InitialContext will takes the help of factory to acquire the original context object. Once the
original context object will receive then lookup will be called on original context. The context searches in
jndi and returns the object to InitialContext and InitialContext returns it to us.
If we are using weblogic then to use this jndi registry, we have to access this jndi registry using jndi context
object.
Every application server has their own jndi registry and to access this jndi registry, application server have
their own context object class and the context will connects to the jndi registry and performs the
operations.
So when the end user provide the name of the stock from the JSP page the request comes to
getStockPriceServlet and after getting the stock name servlet can not access details of the stock from the
database and to access it, servlet needs to get the reference of the stockManager and the stockManager is
with jndi registry and to get the stockManager from the jndi registry servlet has to perform the lookup
operations by connecting to jndi registry using context object and then after getting the object it will call
the getStockPrice() method of StockManager class
stockManager.getStockPrice(stockName), by passing the name of the stock and then it will return price of
the stockName
But We should not write the jndi logic directly in the icicidirect.com servlet because there are many more
classes in my application who want to talk to stock manager class in jndi registry and if we write the lookup
logic as part of our classes then we will face the following problems
1- If we write the lookup logic as part of several classes within our application then the logic will gets
duplicated across all the classes in our application, due to which huge maintenance cost will be encoured.
so we should avoid duplication of the logic.
[Type here]
50
2- The lookup logic which we have written is environment specific lookup so that if the remote server will
shift from one environment to other environment then there may be chance that username and password
of that environment will be different and there is some more difference in other environment so then
again we have to modify the lookup logic within several classes within our application.
3-The lookup logic we are writing is technology specific lookup so if our remote object has designed in EJB
technology then to get that object we have to perform jndi lookup and if the distributed technology
change from EJB to RMI or WebServices then the same jndi lookup logic will not work so again we have to
modify the code in all the classes within our application.
4- The lookup logic which we hace written as part of our classes is platform specific lookup i.e if our remote
object is running on weblogic server then we have to write the weblogic specific logic within all the classes
and if the application server change to other server like from weblogic to JBoss then the lookup logic in
accessing the object in both the server will not be same, it may be different so wde have to again modify
the lookup logic within all the classes within our application.
so we should not write the lookup logic within all the classes within our application we should write this
logic within a class called ServiceLocator. ServiceLocator is a class which locates the external application
system component and returns their reference to our class.
ServiceLocator is a design pattern which takes care of locating the remote server application component
and those references are brought down and it makes available to our application so that all the methods
and components of my application should not perform the saparate lookup, they will make use of the
ServiceLocator.
1- we have written the lookup logic in only one class within our application so that maintainability and
managability of the application will be easy so there will not any duplication of the logic within our
application.
2- If there will change in the environment then we dont have to modify all the classes within our
application just we have to modify ServiceLocator class.
3- As the remote object is technology specific so if the technology shift from EJB to RMI or WebServices
then we dont need to modify the all the classes within our application only we have to modify
ServiceLocator class in our application .
4- As the remote object is plateform specific so if the application server will change from weblogic to Jboss
then we have to modify only one class within our application not all the classes in our application.
so service locator protects our application from such kind of changes which are happening on the remote
application so that service locator shielded our application component so that maintainability of our
application will become easy. Apart from that ServiceLocator provide location transparency, in the location
transparency our class within our application directly talking to other remote server classes but they are
not directly getting the reference of the object but service locator get the reference of the remote server
[Type here]
51
object and our classes directly talking to ServiceLocator and will get the reference of that object and our
classes dont know that the reference which they are getting from ServiceLocator is the part of our
application or is it coming from remote server because they are not performing lookup or they are not
writing the logic for pulling the dependencies, in this way our application classes are completely abstracted
from remote object and
other advantage of ServiceLocator is serviceLocator can optimize the data while performing the lookup. To
optimize the data if the multiple requests are coming then like our servlet class it don’t have to connect to
server multiple times but it will connect to server one time and get the object and share the same object to
all the classes within our application so that we avoided costly lookup calls within our application and the
performance of the application will gets optimized.
ServiceLocator will be implemented at client side. the application which is providing the service is server
side application and the application which is consuming the service of the other application is called client
side application. as the client want the object so client have to write the lookup logic so the service locator
is the client side application.
The role of the Service Locator is to perform lookup operation only and after getting the remote object of
the StockManager class it will not call any method of that class rather after getting the remote object it will
return that object to our class.
StockAnalyzer.java
[Type here]
52
double price=0.0;
price= stockManager.getStockPrice(stockName);
System.out.println(price);
}
}
BSEStockTradeServiceLocator.java
//service locator
public class BseStockTradeServiceLocator {
IFMITest.java
}
Application-context.xml
<bean id="bseStockTradeServiceLocator"
class="com.ifmi.beans.BseStockTradeServiceLocator" />
<bean id="stockManager" factory-bean="bseStockTradeServiceLocator"
factory-method="locateStockManager" />
[Type here]
53
StockManagerImpl.java
@Override
public double getStockPrice(String stockName) {
double price=0.0;
But by performing above operation my classes will be tightly coupled with other
class because we are not creating the object but we are pulling the object of
StockManager class, and we should not create and we should not pull
StockManager into my class, rather we should inject the StockManager into
StockAnalyzer by using setter or constructor.
We can inject the stockManager into StockAnalyser if both have configured as
beans, but we can not configure stockManager as bean because it is an interface
and we can not declare its implementation class StockManagerImpl as bean
because StockManagerImpl class is not there with us, this class is with
application server in jndi registry so we can not create the object of this
class by calling the constructor of the class.
To get the object of the StockManager we need to go to ServiceLocator i.e.
Instantiate the ServiceLocator and call the factory method and factory method
will return the object and place that object in the ioc container so that it
inject into any application classes, this is called “Instance Factory Method
Instantiation”.
StockAnalyser.java
[Type here]
54
price = stockManager.getStockPrice(stockName);
System.out.println(price);
}
}
StockTradeServiceLocator.java
Application-context.xml
<bean id="stockTradeServiceLocator"
class="com.ifmiwa.beans.StockTradeServiceLocator" />
[Type here]
55
StockManager.java
BseStockManagerImpl.java
@Override
public double getStockPrice(String stockName) {
double price = 0.0;
NseStockManagerImpl.java
@Override
public double getStockPrice(String stockName) {
[Type here]
56
--The End--
[Type here]