第一节 AspectJ
1.1 AspectJ简介
- AspectJ是一个基于Java语言的AOP框架
- Spring2.0以后新增了对AspectJ切点表达式支持
- @AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面
- 新版本Spring框架,建议使用AspectJ方式来开发AOP
- 主要用途:自定义开发
1.2 切入点表达式【掌握】
execution():用于描述方法 【掌握】
- 语法:execution(修饰符 返回值 包.类.方法名(参数) throws异常)
修饰符,一般省略 |
|
public |
公共方法 |
* |
任意 |
返回值,不能省略 |
|
void |
返回没有值 |
String |
返回值字符串 |
* |
任意 |
包,[省略] |
|
com.it.crm |
固定包 |
com.it.crm.*.service |
crm包下面子包任意 (例如:com.it.crm.staff.service) |
com.it.crm.. |
crm包下面的所有子包(含自己) |
com.it.crm.*.service.. |
crm包下面任意子包,固定目录service,service目录任意包 |
类,[省略] |
|
UserServiceImpl |
指定类 |
*Impl |
以Impl结尾 |
User* |
以User开头 |
* |
任意 |
方法名,不能省略 |
|
addUser |
固定方法 |
add* |
以add开头 |
*Do |
以Do结尾 |
* |
任意 |
(参数) |
|
() |
无参 |
(int) |
一个整型 |
(int,int) |
两个整型 |
(..) |
参数任意 |
案例1: |
execution(* com.it.crm.*.service..*.*(..)) |
案例2: |
< aop:pointcut expression="execution(* com.it.crm.service.*.*(..)) || execution(* com.it.*Do.*(..))" id="myPointCut"/> |
这里的空格要去掉<aop:pointcut
within:匹配包或子包中的方法【了解】
this:匹配实现接口的代理对象中的方法【了解】
- this(com.it.aop.user.UserDAO)
target:匹配实现接口的目标对象中的方法【了解】
- target(com.it.aop.user.UserDAO)
args:匹配参数格式符合标准的方法【了解】
bean(id):对指定的bean所有的方法【了解】
1.3 AspectJ 通知类型
- aop联盟定义通知类型,具有特性接口,必须实现,从而确定方法名称。
- aspectj 通知类型,只定义类型名称,以及方法格式。
- 个数:6种,知道5种,掌握1种
- before:前置通知(应用:各种校验)
在方法执行前执行,如果通知抛出异常,阻止方法运行。
- afterReturning:后置通知(应用:常规数据处理)
方法正常返回后执行,如果方法中抛出异常,通知无法执行
必须在方法执行后才执行,所以可以获得方法的返回值。
- around:环绕通知(应用:十分强大,可以做任何事情)
方法执行前后分别执行,可以阻止方法的执行,必须手动执行目标方法。
- afterThrowing:抛出异常通知(应用:包装异常信息)
方法抛出异常后执行,如果方法没有抛出异常,无法执行。
- after:最终通知(应用:清理现场)
方法执行完毕后执行,无论方法中是否出现异常都会执行。
1.4 Aspect案例【xml配置】
第一步:导入以下jar包
- spring-aspects-3.2.0.RC2.jar(aspectj实现)
第二步:接口与实现类的编写
public interface UserService {
public void addUser();
public void updateUser();
public void deleteUser();
public int deleteUser(int id);
}
public class UserServiceImpl implements UserService{
@Override
public void addUser() {
System.out.println("添加用户...");
}
@Override
public void updateUser() {
System.out.println("更新用户...");
}
@Override
public void deleteUser() {
System.out.println("删除用户...");
}
@Override
public int deleteUser(int id) {
System.out.println("通过id删除用户...");
return 1;
}
}
第三步:切面类编写
package com.it.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAspect4 {
public void myBefore(JoinPoint jp){
System.out.println("1.前置通知..."+jp.getSignature().getName());
}
public void myAfterReturning(JoinPoint jp,Object retValue){
System.out.println("3.后置通知..."+jp.getSignature().getName());
System.out.println("返回值:"+retValue);
}
public Object myAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("2.环绕通知...开启事务..."+pjp.getSignature().getName());
Object retObj = pjp.proceed();
System.out.println("4.环绕通知...提交事务...");
return retObj;
}
public void myAfterThrowing(JoinPoint jp,Throwable e){
System.out.println("异常通知..."+jp.getSignature().getName()+":"+e.getMessage());
}
public void myAfter(JoinPoint jp){
System.out.println("最终通知..."+jp.getSignature().getName())