代理模式定义: 为其他对象提供了一种代理以控制对这个对象的访问
代理模式的三种角色:
Subject 抽象主题角色: 抽象主题类可以是抽象类也可以是接口, 是一个最普通的业务类型定义, 无特殊要求
RealSubject 具体主题角色: 也叫做被委托角色被代理角色它才是冤大头, 是业务逻辑的具体执行者, Subject 接口的实现
Proxy 代理主题角色: 也叫做委托类代理类它负责对真实角色的应用, 把所有抽象主题类定义的方法限制委托给真实主题角色实现, 并且在真实主题角色处理完毕前做预处理和善后工作
一句话描述静态代理和动态代理:
静态代理: 一个主题类与一个代理类一一对应
动态代理: 多个主题类对应一个代理类
静态代理的例子:
Subject 接口:
- package com.design.one;
- public interface Subject {
- void doSomething();
- }
RealSubject 类:
- package com.design.one;
- public class RealSubject implements Subject{
- @Override
- public void doSomething() {
- System.out.println("doSomething()......");
- }
- }
Proxy 类:
- package com.design.one;
- public class Proxy implements Subject{
- Subject subject = null;
- public Proxy(Subject subject) {
- this.subject = subject;
- }
- @Override
- public void doSomething() {
- System.out.println("之前");
- subject.doSomething();
- System.out.println("之后");
- }
- }
Client 类:
- package com.design.one;
- public class Client {
- public static void main(String[] args) {
- Subject sub = new RealSubject();
- Proxy proxy = new Proxy(sub);
- proxy.doSomething();
- }
- }
输出结果:
之前
doSomething()......
之后
动态代理的例子:
引子: 一般来说, 使用静态代理, 都需要每一个 RealSubject 编写一一对应的代理类, 这些类在编译期间就已经确定了的, 如果有多个 RealSubject 类, 但是他们的代理类里面的前处理 (之前) 和后处理 (之后) 是一样的, 那么使用静态代理模式为多个 RealSubject 类编写相同的处理逻辑的代理类就显得臃肿了和多余了而动态代理不同, 它能使多个 RealSubject 类对应一个代理类, 共享前处理, 后处理功能, 动态调用所需主题, 大大减小了程序规模
Subject 类:
- package com.design.three;
- public interface Subject {
- void doSomething();
- void doSomething1();
- }
Subject2 类:
- package com.design.three;
- public interface Subject2 {
- void doSomething3();
- void doSomething4();
- }
RealSubject 类:
- package com.design.three;
- public class RealSubject implements Subject,Subject2{
- @Override
- public void doSomething() {
- System.out.println("doSomething()......");
- }
- @Override
- public void doSomething1() {
- System.out.println("doSomething()1......");
- }
- @Override
- public void doSomething3() {
- System.out.println("doSomething()3......");
- }
- @Override
- public void doSomething4() {
- System.out.println("doSomething()4......");
- }
- }
RealSubject2 类:
- package com.design.three;
- public class RealSubject2 implements Subject,Subject2{
- @Override
- public void doSomething() {
- System.out.println("Subject2doSomething()......");
- }
- @Override
- public void doSomething1() {
- System.out.println("Subject2doSomething()1......");
- }
- @Override
- public void doSomething3() {
- System.out.println("Subject2doSomething()3......");
- }
- @Override
- public void doSomething4() {
- System.out.println("Subject2doSomething()4......");
- }
- }
MyInvocationHandler 类:
- package com.design.three;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- public class MyInvocationHandler implements InvocationHandler{
- private Object obj = null;
- public MyInvocationHandler(Object obj) {
- this.obj = obj;
- }
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- System.out.println("方法前....");
- return method.invoke(obj, args);
- }
- }
Client 类:
- package com.design.three;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Proxy;
- public class Client {
- public static void main(String[] args) {
- Subject sub = new RealSubject();//1
- // Subject sub = new RealSubject2();//2
- InvocationHandler handler = new MyInvocationHandler(sub);
- Subject proxy = (Subject) Proxy.newProxyInstance(sub.getClass()
- .getClassLoader(), sub.getClass().getInterfaces(), handler);
- proxy.doSomething();
- }
- }
输出结果:
方法前....
doSomething()......
把 2 注释打开, 1 注释掉, 输出结果:
方法前....
Subject2doSomething()......
接下来是四篇个人认为比较好的学习动态代理的文章, 具体原理和分析都在下面了, 我就不再累赘了:
Java 帝国之动态代理
动态代理和静态代理到底有什么区别, 好处在哪里?
JDK 动态代理实现原理
Java 设计模式代理模式实现及原理
来源: https://www.cnblogs.com/tongkey/p/8596697.html