代理模式
来源:互联网 发布:java数组添加元素 编辑:程序博客网 时间:2024/06/03 19:58
这篇博客只是我个人见解,有不对的地方忘大家指出。
为什么要有代理模式。
代理模式是当客户端不想,或者不能直接访问某个对象的时候,我们为其提供一个代理对象,客户通过这个代理对象来访问委托对象。代理分为静态代理,动态代理。静态代理是代理类在编译器就已经存在,被编译成 .class 文件;动态代理是在运行期的时候通过反射机制来获取委托对象。
静态代理
静态代理中代理类和真实类要实现一样的接口。对于这个,我的理解是,在应用代理的时候,我们通过代理类调用的方法从根本上来说还是真实类的方法,代理类实现了真实类的接口,给客户端的感觉他就是在访问真实类的对象。
静态代理是在编译期就决定了代理对象是哪一个,因此,当有多个委托对象的时候,我们最好要有多个代理对象(这里的最好是因为,只应用一个代理对象也是可以的,但是所有的委托都使用同一个代理,对客户端来说并不友好,就像是每一个经纪人都只对一个演员负责,如果对多个人负责的话容易混乱)。从这里也可以看出静态代理的一个缺点——对于每一个委托对象都要有一个代理,当代理很多的时候,代码的整体结构就会很庞大,很乱。此外,代理和委托类都实现了同样的接口,如果接口中添加了方法,除了委托需要实现这个方法,代理类也要实现,这样代码的维护会很复杂。
一个静态代理的例子:
//interface
public interface MoveService {
void noticeMoveType();
}
//impl
public class MoveServiceImpl implements MoveService {
@Override
public void noticeMoveType() {
System.out.println("today's move is GongFu");
}
}
//proxy 代理类也要实现MoveService接口,在方法中调用真实类的方法
public class ProxyAll implements MoveService {
private MoveService moveService;
public ProxyAll(MoveService moveService){
this.moveService = moveService;
}
@Override
public void noticeMoveType() {
System.out.println("notice move type start");
moveService.noticeMoveType();
System.out.println("notice move type end");
}
}
// client 客户端实现
public class ProxyStart {
public static void main(String[] args){
ProxyAll proxyAll = new ProxyAll(new MoveServiceImpl());
proxyAll.noticeMoveType();
}
}
动态代理:
动态代理是在程序运行的过程中通过反射来得到委托类的对象,然后调用其方法,从这里就可以看出动态代理的好处了:只有一个代理类,我们只要在运行的过程中指定委托就可以了。提高了代码的重用性。
一个动态代理的例子
//UserService
public interface UserService {
void userSaySomething();
}
//UserServiceImpl
public class UserUserServiceImpl implements UserService {
@Override
public void userSaySomething() {
System.out.println("this is real userService");
}
}
//Proxy
public class ProxyAll implements InvocationHandler {
private Object target;
public ProxyAll(Object target){
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("——start——");
Object result = method.invoke(target, args);
System.out.println("——end——");
return result;
}
// 生成代理对象
public Object getProxy() {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class<?>[] interfaces = target.getClass().getInterfaces();
return java.lang.reflect.Proxy.newProxyInstance(loader, interfaces, this);
}
}
//ProxyTest
public class ProxyTest {
public static void main(String[] args) {
UserService userService = new UserUserServiceImpl();
ProxyAll handler = new ProxyAll(userService);
UserService userServiceProxy = (UserService)handler.getProxy();
userServiceProxy.userSaySomething();
}
}
实现动态代理,代理类要实现InvocationHandler中的invoke方法。
/**
*@param proxy 被代理的对象
*@param method 要调用的方法
*@param args 执行方法是需要的参数
*/
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable;
/**
*@param loader 类加载器
*@param interfaces 得到全部的接口
*@param h 得到InvocationHandler接口子类的实例
*@return Object 返回代理的实例
*/
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException
阅读全文
0 0
- 代理模式--动态代理
- 代理模式-静态代理
- 代理模式-静态代理
- 代理模式 & 动态代理
- 代理模式--静态代理
- 代理模式--动态代理
- 代理模式(动态代理)
- 代理模式-动态代理
- 代理模式-动态代理
- 代理模式动态代理
- 代理模式-静态代理
- 代理模式-动态代理
- 代理模式 -动态代理
- 代理模式---动态代理
- 代理模式-动态代理
- 代理模式--静态代理
- 代理模式!
- 代理模式
- 关于查询缓存的一个思考
- java 构建字符串 StringBuilder() 和 append()
- 设计模式之完美单利模式
- Qt quick核心编程学习(一)
- JAVA8新特性[第四季]-强大的Stream API
- 代理模式
- 51NOD-2006 飞行员配对(二分图最大匹配)
- 周末在家配置网络
- Android开发的基础技能总结(1)
- TreeSet类的排序问题
- Java中的堆、栈、方法区深入分析
- HDU-1796 How many integers can you find(容斥原理)
- Java中常用的加密与解密方法
- Unity生成Excel表