【AOP系列】(四)—采用Spring的静态配置文件实现AOP

前提

在可以使用注解的地方也可以再配置文件中进行配置。

实现步骤

  同上一篇文章的步骤,只是去掉了LogHandler中的注解,并把配置信息移到了配置文件中。

<!--通过配置信息描述Aspect,Advice,Pointcut等信息 -->
    <aop:config>
        <aop:aspect id="logAspect" ref="logHandler">
            <aop:pointcut id="addAddMethod" expression="execution(* add*(..))" />
            <aop:before method="WriteLog" pointcut-ref="addAddMethod"/>
        </aop:aspect>
    </aop:config>

表达式

表达式描述了将Advice应用在那些JoinPoint上。
示例:如只将Advice应用在com.tgb.spring包下的所有类中的add和delete方法上

<!--通过配置信息描述Aspect,Advice,Pointcut等信息 -->
    <aop:config>
        <aop:aspect id="logAspect" ref="logHandler">
            <aop:pointcut id="addAddMethod" expression="execution(* com.tgb.spring.*.add*(..)) || execution(* com.tgb.spring.*.delete*(..))" />
            <aop:before method="WriteLog" pointcut-ref="addAddMethod"/>
        </aop:aspect>
    </aop:config>

【注】:当客户端调用find方法时,代理依然会生成,只是Advice(打印日志的方法)不会应用到find方法上。

任意公共方法的执行:

execution(public * *(..))

任何一个以“set”开始的方法的执行:

execution(* set*(..))

AccountService 接口的任意方法的执行:

execution(* com.xyz.service.AccountService.*(..))

定义在service包里的任意方法的执行:

execution(* com.xyz.service.*.*(..))

补充

如何获得客户端参数?

JDK的动态代理

 public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("start-->>" + method.getName());
        for (int i=0; i<args.length; i++) {
            System.out.println(args[i]);
        }
        Object ret = null;
        try {
            //调用目标方法
            ret = method.invoke(targetObject, args);
            System.out.println("success-->>" + method.getName()); 
        }catch(Exception e) {
            e.printStackTrace();
            System.out.println("error-->>" + method.getName());
            throw e;
        }
        return ret;
    }

通过invoke方法中的method参数可以拿到客户端调用的方法,通过args可以获得客户端传进来的参数。那么在Spring的实现方式中,如何拿到呢?

通过JoinPoint类。

public class LogHandler {

    public void WriteLog(JoinPoint joinPoint){
        int argLength =joinPoint.getArgs().length;
        //打印客户端参数
        for(int i=0;i<argLength;i++){
            System.out.println(joinPoint.getArgs()[i]);
        }
        //打印方法名
        System.out.println(joinPoint.getSignature().getName());
        System.out.println("打印日志……………………………………");
    }
}

总结

这里对比一下xml和注解方式的优缺点。

xml配置文件方式优点
1、容易修改,不需要重新编译。
2、对象之间的关系一目了然。
3、xml配置文件比注解功能齐全。

xml配置文件方式缺点
1、配置文件配置工作量相对注解要大。
2、配置文件过多的时候不易管理。

注解方式优点
1、在class文件中,可以降低维护成本
2、提高开发效率。

注解方式缺点
1、如果对annotation进行修改,需要重新编译整个工程。
2、分散到各个class文件中,所以不易维护。
3、加载顺序问题,XML里定义的bean比在注解里定义的加载早,有时候还是得依赖XML。

你可能感兴趣的:(spring,AOP)