Spring AOP Example – Advice
Spring AOP + AspectJ
Using AspectJ is more flexible and powerful.
Spring AOP (Aspect-oriented programming) framework is used to modularize cross-cutting concerns in aspects. Put it simple, it’s just an interceptor to intercept some processes, for example, when a method is execute, Spring AOP can hijack the executing method, and add extra functionality before or after the method execution.
In Spring AOP, 4 type of advices are supported :
- Before advice – Run before the method execution
- After returning advice – Run after the method returns a result
- After throwing advice – Run after the method throws an exception
- Around advice – Run around the method execution, combine all three advices above.
Following example show you how Spring AOP advice works.
Simple Spring example
Create a simple customer service class with few print methods for demonstration later.
package com.mkyong.customer.services;
public class CustomerService {
private String name;
private String url;
public void setName(String name) {
this.name = name;
}
public void setUrl(String url) {
this.url = url;
}
public void printName() {
System.out.println("Customer name : " + this.name);
}
public void printURL() {
System.out.println("Customer website : " + this.url);
}
public void printThrowException() {
throw new IllegalArgumentException();
}
}
File : Spring-Customer.xml
– A bean configuration file
<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="customerService" class="com.mkyong.customer.services.CustomerService">
<property name="name" value="Yong Mook Kim" />
<property name="url" value="http://www.mkyong.com" />
</bean>
</beans>
Run it
package com.mkyong.common;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.mkyong.customer.services.CustomerService;
public class App {
public static void main(String[] args) {
ApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] { "Spring-Customer.xml" });
CustomerService cust = (CustomerService) appContext.getBean("customerService");
System.out.println("*************************");
cust.printName();
System.out.println("*************************");
cust.printURL();
System.out.println("*************************");
try {
cust.printThrowException();
} catch (Exception e) {
}
}
}
Output
*************************
Customer name : Yong Mook Kim
*************************
Customer website : http://www.mkyong.com
*************************
A simple Spring project to DI a bean and output some Strings.
Spring AOP Advices
Now, attach Spring AOP advices to above customer service.
1. Before advice
It will execute before the method execution. Create a class which implements MethodBeforeAdvice
interface.
package com.mkyong.aop;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class HijackBeforeMethod implements MethodBeforeAdvice
{
@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
System.out.println("HijackBeforeMethod : Before method hijacked!");
}
}
In bean configuration file (Spring-Customer.xml
), create a bean for HijackBeforeMethod
class , and a new proxy object named ‘customerServiceProxy
‘.
- ‘target’ – Define which bean you want to hijack.
- ‘interceptorNames’ – Define which class (advice) you want to apply on this proxy /target object.
<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="customerService" class="com.mkyong.customer.services.CustomerService">
<property name="name" value="Yong Mook Kim" />
<property name="url" value="http://www.mkyong.com" />
</bean>
<bean id="hijackBeforeMethodBean" class="com.mkyong.aop.HijackBeforeMethod" />
<bean id="customerServiceProxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="customerService" />
<property name="interceptorNames">
<list>
<value>hijackBeforeMethodBean</value>
</list>
</property>
</bean>
</beans>
Note
To use Spring proxy, you need to add CGLIB2 library. Add below in Mavenpom.xml
file.
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
Run it again, now you get the new customerServiceProxybean
instead of the original customerService
bean.
package com.mkyong.common;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.mkyong.customer.services.CustomerService;
public class App {
public static void main(String[] args) {
ApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] { "Spring-Customer.xml" });
CustomerService cust =
(CustomerService) appContext.getBean("customerServiceProxy");
System.out.println("*************************");
cust.printName();
System.out.println("*************************");
cust.printURL();
System.out.println("*************************");
try {
cust.printThrowException();
} catch (Exception e) {
}
}
}
Output
*************************
HijackBeforeMethod : Before method hijacked!
Customer name : Yong Mook Kim
*************************
HijackBeforeMethod : Before method hijacked!
Customer website : http://www.mkyong.com
*************************
HijackBeforeMethod : Before method hijacked!
It will run the HijackBeforeMethod
’s before()
method, before every customerService
’s methods are execute.
2. After returning advice
It will execute after the method is returned a result. Create a class which implements AfterReturningAdvice
interface.
package com.mkyong.aop;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class HijackAfterMethod implements AfterReturningAdvice
{
@Override
public void afterReturning(Object returnValue, Method method,
Object[] args, Object target) throws Throwable {
System.out.println("HijackAfterMethod : After method hijacked!");
}
}
Bean configuration file
<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="customerService" class="com.mkyong.customer.services.CustomerService">
<property name="name" value="Yong Mook Kim" />
<property name="url" value="http://www.mkyong.com" />
</bean>
<bean id="hijackAfterMethodBean" class="com.mkyong.aop.HijackAfterMethod" />
<bean id="customerServiceProxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="customerService" />
<property name="interceptorNames">
<list>
<value>hijackAfterMethodBean</value>
</list>
</property>
</bean>
</beans>
Run it again, Output
*************************
Customer name : Yong Mook Kim
HijackAfterMethod : After method hijacked!
*************************
Customer website : http://www.mkyong.com
HijackAfterMethod : After method hijacked!
*************************
It will run the HijackAfterMethod
’s afterReturning()
method, after every customerService
’s methods that are returned result.
3. After throwing advice
It will execute after the method throws an exception. Create a class which implements ThrowsAdvice
interface, and create a afterThrowing
method to hijack the IllegalArgumentException
exception.
package com.mkyong.aop;
import org.springframework.aop.ThrowsAdvice;
public class HijackThrowException implements ThrowsAdvice {
public void afterThrowing(IllegalArgumentException e) throws Throwable {
System.out.println("HijackThrowException : Throw exception hijacked!");
}
}
Bean configuration file
<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="customerService" class="com.mkyong.customer.services.CustomerService">
<property name="name" value="Yong Mook Kim" />
<property name="url" value="http://www.mkyong.com" />
</bean>
<bean id="hijackThrowExceptionBean" class="com.mkyong.aop.HijackThrowException" />
<bean id="customerServiceProxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="customerService" />
<property name="interceptorNames">
<list>
<value>hijackThrowExceptionBean</value>
</list>
</property>
</bean>
</beans>
Run it again, output
*************************
Customer name : Yong Mook Kim
*************************
Customer website : http://www.mkyong.com
*************************
HijackThrowException : Throw exception hijacked!
It will run the HijackThrowException
’s afterThrowing()
method, if customerService
’s methods throw an exception.
4. Around advice
It combines all three advices above, and execute during method execution. Create a class which implements MethodInterceptor
interface. You have to call the “methodInvocation.proceed();
” to proceed on the original method execution, else the original method will not execute.
package com.mkyong.aop;
import java.util.Arrays;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class HijackAroundMethod implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("Method name : "
+ methodInvocation.getMethod().getName());
System.out.println("Method arguments : "
+ Arrays.toString(methodInvocation.getArguments()));
// same with MethodBeforeAdvice
System.out.println("HijackAroundMethod : Before method hijacked!");
try {
// proceed to original method call
Object result = methodInvocation.proceed();
// same with AfterReturningAdvice
System.out.println("HijackAroundMethod : Before after hijacked!");
return result;
} catch (IllegalArgumentException e) {
// same with ThrowsAdvice
System.out.println("HijackAroundMethod : Throw exception hijacked!");
throw e;
}
}
}
Bean configuration file
<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="customerService" class="com.mkyong.customer.services.CustomerService">
<property name="name" value="Yong Mook Kim" />
<property name="url" value="http://www.mkyong.com" />
</bean>
<bean id="hijackAroundMethodBean" class="com.mkyong.aop.HijackAroundMethod" />
<bean id="customerServiceProxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="customerService" />
<property name="interceptorNames">
<list>
<value>hijackAroundMethodBean</value>
</list>
</property>
</bean>
</beans>
Run it again, output
*************************
Method name : printName
Method arguments : []
HijackAroundMethod : Before method hijacked!
Customer name : Yong Mook Kim
HijackAroundMethod : Before after hijacked!
*************************
Method name : printURL
Method arguments : []
HijackAroundMethod : Before method hijacked!
Customer website : http://www.mkyong.com
HijackAroundMethod : Before after hijacked!
*************************
Method name : printThrowException
Method arguments : []
HijackAroundMethod : Before method hijacked!
HijackAroundMethod : Throw exception hijacked!
It will run the HijackAroundMethod
’s invoke()
method, after every customerService
’s method execution.
Conclusion
Most of the Spring developers are just implements the ‘Around advice ‘, since it can apply all the advice type, but a better practice should choose the most suitable advice type to satisfy the requirements.
Pointcut
In this example, all the methods in a customer service class are intercepted (advice) automatically. But for most cases, you may need to use Pointcut and Advisor to intercept a method via it’s method name.
Spring AOP Example – Advice的更多相关文章
- Spring AOP 中 advice 的四种类型 before after throwing advice around
spring AOP(Aspect-oriented programming) 是用于切面编程,简单的来说:AOP相当于一个拦截器,去拦截一些处理,例如:当一个方法执行的时候,Spring 能够拦截 ...
- Spring AOP增强(Advice)
Sring AOP通过PointCut来指定在那些类的那些方法上织入横切逻辑,通过Advice来指定在切点上具体做什么事情.如方法前做什么,方法后做什么,抛出异常做什么. Spring中有两种方式定义 ...
- Spring Aop——给Advice传递参数
给Advice传递参数 Advice除了可以接收JoinPoint(非Around Advice)或ProceedingJoinPoint(Around Advice)参数外,还可以直接接收与切入点方 ...
- Spring AOP 创建Advice 定义pointcut、advisor
前面定义的advice都是直接植入到代理接口的执行之前和之后,或者在异常发生时,事实上,还可以对植入的时机定义的更细. Pointcut定义了advice的应用时机,在Spring中pointcutA ...
- Spring AOP 创建Advice 基于Annotation
public interface IHello { public void sayHello(String str); } public class Hello implements IHello { ...
- spring aop的五种通知类型
昨天在腾讯课堂看springboot的视频,老师随口提问,尼玛竟然回答错了.特此记录! 问题: Spring web项目如果程序启动时出现异常,调用的是aop中哪类通知? 正确答案是: 异常返回通知. ...
- spring aop 的五种通知类型
本文转自:http://blog.csdn.net/cqabl/article/details/46965197 spring aop通知(advice)分成五类: 前置通知[Before advic ...
- 《Spring 5官方文档》 Spring AOP的经典用法
原文链接 在本附录中,我们会讨论一些初级的Spring AOP接口,以及在Spring 1.2应用中所使用的AOP支持. 对于新的应用,我们推荐使用 Spring AOP 2.0来支持,在AOP章节有 ...
- 尚硅谷spring aop详解
spring的aop实现我们采用AspectJ的方式来实现,不采用spring框架自带的aop aspect实现有基于注解的方式,有基于xml的方式,首先我们先讲基于注解的方式,再将基于xml的方式 ...
随机推荐
- 自定义View(4)Canvas和Paint常用绘制函数
画布Canvas 在Android下进行2D绘图需要Canvas类的支持,它位于"android.graphics.Canvas"包下,直译过来为画布的意思,用于完成在View上的 ...
- rundeck email配置文件配置
最近工作中用到了一个任务管理软件rundeck,其中有个很重要的功能就是任务执行提醒,用邮件执行,其中一些配置项,官网没有详细的说明,在网上也没有一个整体的说明,在次跟大家共享下,rundeck的使用 ...
- $.toJSON的用法或把数组转换成json类型
1. html页面全部代码 <html> <head> <title></title> <script src="../../S ...
- Java语言基本语法
Java语言基本语法 一.标识符和关键字 标识符 在java语言中,用来标志类名.对象名.变量名.方法名.类型名.数组名.包名的有效字符序列,称为“标识符”: 标识符由字母.数字.下划线.美元符号组成 ...
- fiddler for mac
Fiddler 是一免费的web调试工具.并且兼容所有浏览器.系统和平台. Fiddler 是基于微软的 .Net 技术开发的,没办法直接在 Mac/Linux 下使用.本文介绍一些替代方案(这些方案 ...
- Codeforces 4538 (状态压缩dp)Little Pony and Harmony Chest
Little Pony and Harmony Chest 经典状态压缩dp #include <cstdio> #include <cstring> #include < ...
- C# 编写的串口通信程序
如果,翻看我之前的博客,会找到一篇用I/O模拟IIC通信的程序文章.好吧,如果找不到可以点击这里,这里就不在赘述了,系统也已经完全调试通过了. 今天的任务是,把测试得到的数据在上位机的界面上显示出来, ...
- (3)Spring定时任务的几种实现
Spring定时任务的几种实现 近日项目开发中需要执行一些定时任务,比如需要在每天凌晨时候,分析一次前一天的日志信息,借此机会整理了一下定时任务的几种实现方式,由于项目采用spring框架,所以我都将 ...
- 【转】【Android】对话框 AlertDialog -- 不错不错
原文网址:http://blog.csdn.net/feng88724/article/details/6171450 本讲介绍一下Android基本组件:对话框AlertDialog. API: j ...
- 常用的PL/SQL开发原则
(1)广泛使用绑定变量,特别是批量绑定,因为这可以有效的避免sql的硬解析和PL/SQL引擎和SQL引擎的上下文切换!(2)广泛使用UROWID来处理DML语句(UROWID是ROWID扩展,ORAC ...