基于CGLIB,使用方法拦截器的方式
首先在配置文件中添加:
<!-- 使用CGLIB代理,支持基于@AspectJ的AOP -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
声明一个切面@Aspect
@Aspect
@Component("LogAopUtils")
public class LogAopUtils {
@Pointcut("execution(public * com.shinerio..*.*(..))")
public void pointcut() {
}
@Before("pointcut()")
public void beforeAdvice(JoinPoint joinPoint) { // 参数JoinPoint是可选项,通过这个对象可以获得一些信息
System.out.println("前置通知日志记录");
joinPoint.getSignature().getName(); // 得到切入点方法的原型的名字
}
@After("pointcut()")
public void afterAdvice() {
System.out.println("后置通知日志记录");
}
@Around("pointcut()")
public Object aroundAdvice(ProceedingJoinPoint p) throws Throwable {
System.out.println("===========around before advice");
Object retVal = p.proceed(new Object[] { "替代品" });
System.out.println("===========around after advice");
return retVal;
}
}
expression简单说明, 多个execution用&&连接
execution(public * com.shinerio...(..))
execution方法执行
public指定public方法,可以省略
*表示任意返回值(包括void)
com.shinerio.dao.goodsDao.*表示com.shinerio.dao包下goodsDAO的任意方法
com.shinerio.set*表示com.shinerio.dao包下goodsDAO的任意以set开头的方法
com.shinerio.dao..表示com.shinerio.dao包下的任意类的任意方法
com.shinerio...表示com.shinerio目录下任意包的任意类的任意方法
(..)表示任何参数,可以没有参数
各种注解的使用
- 声明切面,类上加@AspectJ()
- 声明切入点,@AspectJ风格的命名切入点使用org.aspectj.lang.annotation包下的@Pointcut+方法(方法必须是返回void类型)实现。
- value:指定切入点表达式;
- argNames:指定命名切入点方法参数列表参数名字,可以有多个用“,”分隔,这些参数将传递给通知方法同名的参数,同时比如切入点表达式“args(param)”将匹配参数类型为命名切入点方法同名参数指定的参数类型。该切入点将匹配目标方法的第一个参数类型为通知方法实现中参数名为“param”的参数类型。
- pointcutName:切入点名字,可以使用该名字进行引用该切入点表达式。
- 声明通知,具体方法和基于schema配置差不多
@Pointcut(value="切入点表达式", argNames = "参数名列表")
public void pointcutName(……) {}