aspectj

来源:互联网 发布:移动宽带网络参数设置 编辑:程序博客网 时间:2024/06/05 02:07

使用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

@Aspectpublic 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@Aspectpublic class PointcutDefine {    //指定了pointcut。方法 customerLog 是一个签名,在 Advice 中可以用此签名代替切入点表达式,所以不需要在方法体内编写实际代码,只起到助记功能    @Pointcut("execution(* test.CustomerBo.*(..))")    public void customerLog(){    }}@Aspectpublic 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>