Unraveling Hypertext_ Analyzing Postmodern Elements in Literature.pptx
Spring
1. Spring Framework
Atul Kahate
akahate@gmail.com
www.atulkahate.com
2. What is Spring?
Open source framework created by Rod Johnson
Created to ease the development of complex (enterprise)
application development
Makes the usage of plain JavaBeans possible where EJBs were
used earlier
POJO-based development
Modular in nature
2 Spring | Atul Kahate
3. Spring Features
Lightweight – Small in size (2.5 MB JAR file), very little
overheads in programming, Non-intrusive (no dependence on
Spring-specific classes)
Dependency Injection (DI) – Objects are passively provided with
their dependencies, rather than they having to actively search for
them (JNDI in the reverse)
Aspect-Oriented Programming (AOP) – Separate business logic
from generic services, such as security, transaction management,
etc
Container – Takes care of lifecycle and configuration of
applications
Framework – Possible to configure complex applications from
simple components with heavy usage of XML
3 Spring | Atul Kahate
5. Core Container
Defines how beans are created, configured, and managed
Contains the BeanFactory, which is the basis for the DI
concept
5 Spring | Atul Kahate
6. Application Context Module
Builds on the core container
Makes spring a framework
Extends the concept of BeanFactory, adding support for
internationalization, application lifecycle events, and
validation
Supplies services such as email, JNDI access, EJB access,
remoting, etc
6 Spring | Atul Kahate
7. AOP Module
Serves as the basis for developing our own aspects for Spring
applications
Supports loose coupling of application objects
Application-wide concerns such as transactions and security
are decoupled from the objects to which they are applied
7 Spring | Atul Kahate
8. JDBC Abstraction and DAO Module
JDBC coding involves opening of connection, processing
result sets, and closing connection
This Spring module abstracts away this code to make our
code simple
Issues such as not closing database connections etc are taken
care of
Provides a layer of abstraction to make database errors more
meaningful
Uses AOP module to provide transaction services
8 Spring | Atul Kahate
9. Object-Relational Mapping (ORM)
Integration Module
Can be used as an alternative to JDBC
Built over the DAO support for several ORM solutions, such
as Hibernate, Java Persistence API, iBatis, Java Data Objects,
etc
9 Spring | Atul Kahate
10. Java Management Extensions (JMX)
Allows exposing our application’s beans as JMX beans
Allows monitoring and reconfiguring a running application
10 Spring | Atul Kahate
11. Java EE Connector API (JCA)
JCA provides a standard way of integrating Java applications
with Mainframes, various databases, etc
Spring provides a layer on top of JCA
11 Spring | Atul Kahate
12. Spring MVC Framework
Spring can either integrate with an MVC framework such as
Struts, JSF etc; and has its own MVC framework
12 Spring | Atul Kahate
13. Spring Portlet MVC
Normal Web applications are request-response based
Portlets are applications that aggregate information on to a
single page, so that the request-response overhead is reduced
Spring provides support for these kinds of applications
13 Spring | Atul Kahate
14. Defining Beans in Spring
NetBeans package beanname
14 Spring | Atul Kahate
15. Usage of configuration files
In Spring, all beans need to be declared in a configuration file
This avoids hard coding of class creation code in our
applications
This code is moved to a single location – the XML
configuration file
Implementations can be changed without any changes to our
source code
Note:The current example will not do anything useful!
15 Spring | Atul Kahate
17. BeanNaming.java
package com.spring.beanname;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
public class BeanNaming {
public static void main(String[] args) {
BeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans3.xml"));
String s1 = (String)factory.getBean("string1");
String s2 = (String)factory.getBean("string2");
String s3 = (String)factory.getBean("java.lang.String");
}
}
17 Spring | Atul Kahate
18. BeanFatcory
The core of Spring's design is the org.springframework.beans
package, designed for use with JavaBean components.
The next-highest layer of abstraction is the BeanFactory interface,
an implementation of the Factory design pattern that enables
objects to be created and retrieved by name. BeanFactory can also
manage relationships between objects.
BeanFactory supports two object modes.
Singleton mode provides a shared instance of the object with a
particular name, which will be retrieved on lookup. Singleton is the
default and most often used object mode. It is ideal for stateless
service objects.
Prototype mode ensures that each retrieval will result in the
creation of an independent object. Prototype mode would be best
used in a case where each user needed to have his or her own object.
18 Spring | Atul Kahate
19. BeanFactory Interface
org.springframework.beans.factory.BeanFactory is a simple interface that can be
implemented for a range of underlying storage methods. The most commonly used
BeanFactory definition is the XmlBeanFactory, which loads beans based on definitions in
an XML file
BeanFactory factory = new XMLBeanFactory(new FileInputSteam("mybean.xml"));
Beans defined in XML files are lazily loaded, which means that the beans themselves will
not be instantiated until they are needed. To retrieve a bean from BeanFactory we can
simply call the getBean() method passing in the name of the bean we want to retrieve:
MyBean mybean = (MyBean) factory.getBean("mybean");
Each bean definition can be a POJO (defined by class name and JavaBean initialization
properties) or a FactoryBean. The FactoryBean interface adds a level of indirection to the
applications built using the Spring framework.
19 Spring | Atul Kahate
20. Hello World in Spring
D:AtulLecturesSICSRWeb TechnologiesWT-
2springSpring-examples-sicsr
21. Requirements
We need a service class
This simply means the class that has our business logic
To decouple the actual business logic from the caller, we can
also have an interface that would be implemented by the
service class
The caller would program to the interface to create a loosely
coupled logic
We also need the tester class to test our service class
Finally, we need an XML file for configuration
21 Spring | Atul Kahate
22. Hello World Depicted
Tester class
(HelloApp.java)
Service interface Service class
(GreetingService.java) (GreetingServiceImpl.java)
Configuration
(hello.xml)
22 Spring | Atul Kahate
23. Hello World Depicted
Tester class public class HelloApp {
(HelloApp.java)
public static void main (String [] args) throws
Exception {
BeanFactory factory = new XmlBeanFactory (new
FileSystemResource ("hello.xml"));
Configuration GreetingService greetingService =
<?xml version="1.0”?>
(hello.xml) (GreetingService) factory.getBean ("greetingService");
<beans>
<bean id="greetingService" greetingService.sayGreeting();
class="com.spring.hello.GreetingServiceIm }
pl">
<property name="greeting"
}
value="Hello World!" />
</bean>
</beans>
23 Spring | Atul Kahate
24. Understanding Tester Class – 1
BeanFactory factory = new XmlBeanFactory (new
FileSystemResource ("hello.xml"));
Tester class uses the BeanFactory, which is the Spring container
Here, we are asking the Spring container to load a file named
hello.xml into the container’s memory
The hello.xml file contains this:
<bean id="greetingService" class="com.spring.hello.GreetingServiceImpl">
<property name="greeting" value="Hello World!" />
</bean>
Indicates that some time later we want to (1) instantiate an object of
the GreetingServiceImpl class by the name greetingService, and (2)
call its setGreeting method, passing the value HelloWorld
See next slide
24 Spring | Atul Kahate
25. Understanding Tester Class – 2
Code
GreetingService greetingService = (GreetingService) factory.getBean
("greetingService");
XML file
<bean id="greetingService" class="com.spring.hello.GreetingServiceImpl">
<property name="greeting" value="Hello World!" />
</bean>
Now, these two are linked and our code obtains an instance of the
GreetingServiceImpl class in the form of a greetingService object
See next slide
25 Spring | Atul Kahate
26. Understanding Tester Class – 3
The following are thus equivalent:
<bean id="greetingService" class="com.spring.hello.GreetingServiceImpl">
<property name="greeting" value="Hello World!" />
</bean>
AND
GreetingServiceImpl greetingService = new GreetingServiceImpl ();
greetingService.setGreeting (“Hello World!”);
First is Spring-way of coding, the second is the traditional
method
26 Spring | Atul Kahate
27. Understanding Tester Class – 3
greetingService.sayGreeting();
We now call the sayGreeting method on the greetingService object
27 Spring | Atul Kahate
28. Understanding Dependency Injection
(DI)
Look at our XML file definition once again:
<bean id="greetingService" class="com.spring.hello.GreetingServiceImpl">
<property name="greeting" value="Hello World!" />
</bean>
We are injecting/feeding our bean with the desired value for
the greeting property
Traditionally, our bean needs to figure this out itself, not any
more
This is called as Dependency Injection (DI)
DI was originally called as Inversion of Control (IOC)
“Acquisition of dependencies” gets inverted
Hence, IOC was renamed to DI
28 Spring | Atul Kahate
29. Why DI?
Objects are provided their dependencies at creation time by
some external entity that coordinates each entity in the
application
Helps in making the application loosely coupled
If an object knows about its dependencies by the interfaces of
the dependencies (not based on their implementation or on
how they were created), then the dependency
implementation can be changed without the depending
object knowing about it
29 Spring | Atul Kahate
30. GreetingService.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.hello;
/**
*
* @author atulk
*/
public interface GreetingService {
void sayGreeting ();
}
30 Spring | Atul Kahate
31. GreetingServiceImpl.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.hello;
/**
*
* @author atulk
*/
public class GreetingServiceImpl implements GreetingService {
private String greeting;
public GreetingServiceImpl () {}
public GreetingServiceImpl (String greeting) {
this.greeting = greeting;
}
public void sayGreeting () {
System.out.println (greeting);
}
public void setGreeting (String greeting) {
this.greeting = greeting;
}
}
31 Spring | Atul Kahate
32. hello.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Document : hello.xml
Created on : May 26, 2008, 2:09 PM
Author : atulk
Description:
Purpose of the document follows.
-->
<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-2.5.xsd">
<bean id="greetingService" class="com.spring.hello.GreetingServiceImpl">
<property name="greeting" value="Hello World!" />
</bean>
</beans>
32 Spring | Atul Kahate
33. HelloApp.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.hello;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
/**
*
* @author atulk
*/
public class HelloApp {
public static void main (String [] args) throws Exception {
BeanFactory factory = new XmlBeanFactory (new FileSystemResource ("hello.xml"));
GreetingService greetingService = (GreetingService) factory.getBean ("greetingService");
greetingService.sayGreeting();
}
}
33 Spring | Atul Kahate
34. Another Example – Simple Interest
Calculation
package com.spring.simpleinterestcalculator
34 Spring | Atul Kahate
35. SimpleInterestCalculatorBean.java
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.simpleinterestcalculator ;
/**
*
* @author atulk
*/
class SimpleInterestCalculatorBean {
private float years;
private float principle;
private float rate;
SimpleInterestCalculatorBean() {
}
public void setYears(float years) {
this.years = years;
}
public float getYears() {
return years;
}
public void setPrinciple(float principle) {
this.principle = principle;
}
public float getPrinciple() {
return principle;
}
public void setRate(float rate) {
this.rate = rate;
}
public float calculate() {
return (float) ((principle * rate * years) / 100);
}
35 Spring | Atul Kahate
public float getInterest() {
return calculate();
}
37. Client.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.simpleinterestcalculator;
/**
*
* @author atulk
*/
import java.io.*;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.xml.*;
import org.springframework.core.io.*;
public class Client {
public static void main(String args[]) throws Exception {
try {
System.out.println("Starting interest calculator ...");
BeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans6.xml"));
SimpleInterestCalculatorBean interest =
(SimpleInterestCalculatorBean) factory.getBean("SimpleInterestBean");
System.out.println(interest.getInterest());
}
catch(Exception e1) {
System.out.println("" + e1);
}
}
}
37 Spring | Atul Kahate
38. Example of Traditional Coding Versus
Spring-style of Coding
NetBeans: Spring-IOC-Example
38 Spring | Atul Kahate
39. Requirement
We want to create a list of bank accounts, and then simply
display the details of all of them
39 Spring | Atul Kahate
40. Version 1 of the Code
Create an Account class, which will hold information about
the various accounts, such as account number,
accountholder’s name, opening balance, etc
Another class AccountMaster would create as many accounts as
we require in a hashmap
The Tester class tests the functionality by displaying
information about all accounts
40 Spring | Atul Kahate
41. Version 1
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.example.version.one;
/**
*
* @author atulk
*/
public class Account {
private String accountNumber;
private String accountName;
private int openingBalance;
private int currentBalance;
public Account(String accountNumber, String accountName, int openingBalance, int currentBalance) {
this.accountNumber = accountNumber;
this.accountName = accountName;
this.openingBalance = openingBalance;
this.currentBalance = currentBalance;
}
public String toString () {
return "Bank: " +
" Account number -- " + accountNumber +
" Account Name -- " + accountName +
" Opening Balance -- " + openingBalance +
" Current Balance -- " + currentBalance +
".n";
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
public int getCurrentBalance() {
return currentBalance;
}
41 Spring | Atul Kahate
public void setCurrentBalance(int currentBalance) {
this.currentBalance = currentBalance;
}
public int getOpeningBalance() {
42. Version 1
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.example.version.one;
import java.util.HashMap;
import java.util.Iterator;
/**
*
* @author atulk
*/
public class AccountMaster {
private String bankName;
HashMap accounts = new HashMap ();
public AccountMaster(String bankName) {
this.bankName = bankName;
System.out.println ("Bank name set to: " + this.bankName);
accounts.put ("100", new Account("1000", "test account 1", 1000, 10000));
accounts.put ("2000", new Account("2000", "test account 2", 2000, 20000));
accounts.put ("3000", new Account("3000", "test account 3", 3000, 30000));
accounts.put ("4000", new Account("4000", "test account 4", 4000, 40000));
accounts.put ("5000", new Account("5000", "test account 5", 5000, 50000));
accounts.put ("6000", new Account("6000", "test account 6", 6000, 60000));
System.out.println ("Exiting the constructor of GetAccount ...");
}
public String toString () {
return "This is for Bank: " + bankName;
}
public HashMap findAccounts () {
return accounts;
}
public Account findAccount (String accountNumber) {
Iterator iter = accounts.values().iterator();
while (iter.hasNext()) {
Account account = (Account) iter.next();
if (accountNumber.equals(account.getAcco untNum ber()))
return account;
}
return null;
}
}
42 Spring | Atul Kahate
43. Version 1
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.example.version.one;
import java.util.Iterator;
/**
*
* @author atulk
*/
public class Tester {
private AccountMaster findAccount;
public Tester () {
System.out.println ("1");
findAccount = new AccountMaster ("My Bank");
System.out.println ("2");
}
public void printAllAccounts () {
System.out.println (findAccount.toString());
Iterator iter = findAccount.findAccounts().values().iterator();
while (iter.hasNext()) {
Account account = (Account) iter.next();
System.out.println (account.toString());
}
}
public static final void main (String args []) {
Tester tester = new Tester ();
System.out.println ("After Tester");
tester.printAllAccounts();
}
}
43 Spring | Atul Kahate
44. Version 2 of the Code
Account class – No change
AccountMaster class – Is now an interface, instead of being a
concrete class
HashMapAccountMaster class – Implements AccountMaster
interface
OldTester – New class, which takes on the functionality of
the earlier Tester class
Tester – Modified to work with OldTester and AccountMaster
classes
44 Spring | Atul Kahate
45. Version 2
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.example.version.two;
/**
*
* @author atulk
*/
public class Account {
private String accountNumber;
private String accountName;
private int openingBalance;
private int currentBalance;
public Account(String accountNumber, String accountName, int openingBalance, int currentBalance) {
this.accountNumber = accountNumber;
this.accountName = accountName;
this.openingBalance = openingBalance;
this.currentBalance = currentBalance;
}
public String toString () {
return "Bank: " +
" Account number -- " + accountNumber +
" Account Name -- " + accountName +
" Opening Balance -- " + openingBalance +
" Current Balance -- " + currentBalance +
".n";
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
public int getCurrentBalance() {
return currentBalance;
}
45 Spring | Atul Kahate
public void setCurrentBalance(int currentBalance) {
this.currentBalance = currentBalance;
}
public int getOpeningBalance() {
46. Version 2
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.example.version.two;
import java.util.HashMap;
/**
*
* @author atulk
*/
public interface AccountMaster {
HashMap getAccounts ();
public Account getAccount (String accountNumber);
}
46 Spring | Atul Kahate
47. Version 2
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.example.version.two;
import java.util.HashMap;
import java.util.Iterator;
/**
*
* @author atulk
*/
public class HashMapAccountMaster implements AccountMaster {
private String bankName;
HashMap accounts = new HashMap ();
public HashMapAccountMaster(String bankName) {
this.bankName = bankName;
System.out.println ("Bank name set to: " + this.bankName);
accounts.put ("100", new Account("1000", "test account 1", 1000, 10000));
accounts.put ("2000", new Account("2000", "test account 2", 2000, 20000));
accounts.put ("3000", new Account("3000", "test account 3", 3000, 30000));
accounts.put ("4000", new Account("4000", "test account 4", 4000, 40000));
accounts.put ("5000", new Account("5000", "test account 5", 5000, 50000));
accounts.put ("6000", new Account("6000", "test account 6", 6000, 60000));
System.out.println ("Exiting the constructor of GetAccount ...");
}
public String toString () {
return "This is for Bank: " + bankName;
}
public HashMap getAccounts () {
return accounts;
}
public Account getAccount (String accountNumber) {
Iterator iter = accounts.values().iterator();
while (iter.hasNext()) {
Account account = (Account) iter.next();
if (accountNumber.equals(account.getAcco untNum ber()))
return account;
}
return null;
}
47 Spring | Atul Kahate
}
48. Version 2
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.example.version.two;
import java.util.Iterator;
/**
*
* @author atulk
*/
public class OldTester {
private AccountMaster accountMaster;
public OldTester () {
}
public void setAccountMaster (AccountMaster accountMaster) {
this.accountMaster = accountMaster;
}
public AccountMaster getAccountMaster () {
return this.accountMaster;
}
public void printAllAccounts () {
System.out.println (accountMaster.toString());
Iterator iter = accountMaster.getAccounts().values().iterator();
while (iter.hasNext()) {
Account account = (Account) iter.next();
System.out.println (account.toString());
}
}
}
48 Spring | Atul Kahate
49. Version 2
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.example.version.two;
/**
*
* @author atulk
*/
public class Tester {
public static final void main(String args[]) {
OldTester oldTester = new OldTester();
AccountMaster accountMaster = new HashMapAccountMaster("My Bank");
oldTester.setAccountMaster(accountMaster);
oldTester.printAllAccounts();
}
}
49 Spring | Atul Kahate
50. Version 3 of the Code
Using Spring
Account class – No change
AccountMaster class – No change
HashMapAccountMaster class – No change
OldTester class – No change
Tester class – Makes use of BeanFactory now
50 Spring | Atul Kahate
51. Version 3
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.example.version.three;
/**
*
* @author atulk
*/
public class Account {
private String accountNumber;
private String accountName;
private int openingBalance;
private int currentBalance;
public Account(String accountNumber, String accountName, int openingBalance, int currentBalance) {
this.accountNumber = accountNumber;
this.accountName = accountName;
this.openingBalance = openingBalance;
this.currentBalance = currentBalance;
}
public String toString () {
return "Bank: " +
" Account number -- " + accountNumber +
" Account Name -- " + accountName +
" Opening Balance -- " + openingBalance +
" Current Balance -- " + currentBalance +
".n";
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
public int getCurrentBalance() {
return currentBalance;
}
51 Spring | Atul Kahate
public void setCurrentBalance(int currentBalance) {
this.currentBalance = currentBalance;
}
public int getOpeningBalance() {
52. Version 3
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.example.version.three;
import java.util.HashMap;
/**
*
* @author atulk
*/
public interface AccountMaster {
HashMap getAccounts ();
public Account getAccount (String accountNumber);
}
52 Spring | Atul Kahate
53. Version 3
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.example.version.three;
import java.util.HashMap;
import java.util.Iterator;
/**
*
* @author atulk
*/
public class HashMapAccountMaster implements AccountMaster {
private String bankName;
private HashMap accounts = new HashMap ();
public HashMapAccountMaster (String bankName) {
System.out.println ("inside ...");
populateAccounts ();
}
public String toString () {
return "This is for Bank: " + bankName;
}
public HashMap getAccounts () {
return accounts;
}
public Account getAccount (String accountNumber) {
Iterator iter = accounts.values().iterator();
while (iter.hasNext()) {
Account account = (Account) iter.next();
if (accountNumber.equals(account.getAcco untNum ber()))
return account;
}
return null;
}
public String getBankName () {
return bankName;
}
public void setBankName (String bankName) {
this.bankName = bankName;
}
Spring | Atul Kahate
public void populateAccounts () {
53 System.out.println ("initializing hashmap");
accounts.put ("1000", new Account("1000", "test account 1", 1000, 10000));
accounts.put ("2000", new Account("2000", "test account 2", 2000, 20000));
accounts.put ("3000", new Account("3000", "test account 3", 3000, 30000));
accounts.put ("4000", new Account("4000", "test account 4", 4000, 40000));
54. Version 3
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.example.version.three;
import java.util.Iterator;
/**
*
* @author atulk
*/
public class OldTester {
private AccountMaster accountMaster;
public OldTester () {
}
public void setAccountMaster (AccountMaster accountMaster) {
this.accountMaster = accountMaster;
}
public AccountMaster getAccountMaster () {
return this.accountMaster;
}
public void printAllAccounts () {
System.out.println (accountMaster.toString());
54 Spring Iterator iter =Kahate
| Atul accountMaster.getAccounts().values().iterator();
while (iter.hasNext()) {
Account account = (Account) iter.next();
System.out.println (account.toString());
55. Version 3
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.example.version.three;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
/**
*
* @author atulk
*/
public class Tester {
public static final void main(String args[]) {
BeanFactory factory = new XmlBeanFactory (new FileSystemResource ("beans.xml"));
OldTester oldTester = (OldTester) factory.getBean ("oldTester");
oldTester.printAllAccounts();
}
}
55 Spring | Atul Kahate
56. Version 3
// Beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Document : hello.xml
Created on : May 26, 2008, 2:09 PM
Author : atulk
Description:
Purpose of the document follows.
-->
<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-2.5.xsd">
<bean id="accountMaster"
class="com.example.version.three.HashMapAccountMaster">
<constructor-arg><value>My Bank</value></constructor-arg>
</bean>
<bean id="oldTester"
class="com.example.version.three.OldTester">
<property name="accountMaster"><ref bean="accountMaster" /></property>
</bean>
</beans>
56 Spring | Atul Kahate
60. Client.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.forex;
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.io.*;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.xml.*;
import org.springframework.core.io.*;
public class Client {
public static void main(String args[]) throws Exception {
try {
System.out.println("Starting interest calculator ...");
BeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans7.xml"));
ForexData forexData =
(ForexData) factory.getBean("ForexData");
System.out.println("Exchange rate between " + forexData.getFromCurrency() +
" and " + forexData.getToCurrency() + " is " + forexData.getExchangeRate());
}
catch(Exception e1) {
System.out.println("" + e1);
}
}
}
60 Spring | Atul Kahate
61. Department and Employee Example
NetBeans Spring-examples-sicsr
Package com.spring.deptandemp
61 Spring | Atul Kahate
62. Department.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.deptandemp;
/**
*
* @author AtulK
*/
public class Department {
String deptID;
String deptName;
Employee employee;
public String getDeptID() {
return deptID;
}
public void setDeptID(String deptID) {
this.deptID = deptID;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public Department(String deptID, String deptName, Employee employee) {
this.deptID = deptID;
this.deptName = deptName;
this.employee = employee;
}
public Department() {
}
62 Spring | Atul Kahate
}
63. Employee.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.deptandemp;
/**
*
* @author AtulK
*/
public class Employee {
private String empID;
private String empName;
private int salary;
public String getEmpID() {
return empID;
}
public void setEmpID(String empID) {
this.empID = empID;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public Employee() {
}
}
63 Spring | Atul Kahate
64. Tester.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.deptandemp;
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.io.*;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.xml.*;
import org.springframework.core.io.*;
public class Tester {
public static void main(String args[]) throws Exception {
try {
System.out.println("Starting department and employee application ...");
BeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans10.xml"));
Department department =
(Department) factory.getBean("departmentBean");
System.out.println("Department " + department.getDeptName()+ " has employee " +
department.employee.getEmpName());
}
catch(Exception e) {
System.out.println("Exception occurred!!! " + e);
}
}
}
64 Spring | Atul Kahate
65. beans10.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-2.5.xsd">
<bean id="employeeBean"
class="com.spring.deptandemp.Employee">
<property name = "empID">
<value>999</value>
</property>
<property name = "empName">
<value>My Employee Name</value>
</property>
<property name = "salary">
<value>5000</value>
</property>
</bean>
<bean id="departmentBean"
class="com.spring.deptandemp.Department">
<property name = "deptID">
<value>100</value>
</property>
<property name = "deptName">
<value>My Department</value>
</property>
<property name = "employee">
<ref bean = "employeeBean"></ref>
</property>
</bean>
</beans>
65 Spring | Atul Kahate
66. DI in detail
Passing one object to another as a DI
NetBeans package com.spring.hello.di
67. Real-life DI
In real-life DI, we pass the object of one class to another
object of a different class as a DI
This way, if A is passed to B, B does not need to worry about
how A was created, etc
A’s implementation can be changed freely from a simple bean
to an EJB to a Web service etc
Again, this can be done by using simple configurations in an
XML file
67 Spring | Atul Kahate
68. Understanding the example
injected into
Model class
(provider)
<beans> View class
<bean id="provider" class="HelloWorldModel"> (renderer)
<constructor-arg>
<value>This is a configurable message</value>
</constructor-arg>
</bean>
<bean id="renderer" class="StandardOutView">
<property name="model">
<ref local="provider"/>
</property>
</bean>
</beans>
68 Spring | Atul Kahate
69. Our Model
Model.java (Interface)
public interface Model {
public String getMessage();
}
HelloWorldModel.java (Implementation)
public class HelloWorldModel implements Model {
String mess;
public HelloWorldModel(String m){
mess = m;
}
public String getMessage() {
return mess;
}
}
69 Spring | Atul Kahate
70. Our View
View.java (Interface)
public interface View {
public void render();
public void setModel(Model m);
public Model getModel();
}
StandardOutView.java (Implementation)
public class StandardOutView implements View {
private Model model = null;
public void render() {
if (model == null) {
throw new RuntimeException(
"You must set the property model of class:"
+ StandardOutView.class.getName());
}
System.out.println(model.getMessage());
}
public void setModel(Model m) {
this.model = m;
}
public Model getModel() {
return this.model;
}
}
70 Spring | Atul Kahate
71. Our XML configuration file
Beans.xml
<!DOCTYPE beans PUBLIC "-
//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-
beans.dtd">
<beans>
<bean id="provider" class="HelloWorldModel">
<constructor-arg>
<value>This is a configurable message</value>
</constructor-arg>
</bean>
<bean id="renderer" class="StandardOutView">
<property name="model">
<ref local="provider"/>
</property>
</bean>
</beans>
71 Spring | Atul Kahate
73. Injecting by DI Example
NetBeans package com.spring.simpleinjectbydi
73 Spring | Atul Kahate
74. ClientTester.java
public class ClientTester {
private String name;
private int age;
…
public static void main(String[] args) {
BeanFactory factory = new XmlBeanFactory(new FileSystemResource(“beans2.xml"));
ClientTester simple = (ClientTester)factory.getBean("clientTester");
factory.getBean("injectRef");
System.out.println(simple);
}
// set methods for all attributes of this class
}
beans2. xml
<bean id="clientTester" class="com.spring.simpleinjectbydi.ClientTester">
<property name="name">
<value>Kishore Kumar</value>
</property>
…
</bean>
74 Spring | Atul Kahate
75. ClientTester.java
public class ClientTester {
private String name;
private int age;
…
public static void main(String[] args) {
BeanFactory factory = new XmlBeanFactory(new FileSystemResource(“beans2.xml"));
ClientTester simple = (ClientTester)factory.getBean("clientTester");
factory.getBean("injectRef");
System.out.println(simple);
}
// set methods for all attributes of this class
}
beans2. xml
<bean id="injectRef" class="com.spring.simpleinjectbydi.InjectRef">
<property name="info">
<ref local="infobyid"/>
</property>
</bean>
75 Spring | Atul Kahate
76. InjectRef.java
public class InjectRef {
private Info info;
public void setInfo (Info info) {
this.info = info;
System.out.println(info.getInfo());
}
}
InfoImpl.java
public class InfoImpl implements Info {
Info.java
private Encyclopedia enc;
public interface Info {
public String getInfo ();
public void setEncyclopedia(Encyclopedia enc) {
}
this.enc = enc;
}
public String getInfo () {
return "Encyclopedia's are a waste of money - use the Internet";
}
}
76 Spring | Atul Kahate
77. InfoImpl.java
public class InfoImpl implements Info {
private Encyclopedia enc;
public void setEncyclopedia(Encyclopedia enc) {
this.enc = enc;
}
public String getInfo () {
return "Encyclopedia's are a waste of money - use the Internet";
}
}
public class Encyclopedia {
}
77 Spring | Atul Kahate
78. Encylopedia.java
Deliberately kept empty
public class Encyclopedia {
}
78 Spring | Atul Kahate
79. Info.java
public interface Info {
public String getInfo ();
}
79 Spring | Atul Kahate
80. InfoImpl.java
public class InfoImpl implements Info {
private Encyclopedia enc;
public void setEncyclopedia(Encyclopedia enc) {
this.enc = enc;
}
public String getInfo () {
return "Encyclopedia's are a waste of money - use the Internet";
}
}
80 Spring | Atul Kahate
81. InjectRef.java
public class InjectRef {
private Info info;
public void setInfo (Info info) {
this.info = info;
System.out.println(info.getInfo());
}
}
81 Spring | Atul Kahate
82. ClientTester.java
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
public class ClientTester {
private String name;
private int age;
private float height;
private boolean isProgrammer;
private Long ageInSeconds;
public static void main(String[] args) {
BeanFactory factory = new XmlBeanFactory(new FileSystemResource(
"beans2.xml"));
ClientTester simple = (ClientTester)factory.getBean("clientTester");
factory.getBean("injectRef");
System.out.println(simple);
}
public void setAgeInSeconds(Long ageInSeconds) {
this.ageInSeconds = ageInSeconds;
}
public void setIsProgrammer(boolean isProgrammer) {
this.isProgrammer = isProgrammer;
82 Spring | Atul Kahate
}
public void setAge(int age) {
this.age = age;
86. Bean initialization and destruction
It may be necessary to perform some initialization logic when
a bean in instantiated
Similarly, when a bean is to be destroyed, some clean up
operations may be required
We need to use the init-method and destroy-method parameters
for our bean
They specify the methods to be called during initialization
and destruction, respectively
86 Spring | Atul Kahate
88. SimpleBean.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.beaninitdestroy;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
public class SimpleBean {
private static final String DEFAULT_NAME = "Atul Kahate";
private String name = null;
private int age = Integer.MIN_VALUE;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void initOurBean () {
System.out.println("Initializing bean");
88 Spring | Atul Kahate
if (name == null) {
System.out.println("Using default name");
name = DEFAULT_NAME;
92. SimpleTarget.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.beanhierarchy;
/**
*
* @author atulk
*/
public class SimpleTarget {
private String val;
public void setVal(String val) {
this.val = val;
}
public String getVal() {
return val;
}
}
92 Spring | Atul Kahate
93. Specifying Bean Dependencies
The ref element is used to set the value of a property or a
constructor argument to be a reference to another bean from the
factory, or from a parent factory:
<ref local=“injectBean” />
<ref bean=“injectBean” />
<ref parent=“injectBean” />
local, bean, and parent are mutually exclusive and must be the ID of
another bean – they specify how to locate that referenced bean
local – Referred bean must be in the same XML file – parser validates this
bean - Referred bean can be in the same XML file or in a different XML file –
Spring framework validates this
parent – Referred bean must come from a parent factory to the current one
93 Spring | Atul Kahate
94. Understanding the example – 1
HierarchicalBeanFactoryUsage.java
BeanFactory parent = new XmlBeanFactory(new
FileSystemResource("parent.xml"));
Loads the parent.xml file
BeanFactory child = new XmlBeanFactory(new
FileSystemResource("beans5.xml"), parent);
Loads the beans5.xml file, with parent as its parent factory
94 Spring | Atul Kahate
95. Understanding the example – 2
SimpleTarget target1 = (SimpleTarget) child.getBean("target1");
Definition for this bean in beans5.xml is as follows:
<bean id="target1" class="com.spring.beanhierarchy.SimpleTarget">
<property name="val">
<ref bean="injectBeanParent"/>
</property>
</bean>
Indicates that injectBeanParent should be passed to it as a parameter
Definition of injectBeanParent in parent.xml is as follows:
<bean id="injectBeanParent" class="java.lang.String">
<constructor-arg>
<value>Bean In Parent</value>
</constructor-arg>
</bean>
Hence, a string Bean In Parent would be passed to the target1 bean
95 Spring | Atul Kahate
96. Understanding the example – 3
SimpleTarget target2 = (SimpleTarget) child.getBean("target2");
Definition for this bean in beans5.xml is as follows:
<bean id="target2" class="com.spring.beanhierarchy.SimpleTarget">
<property name="val">
<ref local="injectBean"/>
</property>
</bean>
Indicates that injectBean should be passed to it as a parameter
Definition of injectBean is defined in the same XML file:
<bean id="injectBean" class="java.lang.String">
<constructor-arg>
<value>Bean In Child</value>
</constructor-arg>
</bean>
Hence, a string Bean In Child would be passed to the target1 bean
Note: injectBean is also defined in parent.xml. But it would be ignored, as we
have specified injectBean also in the local file (beans5.xml) and we have used
ref local in the target2 definition
96 Spring | Atul Kahate
97. Understanding the example – 4
Note: injectBean is also defined in parent.xml. But it would be
ignored, as we have specified injectBean also in the local file
(beans5.xml) and we have used ref local in the target2 definition
Carrying this forward, now do the following changes in beans5.xml and see if the
result changes – why?
<bean id="target2" class="com.spring.beanhierarchy.SimpleTarget">
<property name="val">
<ref bean="injectBean"/>
</property>
</bean>
AND
<!-- <bean id="injectBean" class="java.lang.String">
<constructor-arg>
<value>Bean In Child</value>
</constructor-arg>
</bean> -->
97 Spring | Atul Kahate
98. Understanding the example – 5
SimpleTarget target3 = (SimpleTarget) child.getBean("target3");
Definition for this bean in beans5.xml is as follows:
<bean id="target3" class="com.spring.beanhierarchy.SimpleTarget">
<property name="val">
<ref parent="injectBean"/>
</property>
</bean>
Indicates that injectBean must be obtained from parent factory – ignore local
instance of injectBean, if exists
Definition of injectBean from parent.xml file:
<bean id="injectBean" class="java.lang.String">
<constructor-arg>
<value>Bean In Parent</value>
</constructor-arg>
</bean>
Hence, a string Bean In Parent would be passed to the target1 bean
98 Spring | Atul Kahate
102. Need for AOP – A Case Study
102 Spring | Atul Kahate
103. Account Case Study
Suppose we want to develop a class that has two methods that
allow depositing and withdrawing of money to and from a
bank account
Sample implementation on next page
103 Spring | Atul Kahate
104. Account Class – Sample Implementation
public class Account{
public long deposit(long depositAmount){
newAmount = existingAmount + depositAmount;
currentAmount = newAmount;
return currentAmount;
}
public long withdraw(long withdrawalAmount){
if (withdrawalAmount <= currentAmount){
currentAmount = currentAmount – withdrawalAmount;
}
return currentAmount;
}
}
104 Spring | Atul Kahate
105. Need to Add Security
Suppose we now want to ensure that only the administrator
user can perform the deposit and withdrawal transactions
Hence, we need to first check which user is invoking these
methods and then allow/disallow based on the user
type/role
Suppose we have a User class that returns the user id, by
calling the appropriate method
We can modify our implementation as shown next
105 Spring | Atul Kahate
106. Modified Account Class
public class Account{
public long deposit(long depositAmount){
User user = User.getUser();
if (user.getRole().equals("BankAdmin"){
newAmount = existingAccount + depositAccount;
currentAmount = newAmount;
}
return currentAmount;
}
public long withdraw(long withdrawalAmount){
User user = User.getUser();
if (user.getRole().equals("BankAdmin"){
if (withdrawalAmount <= currentAmount){
currentAmount = currentAmount – withdrawalAmount;
}
}
return currentAmount;
106 Spring | Atul Kahate
}
}
107. Need to Add Transaction and Logging
Capabilities
Suppose now we want to add transaction support and logging
support to our Account class
Modified code shown next
107 Spring | Atul Kahate
108. Modified Account Class
public class Account{
public long deposit(long depositAmount){
logger.info("Start of deposit method");
Transaction trasaction = Transaction.getTransaction();
transaction.begin();
try{
User user = User.getUser();
if (user.getRole().equals("BankAdmin"){
newAmount = existingAccount + depositAccount;
currentAmount = newAmount;
}
transaction.commit();
}catch(Exception exception){
transaction.rollback();
}
logger.info("End of deposit method");
return currentAmount;
}
public long withdraw(long withdrawalAmount){
logger.info("Start of withdraw method");
Transaction trasaction = Transaction.getTransaction();
transaction.begin();
try{
User user = User.getUser();
if (user.getRole().equals("BankAdmin"){
if (withdrawalAmount <= currentAmount){
currentAmount = currentAmount – withdrawalAmount;
}
108 Spring | Atul Kahate
}
transaction.commit();
}catch(Exception exception){
transaction.rollback();
109. Observations
As we can see, as we keep on making changes to our code, it
becomes more and more complex
Involves re-testing of the entire code
Actual business logic is very small – the other aspects
consume majority of code and logic
Can this be avoided?
Let us revisit what our code is actually doing step-by-step
109 Spring | Atul Kahate
110. Steps in Our Code
public void deposit(){
// Transaction Management
// Logging
// Checking for the Privileged User
// Actual Deposit Logic comes here
}
public void withdraw(){
// Transaction Management
// Logging
// Checking for the Privileged User
// Actual Withdraw Logic comes here
}
110 Spring | Atul Kahate
111. Enter AOP
In AOP terms, these aspects such as transaction
management, user role checking, logging, etc should be
separated into separate blocks of code
Our actual code should just concentrate on the business logic
See next slide
111 Spring | Atul Kahate
112. These are aspects
public void businessOperation(BusinessData data){
// Logging
logger.info("Business Method Called");
// Transaction Management Begin
transaction.begin();
// Do the original business operation here
…
…
// Transaction Management End
transaction.end();
}
112 Spring | Atul Kahate
113. Join Points – Places where we can look
for Aspects
public void someBusinessOperation(BusinessData data){
//Method Start -> Possible aspect code here like logging.
try{
// Original Business Logic here.
}catch(Exception exception){
// Exception -> Aspect code here when some exception is raised.
}finally{
// Finally -> Even possible to have aspect code at this point too.
}
// Method End -> Aspect code here in the end of a method.
}
113 Spring | Atul Kahate
114. Pointcut – Join Point where an Aspect
would actually be applied
pointcut method_start_end_pointcut(){
// This point cut applies the aspects, logging and transaction, before the
// beginning and the end of the method.
}
pointcut catch_and_finally_pointcut(){
// This point cut applies the aspects, logging and transaction, in the catch
// block (whenever an exception raises) and the finally block.
}
114 Spring | Atul Kahate
115. Advice
We can roughly say that Aspect is the concept, which is
implemented by an Advice
Aspect is abstract, Advice is concrete
Following Advice types are supported in Spring:
Before Advice
After Advice
Throws Advice
Around Advice
115 Spring | Atul Kahate
116. Before Advice
Intercepts a method before it starts execution
The org.springframework.aop.BeforeAdvice interface is used
to represent this
Example: Authenticate the user before allowing the user to
perform deposit or withdraw transaction
116 Spring | Atul Kahate
117. After Advice
Intercepts a method before it returns control back to the
caller
The org.springframework.aop.AfterReturningAdvice
interface is used to represent this
Example: Delete session data before sending control back to
the caller
117 Spring | Atul Kahate
118. Throws Advice
Intercepts a method when it attempts to throw an exception
The org.springframework.aop.ThrowsAdvice interface is
used to represent this
Example: Delete session data before sending control back to
the caller
118 Spring | Atul Kahate
119. Around Advice
Provides finer control over the execution of a method
The org.aopalliance.intercept.MethodInterceptor interface is
used to represent this
Example: Delete session data before sending control back to
the caller
119 Spring | Atul Kahate
120. AOP Case Study
NetBeans package com.spring.empwithoutaop
120 Spring | Atul Kahate
121. Requirement
We need to represent the details of an employee
We can create an Employee interface that captures the essential
details of the employee and a concrete class named
EmployeeImpl that implements this interface
We can then use the standard new approach to create an
instance of EmployeeImpl
121 Spring | Atul Kahate
122. Employee.java
public interface Employee {
public String getFirstName();
public void setFirstName(String FirstName);
public String getLastName();
public void setLastName(String LastName);
public String getJobTitle();
public void setJobTitle(String JobTitle);
public Float getSalary();
public void setSalary(Float Salary);
public Date getHiredate();
public void setHiredate(Date Hiredate);
}
122 Spring | Atul Kahate
123. EmployeeImpl.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.empwithoutaop;
import java.util.Date;
/**
*
* @author atulk
*/
import java.util.Date;
public class EmployeeImpl implements Employee {
String FirstName;
String LastName;
String JobTitle;
Float Salary;
Date Hiredate;
public EmployeeImpl() {
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String FirstName) {
123 Spring | Atul Kahate
this.FirstName = FirstName;
}
public String getLastName() {
124. Client.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.empwithoutaop;
/**
*
* @author atulk
*/
public class Client {
public Client() {
}
public Employee getEmployee() {
Employee emp = new EmployeeImpl();
return emp;
}
public static void main(String[] args) {
Client client = new Client();
Employee employee = client.getEmployee();
employee.setFirstName("Ram");
employee.setLastName("Shastri");
employee.setJobTitle("SALESMAN");
employee.setSalary(new Float("5000"));
System.out.println("The new salary for " + employee.getFirstName() + " " + employee.getLastName() + " (" + employee.getJobTitle() + ") = " + employee.getSalary());
}
}
124 Spring | Atul Kahate
125. New Business Rules
Now suppose there were some business rules that needed to
be applied:
A Salesman may not earn more than 4000
Ram Shastri is not an acceptable name for an employee
If we have source code, we can make changes – even then it is
not easy
If we do not have source code but have just the JAR, things
are worse
AOP can help resolve this easily
125 Spring | Atul Kahate
126. Using ProxyFactory
Instead of getting hold of an EmployeeImpl object, we have a Spring ProxyFactory intervene and
wrap the EmployeeImpl in a proxy object.
We let the proxy intercept calls to setter methods, verify their validity and throw an exception for
incorrect values
When the validation succeeds, the setter method on the EmployeeImpl object is invoked as we
intended all along.
For this, we need a class that implements the Spring MethodBeforeAdvice interface. We can inject
this class into the ProxyFactory; this instructs the ProxyFactory to intercept any call to methods on
the EmployeeImpl object and call the before() method on the MethodBeforeAdvice before
continuing with the original call to the EmployeeImpl method.
So in short, the steps are:
Specify the Employee “domain interface”
Acquire implementation of the Employee Interface (EmployeeImpl)
Create an implementation of the MethodBeforeAdvice interface that handles Validation of Business
Rules in its before method
Have the application invoke the Spring AOP ProxyFactory to return a proxy wrapping the Employee
instance, after instructing the ProxyFactorythat the MethodBeforeAdvice should be applied to the
proxy
From the application, Invoke the getters and setters on the Employee instance - the proxied
EmployeeImpl
126 Spring | Atul Kahate
127. New Class – EmployeeValidator.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.empwithoutaop;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class EmployeeValidator implements MethodBeforeAdvice {
public EmployeeValidator() {}
public void before(Method method, Object[] args, Object target) throws Throwable {
Employee emp = (EmployeeImpl) target;
if (method.getName().equalsIgnoreCase("setSalary")) {
if ("SALESMAN".equalsIgnoreCase(emp.getJobTitle())) {
// if the job of this employee is SALESMAN, he/she may not earn more than 4000
float newSalary = ((Float) args[0]).floatValue();
if (newSalary > 4000) {
throw new RuntimeException("Salary may not exceed 4000 for Salesmen such as " + emp.getFirstName() + " " + emp.getLastName());
}
}
}
if (method.getName().equalsIgnoreCase("setFirstName")) {
if ("Ram".equalsIgnoreCase(emp.getLastName())) {
// we do not want any employee to be called John Doe
if ("Shastri".equalsIgnoreCase((String) args[0])) {
throw new RuntimeException("Employees should not be called Ram Shastri. Choose another First Name please.");
}
127 Spring |} Atul Kahate
}
if (method.getName().equalsIgnoreCase("setLastName")) {
if ("Ram".equalsIgnoreCase(emp.getFirstName())) {
128. New Client – ClientWithAOP.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.spring.empwithoutaop;
import org.springframework.aop.framework.ProxyFactory;
public class ClientWithAOP {
public Employee getEmployee() {
Employee emp = new EmployeeImpl();
ProxyFactory pf = new ProxyFactory();
pf.setTarget(emp);
pf.setInterfaces(new Class[]{Employee.class}); // this line is required for using the JDK 1.3 proxy based Spring AOP implementation,
//otherwise the CGLib libraries are required
pf.addAdvice(new EmployeeValidator());
return (Employee) pf.getProxy();
}
public ClientWithAOP() {
}
public static void main(String[] args) {
ClientWithAOP client = new ClientWithAOP();
Employee employee = client.getEmployee();
employee.setFirstName("Rahul");
employee.setLastName("Dravid");
employee.setJobTitle("SALESMAN");
employee.setSalary(new Float("5000"));
128 Spring System.out.println("The new salary for " + employee.getFirstName() + " " + employee.getLastName() + " (" + employee.getJobTitle() + ") = " + employee.getSalary());
| Atul Kahate
}
}
130. AOP Joinpoint
Point in the control flow of a program
We can identify Joinpoints and insert additional logic at those
Joinpoint's
Examples of Jointpoint's (place at which the main logic meets
with aspects such as logging, transaction, security, etc)
Method invocation
Class initialization
Object initialization
Set of Joinpoints creates a pointcut
130 Spring | Atul Kahate
131. AOP Advice
The code that is executed at a particular joinpoint
That is, specifies what to do at a join point
Some additional behavior that Spring injects around a method
invocation, defined in a method interceptor
Types of Advice
before advice, which executes before joinpoint
after advice, which executes after joinpoint
around advice, which executes around joinpoint
131 Spring | Atul Kahate
132. AOP Pointcuts
A collection of joinpoints that we use to define when advice
should be executed
By creating pointcuts, you gain fine-grained control over how
we apply advice to the components
Example
A typical joinpoint is a method invocation.
A typical pointcut is a collection of all method invocations in a
particular class
Pointcuts can be composed in complex relationships to
further constrain when advice is executed
132 Spring | Atul Kahate
133. AOP Aspect
An aspect is the combination of advice and pointcuts
133 Spring | Atul Kahate
134. AOP Weaving
Process of actually inserting aspects into the application code
at the appropriate point
Types of Weaving
Compile time weaving
Runtime weaving
134 Spring | Atul Kahate
135. AOP Target
An object whose execution flow is modified by some AOP
process
They are sometimes called advised object
135 Spring | Atul Kahate
136. Implementing AOP
Process by which you can modify the structure of an object
by introducing additional methods or fields to it
You use the Introduction to make any object implement a
specific interface without needing the object's class to
implement that interface explicitly
136 Spring | Atul Kahate
137. Types of AOP
Static AOP
The weaving process forms another step in the build process for
an application
Example: In Java program, you can achieve the weaving process
by modifying the actual bytecode of the application changing
and modifying code as necessary
Dynamic AOP
The weaving process is performed dynamically at runtime
Easy to change the weaving process without recompilation
137 Spring | Atul Kahate
138. AOP Implementation Details
Based on proxies
When we want to create an advised instance of a class, we must
use the ProxyFactory class to create a proxy of an instance of that
class, first providing the ProxyFactory with all the aspects that we
want to be woven into the proxy
We typically use ProxyFactoryBean class to provide declarative
proxy creation
138 Spring | Atul Kahate