1 spring核心AOP
spring aop 实现方式,网上看到大神的示例,非常的清晰,链接如下,总共4篇:
http://tonl.iteye.com/blog/1965740
spring AOP 获得代理方式有两种 JDK动态代理,CGLib生成代理
1. 关于JDK动态代理核心
JDK动态代理核心就是InvocationHandler接口
动态代理一般使用Proxy类来实现,代理类要实现InvocationHandler接口,并复写他的invoke方法,再由Proxy.newProxyInstance方法来获得代理类的实例
package proxyofdynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 本例实现的是动态代理的模式
* @author fun
*
*/
public class RunTest implements InvocationHandler {
Object any_object;
//申明bind方法,返回代理对象
public Object bind(Object any_object){
this.any_object = any_object;
return Proxy.newProxyInstance(any_object.getClass().getClassLoader(), any_object.getClass().getInterfaces(), this);
}
//自己的业务逻辑,被代理方法前的处理
public void methodbefore(){
System.out.println("start to print");
}
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
Object obj_return = null;
this.methodbefore();
obj_return = arg1.invoke(any_object, arg2);
System.out.println("end of print");
return obj_return;
}
public static void main(String[] args) {
RunTest run = new RunTest();
hello_interface hello = (hello_interface)run.bind(new hello_interface_impl());
hello.sayHello();
}
}
核心就是利用invoke方法回调,在回调前后处理自己切入的业务。上面的简单示例测试了在执行接口hello_interface的sayHello方法前调用自定义的逻辑methedbefore.当然也可以获得方法参数。从invoke的方法参数中获得。
2 spring基于aspectJ完成aop
使用aspectj的方式完成aop的时候更加方便快捷,使用中有两种方式,xml配置或者annotation 方式。简单给个annotation的示例。
package com.fun.spring;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* aspectJ 实现的AOP
* Created by fun
*
* @date 2017/5/5.
*/
@Aspect
@Component
public class TestAOP {
// 定义pointcut,然后再@before ,@after @Around 中使用。或者直接在这些
// 注解中直接定义execution
@Pointcut("execution(* com.fun.spring.TestBean.testMethod())")
public void before() {
}
@Pointcut("execution(* com.fun.spring.TestBean.testMethod())")
public void after() {
}
// @Pointcut("execution(* com.fun.spring.TestBean.testMethod())")
// public void around() {
// }
@Before("before() ")
public void beforeMethod(JoinPoint pjp) throws Throwable {
System.out.println("before method....");
}
@After("after() ")
public void afterMethod(JoinPoint pjp) throws Throwable {
System.out.println("after method....");
}
@Around("execution(* com.fun.spring.TestBean.testMethod())")
public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
Object[] obj = pjp.getArgs();
System.out.println("before proceed");
// around 和 before after的最大区别在于,around可以控制方法是否执行
Object result = pjp.proceed(obj);
System.out.println("after proceed");
return null;
}
}
随便一个bean,使用@Aspect 注解即可。但是要在spring的配置加上<aop:aspectj-autoproxy/>
才行。
上面示例中有一点值得注意的地方就是,@Around里面主动调用了pjp.proceed(obj).所以他可以控制切面里面的方法是否执行。例如在执行前校验,如果不满足条件,不执行次方法。而@before 和 @after 没有这种特性。