前提
在可以使用注解的地方也可以再配置文件中进行配置。
实现步骤
同上一篇文章的步骤,只是去掉了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。