AOP :(动态代理)指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式。
通知方法:
前置通知(@Before):logStart:在目标方法(div)运行之前运行
后置通知(@After):logEnd:在目标方法(div)运行结束之后运行(无论方法正常结束还 是异常结束)
返回通知(@AfterReturning):logReturn:在目标方法(div)正常返回之后运行
异常通知(@AfterThrowing):logException:在目标方法(div)出现异常以后运行
环绕通知(@Around):动态代理,手动推进目标方法运行(joinPoint.procced())
例子:
1,编写一个切面类:
package com.aop.test;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import java.util.Arrays;
@Aspect
public class AopAspect {
@Pointcut("execution(public int com.aop.test.MathCalculatorTest.*(..))")
public void pointCut(){};
@Before("pointCut()")
public void aopStart(JoinPoint joinPoint){
Object[] s =joinPoint.getArgs();
System.out.println("运行before:"+ Arrays.asList(s));
}
@After("pointCut()")
public void aopEnd(JoinPoint joinPoint){
System.out.println("运行after:"+joinPoint.getSignature().getName());
}
@AfterReturning(value="pointCut()" ,returning = "result")
public void aopReturnAfter(JoinPoint joinPoint,Object result){
System.out.println("运行AfterReturning:"+result);
}
@AfterThrowing(value = "pointCut()",throwing = "exception")
public void aopExceptionAfter(JoinPoint joinPoint,Exception exception){
System.out.println("运行AfterThrowing:"+exception);
}
}
2,编写一个方法类:
package com.aop.test;
public class MathCalculatorTest {
public int div(int a,int b){
return a/b;
}
}
3,编写一个配置类:
package com.aop.test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@EnableAspectJAutoProxy
@Configuration
public class AopConfig {
//业务逻辑类加入容器中
@Bean
public MathCalculatorTest calculator(){
return new MathCalculatorTest();
}
//切面类加入到容器中
@Bean
public AopAspect aopAspect(){
return new AopAspect();
}
}
4,编写一个测试类:
package com.aop.test;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AopTest {
@Test
public void Test(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AopConfig.class);
MathCalculatorTest m =applicationContext.getBean(MathCalculatorTest.class);
m.div(1,1);
}
}
测试结果如下:
编写流程:
1)、将业务逻辑组件和切面类都加入到容器中;告诉Spring哪个是切面类(@Aspect)
2)、在切面类上的每一个通知方法上标注通知注解,告诉Spring何时何地运行(切入点表达式)
3)、开启基于注解的aop模式;@EnableAspectJAutoProxy