---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------
组成----静态代理和动态代理都有2个角色 真实和代理 都实现一个公共接口 并有个测试类调用代理类
应用环境----你不知道真实类你只知道代理类 但你要实现真实的角色的功能 通过代理帮你完成
就像找房子你不能联系到房主但中介能 你就只能通过中介租房子
中介就相当于代理类 房主就是真实角色 而你就是测试类
静态代理
* 静态代理怎么回事
* 1.有个接口 真实角色和代理角色都要实现(测试类保存的是接口 这样便可通过更改属性文件得到不同的类
* 已达到解耦作用)
* 2.代理角色就是有真实角色的引用 你不知道真实角色 只知道代理角色
* 代理角色既能完成代理又能完成本身的一些别的操作
如果一个功能就要一个代理 那么100功能100代理 ,太坑了 ,所以出来了动态代理, 一个动态代理代替所有代理类
动态代理
那么动态代理与静态代理的区别在哪
1.静态代理 如果想达到代理功能只要在代理类中调用真实角色就行,也就是代理类是完整的有真实的角色的引用
2.动态代理 他的代理类要继承invocationhandler 接口 他是不完整的 也就是没有真实角色的引用而是保存一个object
那么他是怎么实现代理功能的呢
我感觉有点像懒加载似的 就是当你要用时才生成完整的代理类
静态代理 测试类中生成代理类的实例 并调用
动态代理 在测试类中则需要先生成代理类 因为你的代理类还不完整
RealSubject subject = new RealSubject(); //真实角色
InvocationHandler ih = new ProxySubject(subject); //将真实角色 传进代理类中
Class<?> clazz = subject.getClass(); //真实角色的class对象
s = Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), ih); 这段才是生成了完整的代理类实例 返回的是代理类
其实就是利用反射生成一个新的完整的代理类 并赋给s 这样s.requst(); 这样调用真实角色的request()方法
这样就实现动态代理的功能 你可以更换不同的真实角色 都使用一个(不完整的代理类)实现InvocationHandler接口的类
动态生成一个完整的动态代理类 这样你就可以调用真实角色了
动态代理代码
1.接口(真实角色与代理角色都要实现)
public interface Subject {
public void request();
}
2.真实角色
public class ProxySubject implements InvocationHandler
{
private Object object;
public ProxySubject(Object object)
{
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("pre processing");
method.invoke(object, args);
System.out.println("post processing");
return null;
}
}
3.代理角色
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
System.out.println("pre processing");
method.invoke(object, args);
System.out.println("post processing");
return null;
}
}
4.测试类
public class Client
{
public static void main(String[] args)
{
RealSubject subject = new RealSubject();
InvocationHandler ih = new ProxySubject(subject);
Class<?> clazz = subject.getClass();
Subject s = (Subject) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), ih);
s.request();
}
}
总结: 动态代理与静态代理的区别
1.静态代理是在(调用前)就已经有了完整的代理类
2.动态代理是在你(调用时)才动态生成完整的代理类
如果你不动态生成 就调用不了代理类的方法
相同的地方是 最终都是通过代理调用真实对象的方法
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------