徒弟:
师傅,我以前:
使用JDK中的Proxy技术实现AOP功能
使用CGLIB实现AOP功能
使用编程式创建AOP代理
非常繁琐,本来好好的一天的时间,我可以快快乐乐乐完成了某个业务流程,很有成就感,却被这些繁琐的实现方式,毁了我美好的一天,有没有办法救救我呀,有的话,请你吃饭!
师傅:
这么好的差事,还有饭吃
(心里想着毛家、周边的餐馆 ,真爽)
,当然要教!
补充:
个人认为:工作的时候,我们应该更加关注业务逻辑的实现,一些繁琐的使用方式,应该成为茶余饭后研究的乐趣。
要进行AOP编程,首先我们要在配置文件中引入aop命名空间;
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
</beans>
Spring提供了两种切面使用方式,可以根据实际工作情况,选用其中一种:
1、
基于XML配置方式进行AOP开发
2、
基于注解方式进行AOP开发
为了更快地完成配置,将焦点转移到业务逻辑中,我选择了第二种(其实是为了更快地把吃饭的事情确定下来)
既然讲到配置文件,就先将aop的配置开关打开吧,配置文件中加入:
<aop:aspectj-autoproxy/>
哎呀,太着急了,还得
先
加入两个包:
lib/aspectj/aspectjweaver.jar
lib/aspectj/aspectjrt.jar
新增加一个类:
/**
* Book切面
*/
@Aspect
public
class
BookInterceptor {
@Pointcut
(
"execution (* com.netease.lee.service..*.*(..))"
)
private
void
anyMethod()
{
// System.out.println("anyMethod");
}
// 声明一个切入点
/*
* 首先拦截所有方法的执行 然后在方法之前,执行前置通知,
* 执行完前置通知之后,才会执行被拦截到的方法。
* 切入点的名称,附加条件:要求有String类型的参数
* 即这里只拦截saveBook(String bookName)方法
*/
@Before
(
"anyMethod() && args(bookName)"
)
public
void
doBefore(String bookName) {
System.
out
.println(
"前置通知:"
+ bookName);
}
@AfterReturning
(pointcut =
"anyMethod()"
, returning =
"result"
)
public
void
doAfterReturning(String result) {
System.
out
.println(
"后置通知:"
+ result);
}
@After
(
"anyMethod()"
)
public
void
doAfter() {
System.
out
.println(
"最终通知"
);
}
@AfterThrowing
(pointcut =
"anyMethod()"
, throwing =
"e"
)
public
void
doAfterThrowing(Exception e) {
System.
out
.println(
"例外通知:"
+ e);
}
//环绕通知可以替代前面的任何通知
@Around
(
"anyMethod()"
)
public
Object doAround(ProceedingJoinPoint pjp)
throws
Throwable {
System.
out
.println(
"
环绕通知
进入方法"
);
Object result = pjp.proceed();
System.
out
.println(
"
环绕通知
退出方法"
);
return
result;
}
}
@Pointcut
(
"execution (* com.netease.lee.service..*.*(..))"
)
第一个
*
代表任何的返回值类型
,
com.netease.lee.service
是包名。
..
两点,说明对子包里面的类也要拦截。
*.*
说明:第一个*代表所有类,第二个*代表所有方法。
(..)
说明:括号里面的两点,代表方法的参数,这里代表随意。
@Before
(
"anyMethod() && args(name)"
)
前置通知,填入的是切入点的名称。
附上代码:
@Service
(
"bookService"
)
public
class
BookServiceImpl
implements
BookService {
@Resource
private
BookDAO
bookDAO
;
public
void
listBook() {
bookDAO
.listBook();
}
@Override
public
String getBookName(Integer bookId) {
return
bookDAO
.getBookName(bookId);
}
@Override
public
void
saveBook(String bookName) {
bookDAO
.saveBook(bookName);
}
@Override
public
void
updateBoook(String bookName, Integer bookId) {
bookDAO
.updateBook(bookName, bookId);
}
}
运行结果这里就不演示了,赶着去吃饭了!徒弟说不行,这样子的话,如果他写了几十个切面类,别人过来看,岂不是不能“纵观全局”,有没有好办法,一看就知道项目里面配置了哪些切面类,定义了什么?
由于篇幅问题,请看:第五章 Spring进阶-注解方式实现AOP(2)
关注我的微博,请使用网易通行证,通过邀请链接登陆,就可以直接关注我。
本文转自jooben 51CTO博客,原文链接:http://blog.51cto.com/jooben/313306