博客
关于我
代理模式(结构性模式)
阅读量:155 次
发布时间:2019-02-28

本文共 4439 字,大约阅读时间需要 14 分钟。

Proxy Pattern: Provide a surrogate or placeholder for another object to control access to it.

代理模式:给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。

代理模式结构图

在这里插入图片描述

1.静态代理

静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类.

package Static;public interface UserDao {       void save();}
package Static;public class UserDaoImpl implements UserDao {       @Override    public void save() {           System.out.println("----已经保存数据!----");    }}
package Static;public class UserDaoProxy implements UserDao{       //接收保存目标对象    private UserDao target;    public UserDaoProxy(UserDao target){           this.target=target;    }    public void save() {           System.out.println("开始事务...");        target.save();//执行目标对象的方法        System.out.println("提交事务...");    }}
package Static;public class TestMain {       public static void main(String[] args) {           //目标对象        UserDao userDao=new UserDaoImpl();        UserDaoProxy userDaoProx=new UserDaoProxy(userDao);        userDaoProx.save();    }}

缺点:

因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.

2.动态代理

1

package Static;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/** * 创建动态代理对象 * 动态代理不需要实现接口,但是需要指定接口类型 */public class ProxyFactory {       //维护一个目标对象    private Object target;    public ProxyFactory(Object target){           this.target=target;    }    //给目标对象生成代理对象    public Object getProxyInstance(){           return Proxy.newProxyInstance(                target.getClass().getClassLoader(),                target.getClass().getInterfaces(),                new InvocationHandler() {                       @Override                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                           System.out.println("开始事务2");                        //执行目标对象方法                        Object returnValue = method.invoke(target, args);                        System.out.println("提交事务2");                        return returnValue;                    }                }        );    }}
package Static;public class App {       public static void main(String[] args) {           // 目标对象        UserDao target=new UserDaoImpl();        // 【原始的类型 class Static.UserDaoImpl】        System.out.println(target.getClass());        // 给目标对象,创建代理对象        UserDao proxy = (UserDao) new ProxyFactory(target).getProxyInstance();        // class com.sun.proxy.$Proxy0  内存中动态生成的代理对象        System.out.println(proxy.getClass());        // 执行方法   【代理对象】        proxy.save();    }}

2.Cglib代理

上面的静态代理和动态代理模式都是要求目标对象是实现一个接口的目标对象,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候就可以使用以目标对象子类的方式类实现代理,这种方法就叫做:Cglib代理

在Spring的AOP编程中:

如果加入容器的目标对象有实现接口,用JDK代理
如果目标对象没有实现接口,用Cglib代理

package Cglib;public class UserDao {       public void save() {           System.out.println("----已经保存数据!----");    }}
package Cglib;import org.springframework.cglib.proxy.Enhancer;import org.springframework.cglib.proxy.MethodInterceptor;import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;/** * Cglib子类代理工厂 * 对UserDao在内存中动态构建一个子类对象 *///1.需要引入cglib的jar文件,但是Spring的核心包中已经包括了Cglib功能,// 所以直接引入spring-core-3.2.5.jar即可.public class ProxyFactory implements MethodInterceptor {       //维护目标对象    private Object target;    public ProxyFactory(Object target) {           this.target = target;    }    //给目标对象创建一个代理对象    public Object getProxyInstance(){           //1.工具类        Enhancer en = new Enhancer();        //2.设置父类        en.setSuperclass(target.getClass());        //3.设置回调函数        en.setCallback(this);        //4.创建子类(代理对象)        return en.create();    }    @Override    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {           System.out.println("开始事务...");        //执行目标对象的方法        Object returnValue = method.invoke(target, args);        System.out.println("提交事务...");        return returnValue;    }}
package Cglib;import Static.ProxyFactory;import Static.UserDao;import Static.UserDaoImpl;public class App {       public static void main(String[] args) {           // 目标对象        Static.UserDao target=new UserDaoImpl();        // 【原始的类型 class Static.UserDaoImpl】        System.out.println(target.getClass());        //代理对象        UserDao proxy = (UserDao)new ProxyFactory(target).getProxyInstance(); // class com.sun.proxy.$Proxy0  内存中动态生成的代理对象        System.out.println(proxy.getClass());        // 执行方法   【代理对象】        proxy.save();    }}

转载地址:http://pwrd.baihongyu.com/

你可能感兴趣的文章
H5页面授权获取微信授权(openId,微信nickname等信息)
查看>>
2018年年终总结
查看>>
【redis键过期删除策略】很高兴再次认识你
查看>>
【工具篇】EasyExcel的应用
查看>>
监控264后缀文件播放
查看>>
2019数字音乐市场年度回顾,QQ音乐全面领先
查看>>
花1亿扶持优质红人,如涵推动网红经济出圈之路有何深意?
查看>>
理解PendingIntent
查看>>
Android SurfaceFlinger4 提交Buffer
查看>>
深入理解 ClientLifecycleManager 机制
查看>>
js try{}catch(){}finally{}语句
查看>>
PAT (Basic Level) Practice (中文)——1005 继续(3n+1)猜想 (25分)
查看>>
PAT (Basic Level) Practice (中文)——1011 A+B 和 C (15分)
查看>>
R3 PRO 3200G和r7 3700u 哪个好
查看>>
入手评测 联想小新Pro14和Air14Plus哪个好?区别对比
查看>>
修复苹果Mac中的快速视频播放错误的方法
查看>>
Mac系统投屏到电视机的方法
查看>>
【Docker&ARM】ARM架构服务器上docker的安装
查看>>
php--自定义错误处理函数的使用方法
查看>>
php--异常处理主动抛出异常的使用方法
查看>>