AfterThrowing Aspect XML implementation example
create a spring maven project so that we can manage our dependencies in the pom.xml easily.
Project structure looks like below
Define the pom.xml file as below to include AspectJ jars and spring jars
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>Spring</groupId>
- <artifactId>SpringAOP</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>SpringAOP</name>
- <url>http://maven.apache.org</url>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- <version>4.2.4.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>4.2.4.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.aspectj</groupId>
- <artifactId>aspectjrt</artifactId>
- <version>1.7.3</version>
- </dependency>
- <dependency>
- <groupId>aspectj</groupId>
- <artifactId>aspectjweaver</artifactId>
- <version>1.5.4</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
- </project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>Spring</groupId> <artifactId>SpringAOP</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>SpringAOP</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.7.3</version> </dependency> <dependency> <groupId>aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.5.4</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>
Let’s create a class which contains a business logic on which we apply Advice.
- package com.kb;
- public class SimpleCalculatorThrowsException {
- public int add(int x,int y){
- System.out.println("inside Add");
- throw new RuntimeException();
- }
- }
package com.kb; public class SimpleCalculatorThrowsException { public int add(int x,int y){ System.out.println("inside Add"); throw new RuntimeException(); } }
This class has 1 method which performs some business logic,which is addition.
Now let’s write the Aspect class as below
- package com.kb;
- import org.aspectj.lang.JoinPoint;
- public class MyAfterThrowingAspect {
- public void myAdvice(JoinPoint jp){
- System.out.println("After the method "+jp.getSignature().getName()+" throws an exception");
- }
- }
package com.kb; import org.aspectj.lang.JoinPoint; public class MyAfterThrowingAspect { public void myAdvice(JoinPoint jp){ System.out.println("After the method "+jp.getSignature().getName()+" throws an exception"); } }
This Aspect has an advice called myAdvice whose action is to print the log with method name
Now let’s create a beans.xml file which is the spring configuration file where we define our aspect beans and configure the AOP as below
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
- http://www.springframework.org/schema/aop
- http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.2.xsd">
- <aop:aspectj-autoproxy />
- <bean id="simpleCalc" class="com.kb.SimpleCalculator"/>
- <bean id="simpleCalcException" class="com.kb.SimpleCalculatorThrowsException"/>
- <bean id="myAfterThrowingAspect" class="com.kb.MyAfterThrowingAspect" />
- <aop:config>
- <aop:aspect id="myAspect" ref="myAfterThrowingAspect">
- <aop:pointcut id="pointCutAfter"
- expression="execution(* *.*(..))" />
- <aop:after-throwing method="myAdvice" pointcut-ref="pointCutAfter" />
- </aop:aspect>
- </aop:config>
- </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"> <aop:aspectj-autoproxy /> <bean id="simpleCalc" class="com.kb.SimpleCalculator"/> <bean id="simpleCalcException" class="com.kb.SimpleCalculatorThrowsException"/> <bean id="myAfterThrowingAspect" class="com.kb.MyAfterThrowingAspect" /> <aop:config> <aop:aspect id="myAspect" ref="myAfterThrowingAspect"> <aop:pointcut id="pointCutAfter" expression="execution(* *.*(..))" /> <aop:after-throwing method="myAdvice" pointcut-ref="pointCutAfter" /> </aop:aspect> </aop:config> </beans>
We have to add below elements in spring xml file to configure AOP
Need to define AOP namespacelike xmlns:aop=http://www.springframework.org/schema/aop
Need to add < aop:aspectj-autoproxy /> to enable Spring AspectJ support with auto proxy at runtime
Need to configure Aspect classes as any other spring beans
Need to define aop configuration which defines the pointcut and advice mapping using < aop:config> element
expression=”execution(* com.kb.SimpleCalculator.*(..))” defines that advice must be applied to all the methods inside SimpleCalculator class no matter what is its return type and its parameters.
Lets write a class which calls the actual business logic method as below
- package com.kb;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class AOPTestException {
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
- SimpleCalculatorThrowsException calculator = (SimpleCalculatorThrowsException) context.getBean("simpleCalcException");
- int res1= calculator.add(10, 5);
- System.out.println("addition result is "+res1);
- }
- }
package com.kb; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AOPTestException { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); SimpleCalculatorThrowsException calculator = (SimpleCalculatorThrowsException) context.getBean("simpleCalcException"); int res1= calculator.add(10, 5); System.out.println("addition result is "+res1); } }
Run the above class and see the output as below
Observe the output, after the method throws an exception, advice code has been executed.
Note:The advice will not be executed if the method executes normally
Lets create the class which will not throw an exception
- package com.kb;
- public class SimpleCalculator {
- public int add(int x,int y){
- System.out.println("inside Add");
- return x+y;
- }
- public int subtract(int x,int y){
- System.out.println("inside subtract");
- return x-y;
- }
- }
package com.kb; public class SimpleCalculator { public int add(int x,int y){ System.out.println("inside Add"); return x+y; } public int subtract(int x,int y){ System.out.println("inside subtract"); return x-y; } }
Now run the above methods as below
- package com.kb;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class AOPTest {
- public static void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
- SimpleCalculator calculator = (SimpleCalculator) context.getBean("simpleCalc");
- int res1= calculator.add(10, 5);
- System.out.println("addition result is "+res1);
- int res2= calculator.subtract(10, 5);
- System.out.println("subtracted result is "+res2);
- }
- }
package com.kb; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AOPTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); SimpleCalculator calculator = (SimpleCalculator) context.getBean("simpleCalc"); int res1= calculator.add(10, 5); System.out.println("addition result is "+res1); int res2= calculator.subtract(10, 5); System.out.println("subtracted result is "+res2); } }
Observe the output as below
Observing the output shows that advice is not executed as the method executed normally.