创建拦截类:
@Aspect
public class MyAspect{
/** 执行前拦截 */
@Before("execution(* t.t..service.*Service.*(..))")
public void before(JoinPoint point) throws Throwable {
System.out.println("执行方法:" + point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName());
}
/** 执行后拦截 */
@After("execution(* t.t..service.*Service.*(..))")
public void after(JoinPoint point) throws Throwable {
System.out.println("执行完成:" + point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName());
}
/** 执行前后拦截(环绕) */
@Around("execution(* cn.cydl.dlj..service.*Service.*(..))")
public Object around(ProceedingJoinPoint point) throws Throwable {
System.out.println("执行前...");
// 这里相当于@Before
Object obj = point.proceed();// 调用方法具体执行过程,如果不调用,这原来的方法就不会执行了
// obj问原来的方法返回值,如果不返回obj,则原来的方法即时有return也不会返回任何值
// 这里相当于@After
System.out.println("执行后...");
return obj;
}
}
Spring的AOP是上面代理模式的深入。使用Spring AOP,开发者无需实现业务逻辑对象工厂,无需实现代理工厂,这两个工厂都由Spring容器充当。Spring AOP不仅允许使用XML文件配置目标方法,ProxyHandler也允许使用依赖注入管理,Spring AOP提供了更多灵活的选择。
在下面Spring AOP的示例中,InvocationHandler采用动态配置,需要增加的方法也采用动态配置,一个目标对象可以有多个拦截器(类似于代理模式中的代理处理器)。
下面是原始的目标对象:
//目标对象的接口
public interface Person
{
//该接口声明了两个方法
void info();
void run();
}
下面是原始目标对象的实现类,实现类的代码如下:
//目标对象的实现类,实现类实现Person接口
public class PersonImpl implements Person
{
// 两个成员属性
private String name;
private int age;
// name属性的 setter方法
public void setName(String name) {
this.name = name;
}
// age属性的setter方法
public void setAge(int age) {
this.age = age;
}
// info方法,该方法仅仅在控制台打印一行字符串
public void info() {
System.out.println("我的名字是: " + name + " , 今年年龄为: " + age);
}
// run方法,该方法也在控制台打印一行字符串。
public void run() {
if (age < 45) {
System.out.println("我还年轻,奔跑迅速...");
} else {
System.out.println("我年老体弱,只能慢跑...");
}
}
}
该Person实例将由Spring容器负责产生和管理,name属性和age属性也采用依赖注入管理。
为了充分展示Spring AOP的功能,此处为Person对象创建三个拦截器。第一个拦截器是调用方法前的拦截器,代码如下:
//调用目标方法前的拦截器,拦截器实现MethodBeforeAdvice接口
public class MyBeforeAdvice implements MethodBeforeAdvice
{
//实现MethodBeforeAdvice接口,必须实现before方法,该方法将在目标
//方法调用之前,自动被调用。
public void before(Method m, Object[] args, Object target) throws Throwable
{
System.out.println("方法调用之前...");
System.out.println("下面是方法调用的信息:");
System.out.println("所执行的方法是:" + m);
System.out.println("调用方法的参数是:" + args);
System.out.println("目标对象是:" + target);
}
}
第二个拦截器是方法调用后的拦截器,该拦截器将在方法调用结束后自动被调用,拦截器代码如下:
//调用目标方法后的拦截器,该拦截器实现AfterReturningAdvice接口
public class MyAfterAdvice implements AfterReturningAdvice
{
//实现AfterReturningAdvice接口必须实现afterReturning方法,该方法将在目标方法
//调用结束后,自动被调用。
public void afterReturning(Object returnValue, Method m, Object[] args, Object target)throws Throwable
{
System.out.println("方法调用结束...");
System.out.println("目标方法的返回值是 : " + returnValue);
System.out.println("目标方法是 : " + m);
System.out.println("目标方法的参数是 : " + args);
System.out.println("目标对象是 : " + target);
}
}
第三个拦截器是是Around拦截器,该拦截器既可以在目标方法之前调用,也可以在目标方法调用之后被调用。下面是Around拦截器的代码:
//Around拦截器实现MethodInterceptor接口
public class MyAroundInterceptor implements MethodInterceptor
{
//实现MethodInterceptor接口必须实现invoke方法
public Object invoke(MethodInvocation invocation) throws Throwable
{
//调用目标方法之前执行的动作
System.out.println("调用方法之前: invocation对象:[" + invocation + "]");
//调用目标方法
Object rval = invocation.proceed();
//调用目标方法之后执行的动作
System.out.println("调用结束...");
return rval;
}
}