当前位置: 首页 > Linux

面试必问的AOP你知道吗?如何通过Spring实现呢?

时间:2023-04-07 01:04:29 Linux

面试必问的AOP你知道吗?如何通过Spring实现呢?【外链图片传输失败,源站可能有防盗链机制,建议保存图片直接上传(img-snqWdFPL-1600248731209)(https://imgkr.cn-bj.ufileos.c...]AspectOrientedProgramming即面向切面的编程,与oop面向对象编程相比,Aop不再关注程序代码中的某个类和某些方法,而是aop考虑更多的是面切,也就是layer和layer之间的一种切割,所以叫section.想想大家吃的汉堡包(中间夹着肉).那么aop是如何拦截整个surface的呢?考虑servlet的配置urlpattern/*学到了,实际上面也是aop的实现。SpringAop实现方法注解方法XML方法案例实践注解方法JAR包坐标导入org.aspectjaspectjweaver1.8.9/dependency>beans.xml配置添加命名空间xmlns:aop="http://www.springframework.org/schema/aop"http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd配置Aop代理编写aop实现类/***声明切面组件*/@Component@AspectpublicclassLogCut{/***定义入口点匹配方法规则定义*匹配规则表达式含义拦截com.xxx.service包及子包下所有类的所有方法*/@Pointcut("execution(*com.xxx.service..*.*(..))")publicvoidcut(){}/***声明预通知并将通知应用于定义的入口点*在执行目标类方法之前执行通知*/@Before(value="cut()")publicvoidbefore(){System.out.println("预先建议....");}/***声明返回通知并将通知应用于入口点*在执行目标类方法时执行通知*/@AfterReturning(value="cut()")publicvoidafterReturning(){System.输出原则tln("返回通知....");}/***声明最终通知并将通知应用到切入点*目标类方法执行过程中是否发生异常将被执行。通知相当于异常中的finally*/@After(value="cut()")publicvoidafter(){System.out.println("Finalnotification....");}/***声明异常通知并将通知应用到入口点*当目标类的方法执行时发生异常时执行通知*/@AfterThrowing(value="cut()",throwing="e")publicvoidafterThrowing(Exceptione){System.out.println("异常通知....方法执行异常时执行:"+e);}/***声明环绕通知并将通知应用到入口点*通过环绕通知在方法执行前后定义相应的处理*/@Around(value="cut()")publicObjectaround(ProceedingJoinPointpjp)throwsThrowable{System.out.println("surroundingleading...");System.out.println("周边通知");System.out.println(pjp.getTarget()+"--"+pjp.getSignature());Objectresult=pjp.proceed();//执行目标对象方法System.out.println("Surroundback...");返回结果;}}Aop匹配方法规则表达式语言(简要了解)Aop切入点表达式介绍执行任意public方法:execution(public*(..))executeanysetmethodexecution(*set*(..))executecom.xxx。服务包下任意类的任意方法execution(*com.xxx.service.*.*(..))执行com.xxx.service包及其子包下任意类中的任意方法execution(*com.xxx.service..*.*(..))配置切面,入口点,通知Definebean/***Declareaspectcomponent*/@ComponentpublicclassLogCut{publicvoidbefore(){System.out.println("Pre-notification....");}publicvoidafterReturning(){System.out.println("返回通知....");}publicvoidafter(){System.out.println("最终通知....");}publicvoidafterThrowing(Exceptione){System.out.println("异常通知...方法执行异常时执行:"+e);}publicObjectaround(ProceedingJoinPointpjp)throwsThrowable{System.out.println("环绕前方...");System.out.println("环绕通知");System.out.println(pjp.getTarget()+"--"+pjp.getSignature());对象结果=pjp.proceed();System.out.println("后置环绕...");返回结果;}}展开AOP基本概念JoinPoint(连接点)[动态]每一个被拦截的点,spring中指的是每一个被拦截的方法,springaop的一个连接点代表一个方法的执行。pointcut(入口点)[static]定义了连接点的拦截(匹配规则定义指定拦截哪些方法,处理哪些方法),spring有专门的表达式语言定义。通知(advice){emphasis}拦截每一个连接点(eachmethod)之前和之后要做的操作预通知(pre-enhancement)--before()执行方法之前的通知返回通知(returnenhancement)--afterReturning方法正常返回后的通知异常抛出通知(异常抛出增强)--afetrThrow()finalnotification--after无论方法是否异常,都会围绕通知执行通知--around围绕一个连接点(加入点)通知,例如方法调用。这是最强大的通知类型。环绕通知可以在方法调用前后完成自定义行为。它还会选择是继续执行连接点还是直接返回自己的返回值或者抛出异常结束Aspect(切面)的执行。入口点和建议的组合决定了切面的定义。whichmethods,notification定义了拦截方法之后要做什么,而aspect是对横切关注点的抽象,类似于类,类是对对象特性的抽象,aspect是对横切关注点的抽象的交叉关注点。Target(目标对象)是代理目标对象Weave(编织)这个将aspect应用到目标对象并生成代理对象的过程就是weave(过程)。Introduction(介绍)执行Aspect(切面)入口点和notification的组合,决定了切面的定义。入口点定义了要拦截哪些类的哪些方法,通知定义了拦截方法后要做什么。切面是横切的,关注点的抽象类似于类。类是对象特征的抽象,而方面是横切关注点的抽象。Target(目标对象)是代理目标对象Weave(编织)这个将aspect应用到目标对象并生成代理对象的过程就是weave(过程)。引入(introduction)在不修改原有应用程序代码的情况下,在程序运行时为类动态添加方法或字段的过程称为引入。