动态代理是指客户通过代理类来调用其它对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象。
动态代理使用场合:1、调试
2、远程方法调用
代理设计模式的原理:使用一个代理将对象包装起来,然后用代理对象取代原始对象,任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。
在Java语言中Proxy类是专门完成代理的类,是所有动态代理类的父类。通过此类为一个或多个接口动态地生成实现类。Proxy类提供用于创建动态代理类和动态代理对象的静态方法
static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) 创建一个动态代理类所对应的Class对象
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 直接创建一个动态代理对象
使用Proxy生成一个动态代理时,往往并不会凭空产生一个动态代理,这样没有太大的意义。通常都是为指定的目标对象生成动态代理
这种动态代理在AOP中被称为AOP代理,AOP代理可代替目标对象,AOP代理包含了目标对象的全部方法。但AOP代理中的方法与目标对象的方法存在差异:AOP代理里的方法可以在执行目标方法之前、之后插入一些通用处理。
下面用一个小小的Demo来实现下。
interface Human{
void info();
void fly();
}
//被代理类
class SuperMan implements Human{
@Override
public void info() {
System.out.println("我是超人,我怕谁!");
}
@Override
public void fly() {
System.out.println("I believe I can fly!");
}
}
class HumanUtil{
public void method1(){
System.out.println("=======方法一=======");
}
public void method2(){
System.out.println("=======方法二=======");
}
}
class MyInvocationHandler implements InvocationHandler{
Object obj; //被代理对象的声明
//实例化被代理对象
public void setObject(Object obj){
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
HumanUtil h = new HumanUtil();
h.method1();
//实现在method1()和method2()动态插入
Object returnValue = method.invoke(obj, args);
h.method2();
return returnValue;
}
}
class MyProxy{
//动态的创建一个代理类的对象
public static Object getProxyInstance(Object obj){
MyInvocationHandler handler = new MyInvocationHandler();
handler.setObject(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), handler);
}
}
public class TestAOP {
public static void main(String[] args) {
SuperMan superMan = new SuperMan();
Object obj = MyProxy.getProxyInstance(superMan);
Human human = (Human) obj;
human.info();
System.out.println();
human.fly();
}
}