Spring的兩大特性就是IOC和AOP(Aspect Orient Programming),AOP一般稱爲面向切面編程,主要用於事務、日誌等方面。AOP代理分爲靜態代理和動態代理,靜態代理一般是AspectJ AOP(編譯時),動態代理則爲Spring AOP(運行時)中的cglib和jdk兩種。
jdk動態代理
jdk動態代理的核心是InvocationHandler接口和Proxy類,使用jdk動態代理的前提是被代理的類必須實現一個接口。
定義一個接口
package proxy;
/**
* jdk代理演示接口類
* @author : vi3nty
* @date : 16:20 2020/4/20
*/
public interface Person {
String sayHello(String name);
}
實現類
package proxy;
/**
* jdk動態代理實現類
* @author : vi3nty
* @date : 16:20 2020/4/20
*/
public class Chinese implements Person{
@Override
public String sayHello(String name) {
return name+" hello";
}
}
切面類
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 定義切面
* @author : vi3nty
* @date : 16:22 2020/4/20
*/
public class MyInvocationHandler implements InvocationHandler {
private Object object;
public MyInvocationHandler(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
Object invoke=method.invoke(object,args);
System.out.println("after");
return invoke;
}
}
測試類
package proxy;
import java.lang.reflect.Proxy;
/**
* @author : vi3nty
* @date : 16:42 2020/4/20
*/
public class ProxyJDKTest {
public static void main(String[] args) {
Chinese chinese=new Chinese();
MyInvocationHandler handler=new MyInvocationHandler(chinese);
Person personInstance= (Person) Proxy.newProxyInstance(
chinese.getClass().getClassLoader(),
chinese.getClass().getInterfaces(),
handler);
personInstance.sayHello("jdk");
}
}
輸出
before
jdkhello
after
Process finished with exit code 0
cglib動態代理
如果沒有實現接口的話那就需要用cglib動態代理,代理類需實現MethodInterceptor接口。
代碼實現
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* cglib測試
* @author : vi3nty
* @date : 16:56 2020/4/20
*/
public class MyCglib {
public static void main(String[] args) {
CglibProxy proxy=new CglibProxy();
Dog dog= (Dog) proxy.getInstance(new Dog());
dog.eat();
}
}
class Dog{
public void eat(){
System.out.println("dog is eating");
}
}
class CglibProxy implements MethodInterceptor{
private Object target; // 代理對象
public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
// 設置父類爲實例類
enhancer.setSuperclass(this.target.getClass());
// 回調方法
enhancer.setCallback(this);
// 創建代理對象
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("調用前");
Object result = methodProxy.invokeSuper(o, objects); // 執行方法調用
System.out.println("調用後");
return result;
}
}
輸出結果
調用前
dog is eating
調用後
Process finished with exit code 0