使用步骤:
- 启动@AspectJ支持
- 声明切面:使用@Aspect注解进行声明
- 声明切入点:@Pointcut(value="切入点表达式", argNames = "参数名列表")
- value:指定切入点表达式
- argNames:指定命名切入点方法参数列表参数名字,可以有多个用“,”分隔,这些参数将传递给通知方法同名的参数,同时比如切入点表达式“args(param)”将匹配参数类型为命名切入点方法同名参数指定的参数类
- pointcutName:切入点名字,可以使用该名字进行引用该切入点表达式。
- 声明通知
- 前置通知:使用org.aspectj.lang.annotation 包下的@Before注解声明;
@Before(value = "切入点表达式或命名切入点", argNames = "参数列表参数名") value:指定切入点表达式或命名切入点; argNames:与Schema方式配置中的同义。
- 后置通知:同前置通知
- 后置返回通知:使用org.aspectj.lang.annotation 包下的@AfterReturning注解声明;
- 后置异常通知:使用org.aspectj.lang.annotation 包下的@After注解声明;
@AfterThrowing ( value="切入点表达式或命名切入点", pointcut="切入点表达式或命名切入点", argNames="参数列表参数名", throwing="异常对应参数名") value:指定切入点表达式或命名切入点; pointcut:同样是指定切入点表达式或命名切入点,如果指定了将覆盖value属性指定的,pointcut具有高优先级; argNames:与Schema方式配置中的同义; throwing:与Schema方式配置中的同义。
- 环绕通知:使用org.aspectj.lang.annotation 包下的@Around注解声明;
@Around (value="切入点表达式或命名切入点",argNames="参数列表参数名") value:指定切入点表达式或命名切入点; argNames:与Schema方式配置中的同义;
- 前置通知:使用org.aspectj.lang.annotation 包下的@Before注解声明;
实例
1.项目结构
2.代码
Person.java接口
package com.yiguang.Spring.springTest.test;
public interface Person {
public void eatBreakfast();
public void eatLunch();
public void eatSupper();
public String drink(String name);
}
BabyPerson.java
package com.yiguang.Spring.springTest.test;
import org.springframework.stereotype.Component;
@Component
public class BabyPerson implements Person{
public void eatBreakfast() {
System.out.println("小Baby正在吃早餐");
}
public void eatLunch() {
System.out.println("小Baby正在吃午餐");
}
public void eatSupper() {
System.out.println("小Baby正在吃晚餐");
}
public String drink(String name) {
return "小Baby在喝:"+name;
}
}
AdivceMethod.java
package com.yiguang.Spring.springTest.test;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class AdivceMethod {
@Before("execution(* com.yiguang.Spring.springTest.test.BabyPerson.*(..))")
// 匹配BabyPerson类所有的方法,注意*和com之间有个空格
public void beforeEat() {
System.out.println("-------------------这里是前置增强,吃饭之前先洗小手!--------------------");
}
@After("execution(* eatLunch(..))")
// 匹配该工程下所有的eatLunch方法
public void afterEat() {
System.out.println("-------------------这里是后置增强,午饭吃完要睡午觉!--------------------");
}
@Around("execution(* com.yiguang.Spring.springTest.test.BabyPerson.eatSupper())")
// 匹配该工程下BabyPerson的eatLunch方法
public Object aroundEat(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("-------------------这里是环绕增强,吃晚饭前先玩一玩!-------------------");
Object retVal = pjp.proceed();
System.out.println("-------------------这里是环绕增强,晚饭吃完后要得睡觉了!-------------------");
return retVal;
}
@AfterReturning(returning="rvt",pointcut="execution(* com.yiguang.Spring.springTest.test.BabyPerson.drink(..))")
public void log(Object rvt) {
System.out.println("-------------------这里是AfterReturning增强-------------------");
System.out.println("获取小Baby正在喝的饮料"+rvt);
System.out.println("记录每天喝的饮料容量");
}
}
Test.java
package com.yiguang.Spring.springTest.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ConfigurableApplicationContext context =
new ClassPathXmlApplicationContext("beans.xml");
Person person=(Person) context.getBean("babyPerson");
person.eatBreakfast();
System.out.println("===================================================");
person.eatLunch();
System.out.println("===================================================");
person.eatSupper();
System.out.println("===================================================");
person.drink("可乐");
System.out.println("===================================================");
}
}
beans.xml
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.yiguang.Spring.springTest.test"></context:component-scan>
<!-- 启动@AspectJ支持 -->
<!-- proxy-target-class默认"false",更改为"ture"使用CGLib动态代理 -->
<aop:aspectj-autoproxy proxy-target-class="false"/>
</beans>
执行结果: