博客
关于我
代理模式(结构性模式)
阅读量: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/

你可能感兴趣的文章
洛谷 1115 最大子段和、HDU 1003 Max Sum(最大字段和问题)
查看>>
BugkuCTF web_1-10
查看>>
CSS_简介、选择器、属性和属性值、盒子模型
查看>>
POJ 1985 Cow Marathon(树的直径)
查看>>
POJ 2387 Til the Cows Come Home(Dijkstra优先队列)
查看>>
零基础入门JavaScript 这一篇笔记就够了
查看>>
MySQL_属性、记录长度、设计范式、表关系
查看>>
MySQL_安全管理、表单传值、php操作
查看>>
POJ 2299 Ultra-QuickSort(树状数组+离散化+求逆序数)
查看>>
POJ 3468 A Simple Problem with Integers(线段树+区间更新)
查看>>
BugkuCTF web_31-40
查看>>
BUUCTF web WarmUp
查看>>
hcnp笔记
查看>>
第一天 Requests库入门
查看>>
第3章 衡量线性回归的指标:MSE,RMSE,MAE
查看>>
第四节 用户分析
查看>>
python数据分析
查看>>
MySQL(四)数据库结构设计
查看>>
Vue(六)Vue中的计算属性和侦听器
查看>>
springmvc(1)架构执行流程
查看>>