具体步骤
/*
* 1.先创建一个User类
* 2.再创建一个UserProxy类:
* 在增强类里面,创建方法,让不同的方法代表不同的通知(增强)
* 3.进行通知的配置
* 在Spring配置文件中,开启注解扫描
* 使用注解创建User和UserProxy对象
* 在增强类上面添加注解@Aspect
* 在Spring配置文件中开启 生成代理对象
* 4.配置不同类型的通知
* 在增强类的里面,在作为通知(增强)方法上添加通知类型注解,使用切入点表达式配置
* */
用到的注解
1.@Aspect
该注解放在类的上面,加了该注解的类表示将该类设为切面,表明要在该类中存放通知
2.@Before
参数是切入点表达式:“execution(* 全限定路径.原方法名(…))”
该注解放在方法上,表明该方法要作为原方法(切入点)的前置通知
3.@After
参数是切入点表达式:“execution(* 全限定路径.原方法名(…))”
该注解放在方法上,表明该方法要作为原方法(切入点)的最终通知
不管切入点方法是否出现异常,后置通知都执行!
4.@AfterReturning
参数是切入点表达式:“execution(* 全限定路径.原方法名(…))”
该注解放在方法上,表明该方法要作为原方法(切入点)的后置通知
如果切入点方法出现异常,后置通知不执行!
5.@Around
参数是切入点表达式:“execution(* 全限定路径.原方法名(…))”
该注解放在方法上,表明该方法要作为原方法(切入点)的环绕通知
既是环绕,所以有“两个通知”
具体实现
被增强的类
package package1;
//被增强的类
import org.springframework.stereotype.Component;
@Component
public class User {
public void add(){
System.out.println("add...");
}
}
存放通知的类
package package1;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect//存在增强的类称为切面--@Aspect将当前面设为切面,供容器读取
public class UserProxy {
//前置通知
//execution(...)为切入点表达式,表明哪个方法被增强
@Before("execution(* package1.User.add(..))")//表示作为前置通知:在增强方法的前面执行
public void before(){
System.out.println("before...");
}
//最终通知:不管被增强的方法(这里是add)是否出现异常,都执行
@After("execution(* package1.User.add(..))")
public void after(){
System.out.println("after...");
}
//后置(返回)通知:如果被增强的方法(这里是add)出现异常,不执行
@AfterReturning("execution(* package1.User.add(..))")
public void afterReturning() {
System.out.println("afterReturning...");
}
//环绕通知
@Around("execution(* package1.User.add(..))")
public void Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕之前");
proceedingJoinPoint.proceed();
System.out.println("环绕之后");
}
}
bean1.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: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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启注解扫描-->
<context:component-scan base-package="package1"></context:component-scan>
<!--开启Aspect生成代理对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
Test类
public class MyTest {
@Test
public void testAopAnno(){
ApplicationContext context=
new ClassPathXmlApplicationContext("bean1.xml");
User user = context.getBean("user", User.class);
user.add();
}
}
测试结果
环绕之前
before...
add...
afterReturning...
after...
环绕之后