代理模式
代理 (Proxy) 是一种设计模式, 提供了对目标对象另外的访问方式; 即通过代理对象访问目标对象. 这样做的好处是: 可以在目标对象实现的基础上, 增强额外的功能操作, 即扩展目标对象的功能.
这里使用到编程中的一个思想: 不要随意去修改别人已经写好的代码或者方法, 如果需改修改, 可以通过代理的方式来扩展该方法.
举个例子来说明代理的作用: 假设我们想邀请一位明星, 那么并不是直接连接明星, 而是联系明星的经纪人, 来达到同样的目的. 明星就是一个目标对象, 他只要负责活动中的节目, 而其他琐碎的事情就交给他的代理人 (经纪人) 来解决. 这就是代理思想在现实中的一个例子.
代理模式的 关键点是: 代理对象与目标对象. 代理对象是对目标对象的扩展, 并会调用目标对象 .
静态代理
静态代理在使用时, 需要定义接口或者父类, 被代理对象与代理对象一起实现相同的接口或者是继承相同父类.
实例说明:
模拟保存动作, 定义一个保存动作的接口: IUserDao.java, 然后目标对象实现这个接口的方法 UserDao.java, 此时如果使用静态代理方式, 就需要在代理对象 (UserDaoProxy.java) 中也实现 IUserDao 接口. 调用的时候通过调用代理对象的方法来调用目标对象.
需要 注意 的是, 代理对象与目标对象要实现相同的接口, 然后通过调用相同的方法来调用目标对象的方法.
接口: IUserDao.java
- package net.ydstudio.service;
- /**
- * @author Nick
- * @projectName javaLean
- * @package net.ydstudio.service
- * @createDate 2018/08/16 15:35
- * @updateDate 2018/08/16 15:35
- */
- public interface IUserDao {
- /**
- * 保存数据库
- * @param: []
- * @return: void
- */
- void save();
- }
目标对象: UserDao.java
- package net.ydstudio.service.impl;
- import net.ydstudio.service.IUserDao;
- /**
- * @author Nick
- * @projectName javaLean
- * @package net.ydstudio.service.impl
- * @createDate 2018/08/16 15:36
- * @updateDate 2018/08/16 15:36
- */
- public class UserDao implements IUserDao {
- /**
- * 保存数据库
- *
- * @param: []
- * @return: void
- */
- public void save() {
- System.out.println("数据已经保存到数据库");
- }
- }
代理对象: UserDaoProxy.java
- package net.ydstudio.staticproxy;
- import net.ydstudio.service.IUserDao;
- import net.ydstudio.service.impl.UserDao;
- /**
- * @author Nick
- * @projectName javaLean
- * @package net.ydstudio.staticproxy
- * @createDate 2018/08/16 15:37
- * @updateDate 2018/08/16 15:37
- */
- public class UserDaoProxy implements IUserDao {
- /**
- * 保存被代理的对象
- */
- private UserDao target;
- public UserDaoProxy(UserDao target) {
- this.target = target;
- }
- /**
- * 保存数据库
- *
- * @param: []
- * @return: void
- */
- public void save() {
- System.out.println("开始保存数据......");
- target.save();
- System.out.println("结束保存数据......");
- }
- }
测试类:
- package net.ydstudio.proxy;
- import net.ydstudio.service.IUserDao;
- import net.ydstudio.service.impl.UserDao;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.junit.runners.JUnit4;
- import static org.junit.Assert.*;
- /**
- * @author Nick
- * @projectName javaLean
- * @package net.ydstudio.proxy
- * @createDate 2018/08/16 15:58
- * @updateDate 2018/08/16 15:58
- */
- @RunWith(JUnit4.class)
- public class ProxyFactoryTest {
- @Test
- public void test(){
- // 目标对象
- IUserDao target = new UserDao();
- System.out.println(target.getClass());
- // 给目标对象, 创建代理对象
- IUserDao proxy = (IUserDao)new ProxyFactory(target).getProxyInstance();
- // class $Proxy()内存中动态生成的代理对象
- System.out.println(proxy.getClass());
- // 执行方法 代理对象
- proxy.save();
- }
- }
静态代理总结:
可以在不修改代理目标对象的前提下, 对代理目标的功能进行拓展.
需要实现代理目标对象实现的接口, 一旦代理目标所实现的接口有修改, 目标对象与代理都需要维护.
要解决上面静态代理的缺点, 就必须使用动态代理的方式.
动态代理
动态代理有以下特点:
代理对象, 不需要实现接口
代理对象的生成, 是利用 JDK 的 API, 动态的在内存中构建代理对象(需要我们指定创建代理对象 / 目标对象实现的接口的类型)
动态代理也叫做: JDK 代理, 接口代理
最后更新于 2018-08-16 16:29:31 并被添加java标签, 已有 1 位童鞋阅读过.
来源: http://www.tuicool.com/articles/YzyQVjM