Maven 的Pom里添加几个用到的包
<!-- AOP相关 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.12</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.12</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2</version>
</dependency>
Config 文件
<aop:config>
<aop:aspect ref="advice">
<aop:pointcut id="pointcut" expression="execution(* com.luxs.spring.ioc.*.*(..))"/>
<aop:before method="before" pointcut-ref="pointcut" />
<aop:after method="after" pointcut-ref="pointcut" />
<aop:around method="aroundLog" pointcut-ref="pointcut" />
</aop:aspect>
</aop:config>
表忘记声明
xmlns:aop=”http://www.springframework.org/schema/aop”
Aop Log类
package com.luxs.spring.aop;
import org.aspectj.lang.ProceedingJoinPoint;
public class Logger {
public void before() {
System.out.println("before method");
}
public void after() {
System.out.println("after method");
}
public Object aroundLog(ProceedingJoinPoint joinPoint) {
System.out.println("看好了,要特么开始了。");
Object[] args = joinPoint.getArgs();
// 有参数输出参数
if (args != null) {
for (Object obj : args) {
if(obj instanceof Integer)
System.out.println(obj.getClass());
}
}
// 要开始调用本体执行了
Object obj = null;
try {
obj = joinPoint.proceed(args);
} catch (Throwable e) {
// 异常处理
e.printStackTrace();
}
System.out.println("看好了,要特么结束了。");
return obj;
}
}
execution pointcut designator 执行表达式的格式
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
除了返回类型模式(上面代码片断中的ret-type-pattern),名字模式和参数模式以外,所有的部分都是可选的。 返回类型模式决定了方法的返回类型必须依次匹配一个连接点。 你会使用的最频繁的返回类型模式是 ,它代表了匹配任意的返回类型。 一个全称限定的类型名将只会匹配返回给定类型的方法。名字模式匹配的是方法名。 你可以使用 通配符作为所有或者部分命名模式。 参数模式稍微有点复杂:()匹配了一个不接受任何参数的方法, 而 (..)匹配了一个接受任意数量参数的方法(零或者更多)。 模式 ()匹配了一个接受一个任何类型的参数的方法。 模式 (,String)匹配了一个接受两个参数的方法,第一个可以是任意类型,第二个则必须是String类型。 请参见AspectJ编程指南的 Language Semantics部分。
下面给出一些常见切入点表达式的例子。
任意公共方法的执行:execution(public * *(..))
任何一个以“set”开始的方法的执行:execution(* set*(..))
AccountService接口的任意方法的执行:execution(* com.xyz.service.AccountService.*(..))
定义在service包里的任意方法的执行:execution(* com.xyz.service..(..))
定义在service包或者子包里的任意方法的执行:execution(* com.xyz.service...(..))
在service包里的任意连接点(在Spring AOP中只是方法执行) :within(com.xyz.service.*)
在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) :within(com.xyz.service..*)
实现了 AccountService接口的代理对象的任意连接点(在Spring AOP中只是方法执行) :this(com.xyz.service.AccountService) ‘this’在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得代理对象可以在通知体内访问到的部分。
实现了 AccountService接口的目标对象的任意连接点(在Spring AOP中只是方法执行) :`target(com.xyz.service.AccountService) ‘target’在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得目标对象可以在通知体内访问到的部分。
任何一个只接受一个参数,且在运行时传入的参数实现了 Serializable接口的连接点 (在Spring AOP中只是方法执行)args(java.io.Serializable)’args’在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得方法参数可以在通知体内访问到的部分。 请注意在例子中给出的切入点不同于 execution( (java.io.Serializable)): args只有在动态运行时候传入参数是可序列化的(Serializable)才匹配,而execution 在传入参数的签名声明的类型实现了 Serializable接口时候匹配。
有一个 @Transactional注解的目标对象中的任意连接点(在Spring AOP中只是方法执行)
@target(org.springframework.transaction.annotation.Transactional)
‘@target’ 也可以在binding form中使用:请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。
任何一个目标对象声明的类型有一个 @Transactional注解的连接点(在Spring AOP中只是方法执行)
@within(org.springframework.transaction.annotation.Transactional)
‘@within’也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。
任何一个执行的方法有一个 @Transactional annotation的连接点(在Spring AOP中只是方法执行) @annotation(org.springframework.transaction.annotation.Transactional)
‘@annotation’ 也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。
任何一个接受一个参数,并且传入的参数在运行时的类型实现了 @Classified annotation的连接点(在Spring AOP中只是方法执行)
@args(com.xyz.security.Classified)
‘@args’也可以在binding form中使用:- 请常见以下讨论通知的章节中关于如何使得annotation对象可以在通知体内访问到的部分。