很多情况当不能直接访问目标对象的时候、或者目标对象的方法不能满足我们的需求时,可以生成目标对象的代理对象,从而达到目的。spring中AOP基于两种代理模式:JDK代理模式(需要目标对象实现接口),cglib代理模式(基于类的代理,无需实现接口)。
第一步:定义一个接口
package com.proxy;
public interface Dog {
public void run();
public void eat();
}
第二步:定义一个实现该接口的类
package com.proxy;
public class Hdog implements Dog {
@Override
public void run() {
System.out.println("哈士奇跑得不快");
}
@Override
public void eat() {
System.out.println("哈士奇喜欢吃家具");
}
}
第三步:定义一个实现InvocationHandler 接口的类,重写其 invoke 方法
package com.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/*
* 实现InvocationHandler 接口
*/
public class DogProxy implements InvocationHandler {
/*
* 要生成代理对象的目标对象
*/
private Object target;
/*
* 这里使用构造器注入目标对象
*/
public DogProxy(Object target) {
this.target = target;
}
public DogProxy() {
}
// 对代理对象方法的改造,
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("调用之前");
Object object = method.invoke(target, args);
System.out.println("调用之后");
return object;
}
}
第四步:……测试
package com.proxy;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
// 实例化一个目标对象的实例
Dog dog = new Hdog();
Dog proxy = (Dog) Test.getProxy(dog);
proxy.eat();
proxy.run();
}
// 获取目标对象的代理对象
public static Object getProxy(Object target) {
DogProxy dogProxy = new DogProxy(target);
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), dogProxy);
}
}
其运行结果如下:
调用之前
哈士奇喜欢吃家具
调用之后
调用之前
哈士奇跑得不快
调用之后