Dependency Injection(DI)
One of the most striking features of Spring, is the way loose coupling between the components has been achieved. The modules are made independent by keeping them abstract. The values / dependencies are injected to them through the underlying Spring framework’s IOC container.
Three types of dependency Injection are available.
1. Setter injection
2. Constructor injection
3. Interface injection
The value can be set using either constructor injection or setter injection.
Setter injection | Constructor injection |
| 1. All the attributes that the constructor expects as parameter has to be injected.
|
2. If a specific attribute is set using constructor as well as setter injection, then the setter injected value overrides the other one. | 2. Constructor injected values cannot override setter injected values.
|
In the next tutorials to come, we will see in detail as to what exactly these two types of injection are and also try out hands on exercise about using these injection methods.
Read More
Spring AOP – Around Advice
|
This can be mentioned as a collation of the before mentioned advices. It does functionality of before, after and throws.
** UPDATE: Spring Complete tutorial now available here.
Step 1 :
No major changes in the Iterator and IteratorImpl classes.
File : Iterator.java
package com.simpleCodeStuffs.aop; public interface Iterator { void goPrevious(); void goNext(); }
File : IteratorImpl.java
package com.simpleCodeStuffs.aop; public class IteratorImpl implements Iterator{ String flowName; public void goNext() { System.out.println("goNext Method Called on flow - "+flowName); } public void goPrevious(){ System.out.println("goPrevious Method called on flow - "+flowName); } public String getFlowName() { return flowName; } public void setFlowName(String flowName) { this.flowName = flowName; } }
Step 2 :
Create a new class AopExampleAroundAdvice
File : AopExampleAroundAdvice.java
package com.simpleCodeStuffs.aop; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class AopExampleAroundAdvice implements MethodInterceptor{ @Override public Object invoke(MethodInvocation method) throws Throwable { System.out.println("Before invocation of method : "+method.getMethod()); method.proceed(); System.out.println("After execution of method : "+method.getMethod()); return null; } }
Step 3 :
Changes in the aopBeans.xml. Similar to previous tutorials,
- change the value in the list of interceptorNames
- Define the advisor (advice and pattern)
- Define the advice (class reference)
File : aopBeans.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- Bean Classes --> <bean id="beanTarget" class="com.simpleCodeStuffs.aop.IteratorImpl" > <property name="flowName" value="existing code"/> </bean> <!-- Bean configuration --> <bean id="businesslogicbean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>com.simpleCodeStuffs.aop.Iterator</value> </property> <property name="target"> <ref local="beanTarget" /> </property> <property name="interceptorNames"> <list> <value>theAroundAdvisor</value> </list> </property> </bean> <bean id="theAroundAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="theAroundAdvice"/> </property> <property name="pattern"> <value>.*</value> </property> </bean> <bean id="theAroundAdvice" class="com.simpleCodeStuffs.aop.AopExampleAroundAdvice"/> </beans>
Step 4 :
No major change in the Main class. Simply place a call to the methods
File : SpringAopMain.java
package com.simpleCodeStuffs.aop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringAopMain { public static void main(String[] args) { // Read the configuration file ApplicationContext context = new ClassPathXmlApplicationContext("aopBeans.xml"); // Instantiate an object Iterator IteratorInterface = (Iterator) context.getBean("businesslogicbean"); // Execute the public method of the bean IteratorInterface.goNext(); IteratorInterface.goPrevious(); } }
Step 5 :
Run the main method. The output is as follows
Step 6 :
Lets do a simple modification and check how AroundAdvice works with exceptions thrown.
Insert an exception in the goNext() method of IteratorImpl class to check the working. No change is required in Iterator interface
File : Iterator.java
package com.simpleCodeStuffs.aop; public class IteratorImpl implements Iterator{ String flowName; public void goNext() { System.out.println("goNext Method Called on flow - "+flowName); throw new RuntimeException(); } public void goPrevious(){ System.out.println("goPrevious Method called on flow - "+flowName); } public String getFlowName() { return flowName; } public void setFlowName(String flowName) { this.flowName = flowName; } }
Simply adding a try-catch block in AopExampleAroundAdvice class to handle the exception,
File : AopExampleAroundAdvice.java
package com.simpleCodeStuffs.aop; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class AopExampleAroundAdvice implements MethodInterceptor{ @Override public Object invoke(MethodInvocation method) throws Throwable { System.out.println("Before invocation of method : "+method.getMethod()); try{ method.proceed(); } catch(RuntimeException e){ System.out.println("Exception -"+e +" caught on method "+method.getMethod()); } System.out.println("After execution of method : "+method.getMethod()); return null; } }
No other change required. The output is as follows:
|
Read More
Spring AOP – AfterThrows Advice
|
Requirement : In case a particular method call throws an exception, a log needs to be printed.
** UPDATE: Spring Complete tutorial now available here.
Step 1 :
Changes in IteratorImpl class to mock an exception being thrown. No change in IteratorImpl interface
File : Iterator.java
package com.simpleCodeStuffs.aop; public interface Iterator { void goPrevious(); void goNext(); }
File : IteratorImpl.java
package com.simpleCodeStuffs.aop; public class IteratorImpl implements Iterator{ String flowName; public void goNext() { System.out.println("goNext Method Called on flow - "+flowName); throw new RuntimeException(); } public void goPrevious(){ System.out.println("goPrevious Method called on flow - "+flowName); } public String getFlowName() { return flowName; } public void setFlowName(String flowName) { this.flowName = flowName; } }
Step 2 :
Create a new class AopExampleAfterThrows to implement the new functionality
File : AopExampleAfterThrows.java
package com.simpleCodeStuffs.aop; import org.springframework.aop.ThrowsAdvice; public class AopExampleAfterThrows implements ThrowsAdvice { public void afterThrowing(RuntimeException runtimeException) { System.out.println("Logging step : Exception thrown by the method "); } }
Step 3 :
Changes in the aopBeans.xml file. Similar to the Before Advice and After returns Advice, create the advisor and advice beans
File : aopBeans.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- Bean Classes --> <bean id="beanTarget" class="com.simpleCodeStuffs.aop.IteratorImpl"> <property name="flowName" value="existing code" /> </bean> <!-- Bean configuration --> <bean id="businesslogicbean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>com.simpleCodeStuffs.aop.Iterator</value> </property> <property name="target"> <ref local="beanTarget" /> </property> <property name="interceptorNames"> <list> <value>theAfterThrowingAdvisor</value> </list> </property> </bean> <bean id="theAfterThrowingAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="theAfterThrowingAdvice" /> </property> <property name="pattern"> <value>.*</value> </property> </bean> <bean id="theAfterThrowingAdvice" class="com.simpleCodeStuffs.aop.AopExampleAfterThrows" /> </beans>
Step 4 :
No major change in the Main class. Simply place a call to the method that throws a mock exception.
File : SpringAopMain.java
package com.simpleCodeStuffs.aop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class SpringAopMain { public static void main(String[] args) { // Read the configuration file ApplicationContext context = new ClassPathXmlApplicationContext("aopBeans.xml"); // Instantiate an object Iterator IteratorInterface = (Iterator) context .getBean("businesslogicbean"); // Execute the public method of the bean IteratorInterface.goNext(); } }
Step 5 :
Run the Main class. The output is as follows
Please note that the exception shown in the above output is to show the working of the AfterThrows Advice once an exception is thrown. Handling this exception is simple enough. Read on to the next tutorial, wherein in aroundAdvice, this exception has been handled properly.
|
Read More
Bean Method invocation using spEL
|
Step 1 : Create the POJO
File : Customer.java
package com.simpleCodeStuffs.spEL; public class Customer { private String name; private double bill; public String getName() { return name; } public void setName(String name) { this.name = name; } public double getBill() { return bill; } public void setBill(double bill) { this.bill = bill; } }
File : Amount.java
package com.simpleCodeStuffs.spEL; public class Amount { public double billAmount() { return 100.9; } }
The scenario is such that the value of bill attribute of ‘Customer’ depends on the value returned from ‘billAmount()’ method of ‘Amount’
Step 2 : Create the xml file
File : elBeans.xml
<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-3.0.xsd"> <bean id="cust" class="com.simpleCodeStuffs.spEL.Customer"> <property name="name" value="#{'SANDY'.toLowerCase()}" /> <property name="bill" value="#{amount.billAmount()}" /> </bean> <bean id="amount" class="com.simpleCodeStuffs.spEL.Amount"> </bean> </beans>
Note here, method invocation is done on Amount class through the bean as
spEL #{amount.billAmount()} and the returned value is set to bill using injection.
Step 3 : Create the main class
File : MainClass.java
package com.simpleCodeStuffs.spEL; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainClass { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("elBeans.xml"); Amount bill = (Amount) context.getBean("amount"); Customer customer = (Customer) context.getBean("cust"); System.out.println("Customer name: " + customer.getName()); System.out.println("Bill amount: " + customer.getBill()); } }
Step 4 :
The output is
|
Read More
Basic example of Spring AOP Concept using BeforeAdvice
|
Take an example wherein there exists an interface ‘Iterator’. It is implemented by a class ‘IteratorImpl’(which obviously, overrides the methods of ‘Iterator’, in this case goNext() ). Consider a scenario wherein this set up is part of a very large code. Now, I get a requirement to insert a logging step into this code. This can be done using AOP with no impact at all on the existing classes.
** UPDATE: Spring Complete tutorial now available here.
Step 1 :
Include the required libraries in your classpath
Step 2 :
Creating the existing code set up as per our scenario
Create a new package. Click on your project SpringTutorial, select New->Package. Give com.simpleCodeStuff.aop. Create the interface Iterator with an abstract method(goNext() ) and a class IteratorImpl which implements Iterator(thus defining goNext() method).
File : Iterator.java
package com.simpleCodeStuffs.aop; public interface Iterator { void goNext(); }
File : IteratorImpl.java
package com.simpleCodeStuffs.aop; public class IteratorImpl implements Iterator{ String flowName; public void goNext() { System.out.println("goNext Method Called on flow - "+flowName); } public String getFlowName() { return flowName; } public void setFlowName(String flowName) { this.flowName = flowName; } }
The call to the goNext() method is sent from a main class SpringAopMain, by loading the configuration metadata xml aopBeans.xml and consecutively loading the bean specified corresponding to IteratorImpl beanTarget(So far, AOP is not implemented. It is simple Spring IOC)
File : SpringAopMain.java
package com.simpleCodeStuffs.aop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class SpringAopMain { public static void main(String[] args) { // Read the configuration file ApplicationContext context = new ClassPathXmlApplicationContext("aopBeans.xml"); // Instantiate an object Iterator IteratorInterface = (Iterator) context .getBean("beanTarget"); // Execute the public method of the bean IteratorInterface.goNext(); } }
The configuration metadata xml aopBeans.xml with the required bean definitions
File : aopBeans.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- Bean Classes --> <bean id="beanTarget" class="com.simpleCodeStuff.aop.IteratorImpl" > <property name="flowName" value="existing code"/> </bean> </beans>
The existing output is
Step 3 :
In this step, let us take up the changes needed to insert the logging step, say before the goNext method is called.
Create a new class to perform the logging step -AopExampleBefore, which implements MethodBeforeAdvice class from the springframework. This class must hence define the abstract method before() from the implemented class.
File : AopExampleBefore.java
package com.simpleCodeStuffs.aop; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class AopExampleBefore implements MethodBeforeAdvice { public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable { System.out.println("Logging step :Before Advice Called"); } }
Now, majority of the changes are done in the xml which binds these classes using aop concept aopBeans.xml. Just as in the Spring IOC case, this configuration metadata xml has to be present directly under the src folder.
Note- our existing code undergoes no alteration which not only makes the changes easier but also leaves way for further changes in the code giving modularity to our code.
File : aopBeans.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- Bean Classes --> <bean id="beanTarget" class="com.simpleCodeStuffs.aop.IteratorImpl"> <property name="flowName" value="existing code" /> </bean> <!-- Bean configuration --> <bean id="businesslogicbean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>com.simpleCodeStuffs.aop.Iterator</value> </property> <property name="target"> <ref local="beanTarget" /> </property> <property name="interceptorNames"> <list> <value>theTracingBeforeAdvisor</value> </list> </property> </bean> <!-- Advisor pointcut definition for before advice --> <bean id="theTracingBeforeAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="theTracingBeforeAdvice" /> </property> <property name="pattern"> <value>.*</value> </property> </bean> <!-- Advice classes --> <bean id="theTracingBeforeAdvice" class="com.simpleCodeStuffs.aop.AopExampleBefore" /> </beans>
Explanation :
- target defines which bean is intercepted(or bypassed)
- interceptorNames Define which class (advice) you want to apply on this proxy /target object.
- proxyInterfaces provides the interface that has been implemented by the class referred by bean âtargetâ
- Advisor pointcut The bean that defines the ’advice’ and the ‘pattern’. As is clear from the terminology provided at the start of this concept, a pointcut has to match the joinpoint, so that a particular action is taken.
- Advice – the bean referring to the class which bypasses the ‘target’
- Pattern Specifies the pattern(characters)to look for in the method inside the ‘target’ class that has to be bypassed.
The only change in the existing code is the beanID which is called from the main method. Instead of directly calling for targetBean (class IteratorImpl), the bean taken up now will be businesslogicbean which provides the beans configuration.
File : SpringAopMain.java
package com.simpleCodeStuffs.aop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringAopMain { public static void main(String[] args) { // Read the configuration file ApplicationContext context = new ClassPathXmlApplicationContext("aopBeans.xml"); // Instantiate an object Iterator IteratorInterface = (Iterator) context .getBean("businesslogicbean"); // Execute the public method of the bean IteratorInterface.goNext(); } }
The output now is as follows
|
Read More
Operators in spEL
|
The various operators that are most frequently used in this context are :-
Relational operators
- equal (==)
- not equal (!=)
- less than (<)
- less than or equal (<=)
- greater than (>)
- greater than or equal (>=)
Logical operators
- And(&&)
- Or(||)
- not (!).
Mathematical operators
- addition (+)
- Subtraction (-)
- Multiplication (*)
- division (/)
- modulus (%)
- exponential power (^).
Ternary operator
- if-then-else (<condn> ? <stmt1 if true> : <Stmt2 if false>)
.
- if-then-else (<condn> ? <stmt1 if true> : <Stmt2 if false>)
Step 1 : Create a sample POJO
File : Operators.java
package com.simpleCodeStuffs.spEL; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component("operators") public class Operators { @Value("#{1==1}") private boolean equals; public boolean isEquals() { return equals; } public void setEquals(boolean equals) { this.equals = equals; } }
Step 2 : Create the main class
File : MainClass.java
package com.simpleCodeStuffs.spEL; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainClass { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("elBeans.xml"); Operators op = (Operators) context.getBean("operators"); System.out.println("equals" + op.isEquals()); } }
Step 3 : Enable automatic component scanning in elBeans.xml
File : elBeans.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.simpleCodeStuffs.spEL" /> </beans>
Step 4 : Run the program. The output is
Step 5 : Other operators and the functionalities
@Value("#{1 != 5}") //true private boolean NotEqual; @Value("#{1 < 1}") //false private boolean LessThan; @Value("#{1 <= 1}") //true private boolean LessThanOrEqual; @Value("#{1 > 1}") //false private boolean GreaterThan; @Value("#{1 >= 1}") //true private boolean GreaterThanOrEqual; /* * Logical operators , numberBean.no == 999 * @Value("#{numberBean.no == 999 and numberBean.no < 900}") * can be used in case 'numberBean' is another bean. */ @Value("#{999 == 999 and 999 < 900}") //false private boolean And; @Value("#{999 == 999 or 999 < 900}") //true private boolean Or; @Value("#{!(999 == 999)}") //false private boolean Not; //Mathematical operators @Value("#{1 + 1}") //2.0 private double testAdd; @Value("#{'1' + '@' + '1'}") //1@1 private String AddString; @Value("#{1 - 1}") //0.0 private double Subtraction; @Value("#{1 * 1}") //1.0 private double Multiplication; @Value("#{10 / 2}") //5.0 private double Division; @Value("#{10 % 10}") //0.0 private double Modulus ; @Value("#{2 ^ 2}") //4.0 private double ExponentialPower;
//Ternary operator @Value("#{99!=0?'expresion holds true':'expression is false'}") private String name; public String getName() { return name; } public void setName(String name) { this.name = name; }
File : Operators.java
package com.simpleCodeStuffs.spEL; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component("operators") public class Operators { @Value("#{99!=0?'expresion holds true':'expression is false'}") private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
File : MainClass.java
package com.simpleCodeStuffs.spEL; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainClass { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("elBeans.xml"); Operators op = (Operators) context.getBean("operators"); System.out.println(op.getName()); } }
The output is –
|
Read More