目录
1.定义主配置类
package com.qz.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import com.qz.aop.LogAspects;
import com.qz.aop.MathCaculator;
/**
* 【AOP底层就是动态代理】
* AOP: 指的是在程序运行期间动态的将某段代码插入到某个方法的指定位置的编程方式
* 1、导入AOP模块;Spring-aspects Jar包
* 2、定义一个业务逻辑类(Mathcaculator)
* 3、定义一个切面类(LogAspects),切面类里面的方法需要动态感知目标方法执行到什么位置
* 通知方法:
* 前置通知:@Before 在目标方法运行之前运行
* 后置通知:@After 在目标方法运行结束之后运行(无论正常还是异常)
* 返回通知:@AfterReturning 在目标方法正常返回之后运行
* 异常通知:@AfterThrowing 在目标方法出现异常之后运行
* 环绕通知:@Around 动态代理,手动推进目标方法的运行
* 4、给切面类目标方法标注何时何地运行(通知注解);
* 5、将切面类和目标方法类都加入到spring容器中;
* 6、必须告诉Spring哪个是切面类,给切面类上加一个注解(@Aspect)
* [重点]7、开启基于注解的切面(@EnableAspectJAutoProxy)
*/
@Configuration
@EnableAspectJAutoProxy
public class MainConfigOfAOP {
@Bean
public MathCaculator caculator(){
return new MathCaculator();
}
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
}
2.定义目标类
package com.qz.aop;
public class MathCaculator {
public int div(int i,int j){
System.out.println("Math............");
return i/j;
}
}
3.定义切面类
package com.qz.aop;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class LogAspects {
/**
* 抽取公共的切入表达式
* 1、本类使用此切面表达式:@Before(" pointCut()")
* 2、其他切面类引用:@Before("com.qz.aop.LogAspects.pointCut()")
*/
@Pointcut("execution(public int com.qz.aop.MathCaculator.*(..))") //有很多的写的方法
public void pointCut(){};
/*
在目标方法之前切入
@Before("public int com.qz.aop.MathCaculator.div(int, int)") //指定div方法切入,指定参数类型
@Before("public int com.qz.aop.MathCaculator.*(..)") //所有的方法、所有的参数类型
public void logStart(){
System.out.println("除法开始运行。。。参数:{}");
}
*/
@Before("pointCut()") //所有的方法、所有的参数类型
public void logStart(JoinPoint joinPoint){
System.out.println( joinPoint.getSignature().getName() + "方法开始...参数列表:{" + Arrays.asList(joinPoint.getArgs()) + "}");
}
@After("pointCut()")
public void logEnd(JoinPoint joinPoint){
System.out.println(joinPoint.getSignature().getName() +"结束。。。");
}
@AfterReturning(value="pointCut()",returning="myresult")
public void logReturn(JoinPoint joinPoint,Object myresult){//JoinPoint joinPoint必须放在第一个参数里面
System.out.println(joinPoint.getSignature().getName() +"正常返回。。。返回值:{"+ myresult +"}");
}
@AfterThrowing(value="pointCut()",throwing="myException")
public void logException(JoinPoint joinPoint,Exception myException){
System.out.println(joinPoint.getSignature().getName() +"除法异常。。。异常信息:。。。"+myException);
}
}
4.开始测试
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.qz.aop.MathCaculator;
import com.qz.config.MainConfigOfAOP;
public class AOPTest {
@Test
public void test(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
MathCaculator bean = context.getBean(MathCaculator.class);
int div = bean.div(4, 2);
}
}
/*
结果:
div方法开始...参数列表:{[4, 2]}
Math............
div结束。。。
div正常返回。。。返回值:{2}
*/
//异常测试:
public class AOPTest {
@Test
public void test(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
MathCaculator bean = context.getBean(MathCaculator.class);
int div = bean.div(4, 0);
}
}
/*
结果:
div方法开始...参数列表:{[4, 0]}
Math............
div结束。。。
div除法异常。。。异常信息:。。。java.lang.ArithmeticException: / by zero
*/