- 原理,导入AspectJ的jar包,并且在spring的配置文件中做以下声明,这一句是告诉Spring如果创建对象的时候符合切面类的筛选条件(其实就是切入点表达式)时候,Spring不会创建原生的对象,而是会创建出一个代理对象。
<aop:aspectj-autoproxy/>
-
jar包链接:https://pan.baidu.com/s/1mgiprsaUUQz3kBcDgBF60g 提取码:38is
-
程序结构
-
程序
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--组件扫描--> <context:component-scan base-package="com.aspectj.annotation"/> <!--生成代理--> <aop:aspectj-autoproxy/> </beans>
package com.aspectj.annotation.calculator; public interface Calculator1 { int add(int a, int b); int sub(int a, int b); int div(int a, int b); }
package com.aspectj.annotation.calculator; import org.springframework.stereotype.Component; @Component public class CalculatorIImpl implements Calculator1 { @Override public int add(int a, int b) { return a+b; } @Override public int sub(int a, int b) { return a-b; } @Override public int div(int a, int b) { return a / b; } }
package com.aspectj.annotation; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; import java.util.Arrays; /** * 日志切面 */ @Component //标志为一个组件 @Aspect //标识为一个切面 public class LoggingAspect { /** * 前置通知: 在目标方法(连接点)执行之前执行的方法 */ @Before("execution(public int com.aspectj.annotation.calculator.CalculatorIImpl.add(int, int))") public void beforeMethod(JoinPoint joinPoint){ Object [] methodArgs = joinPoint.getArgs(); System.out.println("前置方法 LogginAspect==> the method start args: " + Arrays.asList(methodArgs) ); String methodName = joinPoint.getSignature().getName(); System.out.println("前置方法 LoginAspect ==> the method : "+ methodName + "is start.") ; } /** * 后置通知: 在目标方法执行之后执行,特点: 不管目标方法是否抛出异常都会执行 * 不能获得方法的结果的!!!!!!!!!!!! * 1、* com.as 这个星号代表任意修饰符任意返回值 * 2、CalculatorIImpl.* 这个星号代表任意方法名 * 3、calculator.* 这个包下任何类 * 4、 (..) 代表任意参数列表 * * * 连接点对象 */ @After("execution(* com.aspectj.annotation.calculator.*.*(..))") public void afterMethod(JoinPoint joinPoint){ String methodName = joinPoint.getSignature().getName(); System.out.println("后置方法 LoginAspect ==> the method: "+ methodName + "is end"); } /** * 返回方法,在目标方法正常执行后,可以获取到该方法的返回值 * 通过returning指定一个名字,这个名字必须和方法的一个参数名字一样 */ @AfterReturning(value = "execution(* com.aspectj.annotation.calculator.*.*(..))", returning = "result") public void afterReturning(JoinPoint joinPoint, Object result){ String methodName = joinPoint.getSignature().getName(); System.out.println("返回值方法 Loggin the method" + methodName + "end, it’s result is " + result); } /** * 异常方法,在方法抛出异常的时候执行 * 和返回值处理方法相似,要在注解中加入一个和入参名字相同的设置 * 可以通过入参中指定异常的类型来指定抛出指定异常的时候才执行 */ @AfterThrowing(value = "execution(* com.aspectj.annotation.calculator.*.*(..))", throwing = "ex") public void afterThrowing(JoinPoint joinPoint, ArithmeticException ex){ System.out.println("异常处理方法 " + joinPoint.getSignature().getName() + "该异常是 :" + ex ) ; } /** * 环绕通知: 环绕着目标方法执行,可以理解为上边四种方法的结合体, * 更像是动态代理的整个过程 */ @Around(value = "execution(* com.aspectj.annotation.calculator.*.*(..))") public Object aroundMethod (ProceedingJoinPoint pjp){ // 执行动态方法 try{ // 前置通知 System.out.println("前置, 方法名为" + pjp.getSignature().getName() + "参数列表为" + Arrays.asList(pjp.getArgs()) ); Object result = pjp.proceed(); System.out.println(); return result; }catch (Throwable e){ // 异常通知 System.out.println("环绕通知异常" + e); }finally { // 后置通知 System.out.println("环绕通知后置"); } return null; } }
package com.aspectj.annotation.calculator; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String []args){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml"); // 获取 Calculator1 calculator1 = applicationContext.getBean("calculatorIImpl", Calculator1.class); System.out.println(calculator1.getClass().getName()); // int result = calculator1.add(1,1); int result1 = calculator1.div(1, 0); // System.out.println(result); } }
Spring 之使用AspectJ实现动态代理
最新推荐文章于 2024-09-02 10:10:31 发布