动态代理是代理模式的一种,代理模式是设计模式之一。
1、代理模式
代理(proxy)提供了对目标对象的另一种访问方式。即通过代理对象访问对象。这样做的好处是,可以在目标对象实现的基础上,增加额外的功能操作,即扩展目标对象的功能(是AOP思想的技术实现)。
这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或方法,如果需要修改,可以考虑通过代理扩展改方法。
代理模式分为静态代理和动态代理。
2、代理例子
1)StudentInteface接口类,交钱接口
public interface StudentInteface {
void giveMoney();
}
2)StudentImpl实现类,实现交钱接口
public class StudentImpl implements StudentInteface{
@Override
public void giveMoney() {
System.out.println("交钱了。。。。");
}
}
例子,学生上交班费的的例子。下面分别通过静态代理和动态代理来实现代理交钱。
4)静态代理类JtProxyImpl,代理交钱接口,并做方法增强
public class JtProxyImpl implements StudentInteface{
private StudentImpl impl;
public JtProxyImpl(StudentImpl impl){
this.impl = impl;
}
@Override
public void giveMoney() {
System.out.println("静态代理,交钱之前。。。。");
impl.giveMoney();
}
}
6)动态代理处理类DtProxyHandler
public class DtProxyHandler implements InvocationHandler {
private Object object;
public DtProxyHandler(Object object){
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("动态代理,交钱之前。。。。");
return method.invoke(object, args);
}
}
7) 代理测试
public class MainDemo {
public static void main(String[] args) {
// 静态代理
StudentImpl impl = new StudentImpl();
JtProxyImpl proxy1 = new JtProxyImpl(impl);
proxy1.giveMoney();
System.out.println("*******************************");
// 动态代理
StudentInteface inter = new StudentImpl();
DtProxyHandler dtProxyHandler = new DtProxyHandler(inter);
StudentInteface proxy2 = (StudentInteface) Proxy.newProxyInstance(inter.getClass().getClassLoader(), inter.getClass().getInterfaces(), dtProxyHandler);
proxy2.giveMoney();
}
}
3、总结
动态代理字节码随用随创建,随用随加载。与静态代理的区别也在于此,因为静态代理的字节码是一开始就创建好的,并完成加载。
动态代理的优势在于,可以很方便地对代理类的函数进行统一的处理,而不用像静态代理那样修改每个代理类中的方法,因为所以有被执行代理的方法,都是通过InvocationHandler中的Invoke方法进行调用的。所以我们只需要在Invoke方法中统一出来对方法的增强,据可以对所有被代理的方法进行相同的操纵了。