结构型设计模式之代理模式

Posted 丨Jack_Chen丨

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结构型设计模式之代理模式相关的知识,希望对你有一定的参考价值。

@TOC

代理模式

分类

1.静态代理:静态定义代理类

2.动态代理:动态生成代理类

主要角色

代理模式一般包含三种角色:

1.抽象主题角色(Subject)

2.真实主题角色(RealSubject)

3.代理主题角色(Proxy)

作用

1.保护目标对象,将代理对象与真实被调用目标对象分离

2.增强目标对象

3.降低系统耦合性,提升扩展性

静态代理与动态代理的区别

静态代理的基本使用

买票前的操作
进行买票操作
买票后的操作

JDK动态代理的基本使用

创建抽象主题

public interface IUser 
    /**
     * 购物
     */
    void shopping();

创建真实主题

public class User implements IUser
    @Override
    public void shopping() 
        System.out.println("user shopping....");
    

创建代理主题

public class JDKProxy implements InvocationHandler 

    private Object tarjet;

    public JDKProxy(Object tarjet) 
        this.tarjet = tarjet;
    

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
        System.out.println("代理user,执行shopping()开始...");
        Object oj = method.invoke(tarjet, args);
        System.out.println("代理user,执行shopping()结束...");
        return oj;
    

客户端调用

    public static void main(String[] args) 
        User user = new User();
        JDKProxy jdkProxy = new JDKProxy(user);
        IUser proxyInstance = (IUser) Proxy.newProxyInstance(user.getClass().getClassLoader(), user.getClass().getInterfaces(), jdkProxy);
        proxyInstance.shopping();
    
代理user,执行shopping()开始...
user shopping....
代理user,执行shopping()结束...

小优化

在调用时候,传入了一推参数,可进一步优化

public class JDKProxy implements InvocationHandler 

    private Object tarjet;

    public Object JDKProxy(Object target)
        this.tarjet = target;
        Class<?> clazz =  target.getClass();
        return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
    

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
        System.out.println("代理user,执行shopping()开始...");
        Object oj = method.invoke(tarjet, args);
        System.out.println("代理user,执行shopping()结束...");
        return oj;
    
    public static void main(String[] args) 
        JDKProxy jdkProxy = new JDKProxy();
        IUser user= (IUser)jdkProxy.JDKProxy(new User());
        user.shopping();
    

CGLIB动态代理的基本使用

注意:CGLib不能代理final的方法

创建抽象主题

注意:CGLb代理的目标对象不需要实现任何接口,就可以通过动态继承目标对象实现动态代理。所以此处可以不用创建接口。直接使用真实主题。

public interface IUser 
    public void shopping();

创建真实主题

public class User implements IUser
    @Override
    public void shopping() 
        System.out.println("user shopping....");
    

直接使用真实主题。

public class User 
    public void shopping() 
        System.out.println("user shopping....");
    

创建代理主题

public class CglibProxy implements MethodInterceptor 
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable 
        System.out.println("代理user,执行shopping()开始...");
        Object invokeSuper = methodProxy.invokeSuper(o, objects);
        System.out.println("代理user,执行shopping()结束...");
        return invokeSuper;
    

客户端调用

    public static void main(String[] args) 
        CglibProxy cglibProxy = new CglibProxy();
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(User.class);
        enhancer.setCallback(cglibProxy);
        IUser iUser = (IUser) enhancer.create();
        iUser.shopping();
    

小优化

在客户端调用时,稍显复杂,可进一步优化

public class CglibProxy implements MethodInterceptor 

    public Object getInstance(Class<?> clazz) throws Exception
        //相当于Proxy,代理工具类
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable 
        System.out.println("代理user,执行shopping()开始...");
        Object invokeSuper = methodProxy.invokeSuper(o, objects);
        System.out.println("代理user,执行shopping()结束...");
        return invokeSuper;
    
    public static void main(String[] args) throws Exception 
        IUser user = (IUser) new CglibProxy().getInstance(User.class);
        user.shopping();
    

CGLIB与JDK动态代理区别

1.执行条件

2.实现机制

3.性能

以上是关于结构型设计模式之代理模式的主要内容,如果未能解决你的问题,请参考以下文章

结构型设计模式之代理模式

javaweb 之 代理模式

设计模式之代理模式

揭秘设计模式之代理模式

设计模式之代理模式20170724

第六篇 设计模式之代理模式