代理模式(Proxy)
属于结构型模式
Proxy-代理模式是指为其他对象提供一种代理,来控制对这个对象的访问
即对A对象进行代理后, 本来A对象的功能交给代理B来做; 代理就是原实例前后添加一层处理.
为什么使用代理模式
- 授权机制: 不同级别的用户对于同一对象的访问权限是不同的, 要用代理实现对不同用户的访问权限的控制
- 某个客户端不能直接操作一个对象, 但又要和那个对象互动, 也要通过代理实现间接互动
- 代理类为委托类预处理消息,过滤消息,把消息传递给委托类, 以及事后对返回结果的处理等.
3种代理模式
1. 静态代理
实现步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public interface UserService{ void login(); }
public class UserServiceImpl implements UserService{ @Override public void login(){ System.out.println("登录"); } }
public class UserServiceProxy implements UserService{ private UserService userService;
public UserService(final UserService userService){ this.userService=userService; }
@Override public void login(){ System.out.println("准备登录"); userService.login(); System.out.println("登录完成"); } }
public class ProxyTest{ public static void main(String[] args){ UserService userService=new UserServiceImpl(); UserServiceProxy userServiceProxy=new UserServiceProxy(userService); userServiceProxy.login(); } }
|
静态代理可以做到符合开闭原则的对目标对象进行功能扩展, 但是工作量大, 要给每个对象创建代理类, 而且不易管理, 接口发生改变, 代理类也要改变
2. JDK动态代理
动态代理中, 不需要手动创建代理类了, 只要编写一个动态处理器就OK了
实现步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class DynamicProxyHandler implements InvocationHandler{ private Object object;
public DynamicProxyHandler(final Object object){ this.object=object; }
@Override public Object invoke(Object proxy,Method method,Object[] agrs)throws Throwable{ System.out.println("准备"); Object result=method.invoke(Object,args); System.out.println("完成"); return result; } }
public class DynamicProxyTest{ public static void main(String[] args){ UserService userService=new UserServiceImpl(); UserService userServiceProxy=(UserService)Proxy.newProxyInstnce(UserService.class.getClassLoader(),new Class[]{UserService.class},new DynamicProxyHandler(userService)); userServiceProxy.login(); } }
|
3. CGLIB代理
JDK实现动态代理需要实现类通过接口定义业务的方法, 对于没有接口的类就不能实现代理.这就需要CGLIB了
实现步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class CglibProxy implements MethodInterceptor{ private Object target; public Object getInstance(final Object target){ this.target=target; Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(This.target.getClass()); enhancer.setCallback(this); return enhancer.create(); }
public Object intercept(Object object, Method method, Object[] args,MeyhodProxy methodProxy)throws Throwable{ System.out.println("准备"); Object result=method.invoke(object,args); System.out.println("结束"); return result } }
public class CglibDynamicProxyTest{ public static void main(String[] args){ UserService userService=new UserServiceImpl(); CglibProxy cglibProxy=new CglibProxy(); UserService userServiceProxy=(UserService)cglibProxy.getInstance(userService1;) userServiceProxy.login(); } }
|
CGLIB代理比JDK代理的性能更高,但是CGLIB比JDK创建代理的耗时要更高,所以单例对象CGLIB更合适, 反之JDK更合适.

Anything can go right will go right