Spring AOP:面向切面编程,AspectJ,是基于spring 的xml文件的方法
导包等不在赘述;
建立一个接口:ArithmeticCalculator,没有实例化的方法;
package com.atguigu.spring.aop.impl.panpan; public interface ArithmeticCalculator { //创建一个接口,其是抽象的类,不能实例化 int add(int i,int j); int sub(int i,int j); int mul(int i,int j); int div(int i,int j); }
建立一个类:ArithmeticCalculatorImpl 继承于接口:ArithmeticCalculator,实现接口中没有实例化的方法
package com.atguigu.spring.aop.impl.panpan; import org.springframework.stereotype.Component; public class ArithmeticCalculatorImpl implements ArithmeticCalculator { @Override public int add(int i, int j) { int result=i+j; return result; } @Override public int sub(int i, int j) { int result=i-j; return result; } @Override public int mul(int i, int j) { int result=i*j; return result; } @Override public int div(int i, int j) { int result=i/j; return result; } }
建立类:ArithmeticCalculatorLoggingProxy,实例化一些面向切面编程的方法
package com.atguigu.spring.aop.impl.panpan; import java.util.Arrays; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; public class ArithmeticCalculatorLoggingProxy { //前置通知的方法,在xml文件中可以通过method这个属性获取该方法的方法名,joinPoint是切点, public void beforeMethod(JoinPoint joinPoint){ //获取方法名,和参数值,参数值要多个,所以用数组集合的方法 String methodName=joinPoint.getSignature().getName(); Object[] args=joinPoint.getArgs(); System.out.println("The method "+methodName+" begains "+Arrays.asList(args)); } //后置通知的方法 public void afterMethod(JoinPoint joinPoint){ //获取方法名,和参数值 String methodName=joinPoint.getSignature().getName(); System.out.println("The method "+methodName+ " ends"); } //返回通知的方法 public void afterReturning(JoinPoint joinPoint,Object result){ //获取方法名,和参数值 String methodName=joinPoint.getSignature().getName(); System.out.println("The method "+methodName+ " *** ends :"+result); } //异常通知的方法 public void afterThrowing(JoinPoint joinPoint, Exception e){ String methodName=joinPoint.getSignature().getName(); System.out.println("The method "+methodName+ " Exception :"+ e); } //环绕通知的 public Object aroundMethod(ProceedingJoinPoint pjp){ Object result=null; //获取方法名 String methodName=pjp.getSignature().getName(); try { //前置通知,Arrays.asList(pjp.getArgs())为该方法的参数个数,为数组集合 System.out.println("The method "+methodName+" begains "+Arrays.asList(pjp.getArgs())); //执行目标方法 result=pjp.proceed(); //返回通知 System.out.println("The method "+methodName+ " ends with :"+result); } catch (Throwable e) { //异常通知 System.out.println("The method " +methodName+ " occurs exception "+ e); e.printStackTrace(); } //后置通知 System.out.println("The method " + methodName + " ends"); return result; } }
建立spring的xml文件,进行bean和AOP的配置
<!-- 配置bean ,全类名是继承接口类的全类名--> <bean id="arithmeticCalculator" class="com.atguigu.spring.aop.impl.panpan.ArithmeticCalculatorImpl"></bean> <!-- 配置切面的bean ,全类名是实现切面编程的类全类名--> <bean id="arithmeticCalculatorLoggingProxy" class="com.atguigu.spring.aop.impl.panpan.ArithmeticCalculatorLoggingProxy"></bean> <!-- 配置AOP --> <aop:config> <!-- 配置切点表达式,全类名为接口的全类名 --> <aop:pointcut expression="execution(* com.atguigu.spring.aop.impl.panpan.ArithmeticCalculator.*(int,int))" id="pointcut"/> <!-- 配置切面及通知 method中的为方法名,--> <aop:aspect ref="arithmeticCalculatorLoggingProxy" order="1"> <aop:before method="beforeMethod" pointcut-ref="pointcut"/> <aop:after method="afterMethod" pointcut-ref="pointcut"/> <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/> <aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/> <aop:around method="afterMethod" pointcut-ref="pointcut" /> </aop:aspect> </aop:config>
建立类Main,进行测试
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.test.xml"); //ArithmeticCalculator,是一个接口类,注解的是继承该接口的类 ArithmeticCalculator impl=(ArithmeticCalculator) ctx.getBean("arithmeticCalculator"); System.out.println(impl.getClass().getName()); int result=impl.add(12,2); System.out.println(result); double result2=impl.div(12, 2); System.out.println(result2);