簡單解釋下AOP
能在程序運行期間冤荆,能動態(tài)的將某段代碼切入到指定的位置進行運行的編程方式
測試過程
* 1、模塊導入spring-aspects
* 2卤橄、定義一個業(yè)務邏輯類MathCalculator,在業(yè)務邏輯運行的時候辛蚊,將日志進行打印
* 3粤蝎、定義一個日志切面類:LogAspect,需要感知MathCalculator運行到哪里,并進行執(zhí)行
* 通知方法:
* 前置通知(@Before):logStart
* 后置通知(@After):logEnd
* 返回通知(@AfterReturning):logReturn
* 異常通知(@AfterThrowing):logException
* 環(huán)繞通知(@Around):動態(tài)代理,手動推進目標方法的運行(joinPoint.procced())
* 4奈虾、給切面類的目標方法標注何時何地運行
* 5筹燕、將切面類和業(yè)務邏輯類都加入到容器中
* 6韧掩、告訴Spring,哪個類是切面類(給切面類上家一個注解)
* 7、需要給配置類加上@EnableAspectJAutoProxy,表示【開啟基于注解的AOP模式】
* 在spring中有很多的Enable開頭的注解延柠,都是開啟某個基于注解的功能
邏輯類
/**
* @author huangxiaoting
* @date 2019/8/26 15:24
*/
public class MathCalculator {
public int div(int i,int j){
return i/j;
}
}
切面類
/**
* @author huangxiaoting
* @date 2019/8/26 15:27
*/
//目的是告訴spring,這是一個切面類
@Aspect
public class LogAspect {
@Pointcut("execution(public int com.dwd.snail.testspring.test.aop.MathCalculator.*(..))")
public void pointCut(){
}
@Before("pointCut()")
//JoinPoint一定要出現(xiàn)在參數(shù)比表的第一位
public void logStart(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
System.out.println(""+ joinPoint.getSignature().getName()+"運行锣披。贞间。。參數(shù)列表是:{"+ Arrays.asList(args) +"}");
}
@After("com.dwd.snail.testspring.test.aop.LogAspect.pointCut()")
public void logEnd(JoinPoint joinPoint){
System.out.println(""+ joinPoint.getSignature().getName()+"除法結(jié)束雹仿。增热。。");
}
@AfterReturning(value = "pointCut()",returning = "result")
public void logReturn(Object result){
System.out.println("除法正常返回胧辽。钓葫。。計算結(jié)果是:{"+result+"}");
}
@AfterThrowing(value ="pointCut()",throwing = "exception")
public void logException(Exception exception){
System.out.println("除法異常票顾。。帆调。異常信息是:{"+exception+"}");
}
}
配置類
@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {
//業(yè)務邏輯類加入到容器中
@Bean
public MathCalculator mathCalculator(){
return new MathCalculator();
}
//切面類也加入到容器中
@Bean
public LogAspect logAspect(){
return new LogAspect();
}
}
測試類
public class IocTest_Aop {
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
@Test
public void test01(){
// printBeans(applicationContext);
// applicationContext.close();
MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
mathCalculator.div(1,1);
//這種方式是是普通的new一個實例對象奠骄,并沒有交給spring容器管理,所以切面的功能也不會滲透進去
// MathCalculator mathCalculator2=new MathCalculator();
// mathCalculator2.div(1,2);
}
// private void printBeans(AnnotationConfigApplicationContext applicationContext){
// String[] names=applicationContext.getBeanDefinitionNames();
// for (String name:names){
// System.out.println(name);
// System.out.println(applicationContext.getBean(name));
// }
// }
}
正常的結(jié)果展示
div運行番刊。含鳞。。參數(shù)列表是:{[1, 1]}
div除法結(jié)束芹务。蝉绷。。
除法正常返回枣抱。熔吗。。計算結(jié)果是:{1}
異常的結(jié)果展示
div運行佳晶。桅狠。。參數(shù)列表是:{[1, 0]}
div除法結(jié)束。中跌。咨堤。
除法異常。漩符。一喘。異常信息是:{java.lang.ArithmeticException: / by zero}