(1)Spring AOP的简单应用:
-->AOP:(Aspect Orinted Programming)面向切面编程,用于具有横切逻辑的场合,如:访问控制,事务管理,性能检测,由切入点和增强处理组成。
AOP主要核心是:在什么位置(pointcut:切入点)执行什么功能(advice:增强处理),AOP在Java里是利用反射机制实现,
关键词:
-->Aspect(切面):一个模块化的横切逻辑,类似于 Java 中的类声明。
-->Join Point(连接点):原程序执行过程中的某一个点,构造方法调用,字段的设置和获取,方法的调用,方法的执行,异常的处理执行,类的初始化。比如方法1-->方法2-->方法3,此时方法2可以称作一个连接点
-->Advice(增强处理):在连接点上执行的代码逻辑,Advice 定义了在 Pointcut
里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。eg:在2的前后加上日志输出
-->Pointcut(切入点):对连接点的描述,即匹配的条件,它定义了相应的 Advice 将要发生的地方,eg:假如符合2连接点的某一个特征,执行增强程序
-->Target Object(目标对象):被切面增强的对象
-->Weaving(织入):执行增强处理程序的过程
xml文件配置实现方式:
1 <!-- 注解方式配置事物 --> 2 <tx:annotation-driven transaction-manager="transactionManager" /> 3 <bean class="com.one.ssm.impl.aopTest.UserServiceLogger" /> 4 <aop:aspectj-autoproxy/> 5 注意:需要在配置文件中加入<aop:aspectj-autoproxy/>就可以启用对@AspectJ注解的支持 6 <!--Aop配置实例--> 7 <bean id="thLogger" class="com.one.ssm.impl.aopTest.UserServiceLogger"></bean> 8 <aop:config> 9 <aop:pointcut id="pointcut" expression="execution(public void *(..))"></aop:pointcut> 10 <aop:aspect ref="thLogger"> 11 <!--前置增强--> 12 <aop:before method="before" pointcut-ref="pointcut"/> 13 <!--后置增强--> 14 <aop:after-returning returning="result" method="afterRunning" pointcut-ref="pointcut"/> 15 <!--异常抛出增强--> 16 <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/> 17 <!--实现最终增强,无论如何都要执行,相当于finally--> 18 <aop:after method="afterLogger" pointcut-ref="pointcut"/> 19 <!--实现环绕增强,通过方法名为ProceedingJoinPoint类型的参数获取连接点的信息 20 她的proceed()方法可以调用真正的目标方法,实现对连接点的完全控制--> 21 <aop:around method="aroundLogger" pointcut-ref="pointcut"/> 22 </aop:aspect> 23 </aop:config>
xml配置方式
注解实现方式:
1 @Aspect //将UserServiceLogger 定义为切面 2 public class UserServiceLogger { 3 private static final Logger log=Logger.getLogger("UserServiceLogger.class"); 4 5 @Before("excution(*service.UserService.*(..))")//将before()方法定义为前置增强 6 public void before(JoinPoint jp){ 7 log.info("前置增强:调用"+jp.getSignature().getName().toString()+"的方法执行," + 8 "方法入参:"+Arrays.toString(jp.getArgs())); 9 } 10 @ afterRunning("excution(*service.UserService.*(..))" returning =result) //代表将afterRunning()方法定义为后置增强 11 public void afterRunning(JoinPoint jp,Object result){ 12 log.info("后置增强"+jp.getSignature().getName().toString()+"的方法执行"+ 13 "方法入参:"+Arrays.toString(jp.getArgs())); 14 } 15 //异常抛出增强 16 public void afterThrowing(JoinPoint jp,RuntimeException e){ 17 log.info(jp.getSignature().getName().toString()+"方法异常为:"+e); 18 } 19 //最终增强 20 public void afterLogger(JoinPoint jp){ 21 log.info(jp.getSignature().getName().toString()+"方法结束执行。"+ 22 "方法入参:"+Arrays.toString(jp.getArgs())); 23 } 24 //环绕增强 25 public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable { 26 log.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName().toString()+"方法。方法入参:" 27 + Arrays.toString(jp.getArgs())); 28 try { 29 //执行目标方法并获得返回值 30 Object result=jp.proceed(); 31 log.info("调用"+jp.getTarget()+"的"+jp.getSignature().getName().toString()+result); 32 return result; 33 } catch (Throwable e) { 34 log.info(jp.getSignature().getName().toString()+"方法发生异常"+e); 35 throw e; 36 }finally { 37 log.info(jp.getSignature().getName().toString()+"方法结束执行"); 38 }
java代码实现
(2)execution表达式实例与概念说明
execution() 表达式的主体;
第一个”*“符号 表示返回值的类型任意;
包名后面的”..“ 表示当前包及子包
第二个”*“ 表示类名 表示所有类。
.*(..) 表示任何方法名, 括号表示参数,两个点表示任何参数类型
基本语法格式为:
execution(<修饰符模式>?<返回类型模式><方法名模式>(<参数模式>)<异常模式>?) 除了返回类型模式、方法名模式和参数模式外,其它项都是可选的。
execution(public * *(..)):任意公共方法的执行
execution(* *To(..)):匹配目标类所有以To为后缀的方法
execution(* com.xyz.service.AccountService.*(..)) :定义在service包里的任意方法的执行
execution(* com.xyz.service.*.*(..)) :定义在service包和所有子包里的任意类的任意方法的执行:
execution(* com..*.*Dao.find*(..)) :匹配包名前缀为com的任何包下类名后缀为Dao的方法,方法名必须以find为前缀
execution(* joke(String,..))):匹配目标类中的joke()方法,该方法第 一个入参为String,后面可以有任意个入参且入参类型不限,如joke(String s1)、joke(String s1,String s2)和joke(String s1,double d2,Strings3)都匹配
以上内容个人学习所得,仅供参考!!!
原文地址:https://www.cnblogs.com/zxh-xy/p/10699455.html