委派模式与模板模式(2)

简介: 委派模式与模板模式(2)

三、委派模式在源码中的体现


JDK 中有一个典型的委派 ,众所周知 JVM 在加载类是用的双亲委派模型 ,这又是什么呢?—类加载器在加载类时 , 先把这个请求委派给自己的父类加载器去执行 ,如果父类加载器还存在父类加载器 ,就继续向上委派,直到顶层的启动类加载器。如果父类加载器能够完成类加载,就成功返回,如果父类加载器无法完成加载,那么子加载器才会尝试自己去加载。从定义中可以看到双亲加载模型一个类加载

器加载类时 , 首先不是自己加载 ,而是委派给父加载器。下面我们来看看 loadClass()方法的源码 ,此方法在 Classloader 中。在这个类里就定义了一个双亲,用于下面的类加载。


public abstract class ClassLoader {
    private final ClassLoader parent;
    protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }
                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);
                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }
}


常用代理执行方法 invoke

同样在反射里的 Method 类里我们常用代理执行方法 invoke也存在类似的机制。


public final class Method extends Executable {
    @CallerSensitive
    public Object invoke(Object obj, Object... args)
        throws IllegalAccessException, IllegalArgumentException,
           InvocationTargetException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        MethodAccessor ma = methodAccessor;             // read volatile
        if (ma == null) {
            ma = acquireMethodAccessor();
        }
        return ma.invoke(obj, args);
    }
}


看完代码 , 相信小伙伴们对委派和代理区别搞清楚了吧。


Spring loC中 在调用 doRegisterBeanDefinitions()


下面来看一下委派模式在Spring 中的应用在Spring loC中 在调用 doRegisterBeanDefinitions()


方法时即 BeanDefinition进行注册的过程中,会设置 BeanDefinitionParserDelegate类型的 Delegate对象传给 this.delegate 并将这个对象作为一个参数传给 :parseBeanDefinitions(root, this.delegate)


中 ,然后主要的解析的工作就是通过 delegate作为主要角色来完成的, 可以看到下方代码 :


public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
    // 判断节点是否属于同一令名空间 , 是则执行后续的解析 
    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    if (delegate.isDefaultNamespace(root)) {
      NodeList nl = root.getChildNodes();
      for (int i = 0; i < nl.getLength(); i++) {
        Node node = nl.item(i);
        if (node instanceof Element) {
          Element ele = (Element) node;
          if (delegate.isDefaultNamespace(ele)) {
            parseDefaultElement(ele, delegate);
          }
          else {
                        //注解定义的 context 的 namespace 进入到这个分支中
            delegate.parseCustomElement(ele);
          }
        }
      }
    }
    else {
      delegate.parseCustomElement(root);
    }
  }
}   


其中最终能够走到 bean 注册部分的是 ,会进入到 parseDefault Element(ele, delegate)中,然后


针对不同的节点类型针对 bean 的节点进行真正的主册操作而在这个过程中,delegate 会对element


进行 parseBeanDefinitionElement , 得到了一个 BeanDefinitionHolder 类型的对象,之后通过这个


对象完成真正的注册到 Factory 的操作。


SpringMVC 的 DispatcherServlet

下面我们再来还原一下 SpringMVC 的 DispatcherServlet 是如何实现委派模式的。创建业务类


MemberController :


public class MemberController {
    public void getMemberById(String mid) {
    }
}


目录
相关文章
|
3月前
|
设计模式 Java
常用设计模式(工厂方法,抽象工厂,责任链,装饰器模式)
有关设计模式的其他常用模式请参考 单例模式的实现 常见的设计模式(模板与方法,观察者模式,策略模式)
39 2
|
6月前
|
设计模式 算法 Java
JAVA设计模式13:模版方法模式,将一些步骤延迟到子类中实现
JAVA设计模式13:模版方法模式,将一些步骤延迟到子类中实现
|
8月前
|
设计模式 前端开发 Java
你以为委派模式很神秘,其实你每天都在用
我们用代码来模拟老板给员工分配任务的业务场景。
56 0
|
9月前
|
设计模式 程序员 编译器
【大话设计模式】封装 继承 多态
【大话设计模式】封装 继承 多态
|
前端开发 Java
简述ClassLoader双亲委派模式
简述ClassLoader双亲委派模式
95 0
|
设计模式 Java Spring
Java设计模式 ->委派模式
Java设计模式 ->委派模式
80 0
|
算法 Java 调度
Delegate 委派模式和代理模式strategy的区别?策略模式如何实现消除多层if else?(下)
Delegate 委派模式和代理模式strategy的区别?策略模式如何实现消除多层if else?(下)
107 0
Delegate 委派模式和代理模式strategy的区别?策略模式如何实现消除多层if else?(下)
|
算法 前端开发 Java
Delegate 委派模式和代理模式strategy的区别?策略模式如何实现消除多层if else?(上)
Delegate 委派模式和代理模式strategy的区别?策略模式如何实现消除多层if else?
187 0
Delegate 委派模式和代理模式strategy的区别?策略模式如何实现消除多层if else?(上)
|
SQL Java 数据库连接
委派模式与模板模式(5)
委派模式与模板模式(5)
106 0
委派模式与模板模式(5)
|
Java 数据库连接 数据库
委派模式与模板模式(4)
委派模式与模板模式(4)
107 0