aspectj

xiaoxiao2021-02-28  63

使用proxy指定劫持的class和需要的advise或者advisor advise是用来指定需要插入的内容和位置 advisor传入advise用来指定method advise有四种形式 before: MethodBeforeAdvice 在方法调用前

public class HijackBeforeMethod implements MethodBeforeAdvice { public void before(Method arg0, Object[] args, Object target) throws Throwable { System.out.println("HijackBeforeMethod : Before method hijacked!"); } }

afterreturning:AfterReturningAdvice 在方法返回后

public class HijackAfterMethod implements AfterReturningAdvice { public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("HijackAfterMethod : After method hijacked!"); } }

after-throwing:ThrowsAdvice 抛出异常时

public class HijackThrowExceptionMethod implements ThrowsAdvice { public void afterThrowing(IllegalArgumentException e) throws Throwable { System.out.println("HijackThrowException : Throw exception hijacked!"); } }

around:MethodInterceptor 可以在实现这个借口的类里面同时实现上面三个功能

public class HijackAroundMethod implements MethodInterceptor { public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("Method name : " + methodInvocation.getMethod().getName()); System.out.println("Method arguments : " + Arrays.toString(methodInvocation.getArguments())); // 相当于 MethodBeforeAdvice System.out.println("HijackAroundMethod : Before method hijacked!"); try { // 调用原方法,即调用CustomerService中的方法 Object result = methodInvocation.proceed(); // 相当于 AfterReturningAdvice System.out.println("HijackAroundMethod : After method hijacked!"); return result; } catch (IllegalArgumentException e) { // 相当于 ThrowsAdvice System.out.println("HijackAroundMethod : Throw exception hijacked!"); throw e; } } }

xml文档

<bean id="hijackBeforeMethodBean" class="com.shiyanlou.spring.aop.advice.HijackBeforeMethod" /> <bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-指定需要劫持的class-> <property name="target" ref="customerService" /> <!--指定advise--> <property name="interceptorNames"> <list> <value>hijackAroundMethodBean</value> </list> </property> </bean>

最后从context中获得的bean是代理器而不是劫持的class本身

public class App { public static void main(String[] args) { ApplicationContext appContext = new ClassPathXmlApplicationContext( new String[] { "SpringAOPAdvice.xml" }); CustomerService cust = (CustomerService) appContext.getBean("customerServiceProxy"); System.out.println("*************************"); cust.printName(); System.out.println("*************************"); cust.printURL(); System.out.println("*************************"); try { cust.printThrowException(); } catch (Exception e) { } } }

注解实现aspectj

@Aspect public class LoggingAspect { //*表示任意的返回类型,后面是指定的class和method。(..)指任意的参数,class和method可以用*来表示任意class或者method @Before("execution(public * com.shiyanlou.spring.aop.aspectj.CustomerBo.addCustomer(..))") public void logBefore(JoinPoint joinPoint){ System.out.println("logBefore() is running ..."); System.out.println("hijacked:"+joinPoint.getSignature().getName()); System.out.println("**********"); } @After("execution(public * com.shiyanlou.spring.aop.aspectj.CustomerBo.deleteCustomer(..))") public void logAfter(JoinPoint joinPoint){ System.out.println("logAfter() is running ..."); System.out.println("hijacked:"+joinPoint.getSignature().getName()); System.out.println("**********"); } } 以上是同时实现了pointcut和advise @Aspect public class PointcutDefine { //指定了pointcut。方法 customerLog 是一个签名,在 Advice 中可以用此签名代替切入点表达式,所以不需要在方法体内编写实际代码,只起到助记功能 @Pointcut("execution(* test.CustomerBo.*(..))") public void customerLog(){ } } @Aspect public class LoggingAspect { //通过签名来找到pointcut然后写advise @Before("test.PointcutDefine.customerLog()") public void logBefore(JoinPoint joinPoint){ System.out.println("logBefore() is running ..."); System.out.println("hijacked:"+joinPoint.getSignature().getName()); System.out.println("**********"); } @After("test.PointcutDefine.customerLog()") public void logAfter(JoinPoint joinPoint){ System.out.println("logAfter() is running ..."); System.out.println("hijacked:"+joinPoint.getSignature().getName()); System.out.println("**********"); } } xml文档 <?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:util="http://www.springframework.org/schema/util" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <aop:aspectj-autoproxy/> <bean id="customerBo" class="test.CustomerBo"/> <bean id="loggingAspect" class="test.LoggingAspect"/> <beans>
转载请注明原文地址: https://www.6miu.com/read-39463.html

最新回复(0)