责任链模式为请求创建了一个接受者对象的链,使得请求者与接受者解耦,
而且请求者无需关心接受者的具体实现,只需将请求传递给接收者链即可。
下面举一个类加载的例子,类加载采用双亲委派机制,先将类给最上层的BootstrapClassLoader,
如果BootstrapClassLoader可以加载则进行加载,如果不能加载,则传递给下一级的ExtensionClassLoader.进行加载,
如果可以加载则进行加载,反之继续传递给下一级加载器ApplicationClassLoader。
依次类推,直到最后所有类加载器都不能进行加载,则抛出类加载异常。
首先我们创建一个ClassLoader的抽象类,后续的BootstrapClassLoader、ExtensionClassLoader等继承该抽象类
public abstract class ClassLoader { public static int BOOTSTRP = 1; public static int EXTENSION = 2; public static int APPLICATION = 3; protected int priority;//当前类加载器优先级 //下一级加载器 protected ClassLoader nextClassLoader; public void setNextClassLoader(ClassLoader nextClassLoader) { this.nextClassLoader = nextClassLoader; } public void runLoader(String className, int priority) { System.out.println("当前加载器优先级:" + this.priority + "--当前类优先级:" + priority); if(this.priority == priority) {//当前类可以加装则进行加载 loader(className); }else {//当前类加载器无法加载则将当前类传递到下一级加载器 if(nextClassLoader != null) {//如果下一级类加载器存在则传递给下一级,反之抛出异常。 //System.out.println("--" + this.priority + ":" + priority); nextClassLoader.runLoader(className, priority); }else {//当前加载器无法加载,且后续加载器为null则抛出类加载失败 System.out.println("Class Loader Fail"); } } } public abstract void loader(String className); }
该类中有一个priority设置优先级,先将类传递给BootstrapClassLoader,如果类的优先级等于该加载器优先级,则调用loader进行加载。
反之则通过nextClassLoader.runLoader(className,priority)传递给下一级加载器,最后没有下一级加载器则抛出异常。
ClassLoader 的子类初始化时需要完成两件事情:
1、通过构造方法指定当前类加载器的优先级,
2、通过父类的setNextClassLoader指定当前类加载器的下一个类加载器,构造加载链。
BootstrapClassLoader
public class BootstrapClassLoader extends ClassLoader{ public BootstrapClassLoader(int priority) { this.priority = priority; } @Override public void loader(String className) { // TODO Auto-generated method stub System.out.println("BootstrapClassLoader:" + className); } }
ExtensionClassLoader
public class ExtensionClassLoader extends ClassLoader{ public ExtensionClassLoader(int priority) { this.priority = priority; } @Override public void loader(String className) { // TODO Auto-generated method stub System.out.println("ExtensionClassLoader:" + className); } }
ApplicationClassLoader
public class ApplicationClassLoader extends ClassLoader{ public ApplicationClassLoader(int priority) { this.priority = priority; } @Override public void loader(String className) { // TODO Auto-generated method stub System.out.println("ApplicationClassLoader:" + className); } }
Main
public class Main { public static ClassLoader buildLoaderChain() { //设置各个加载器优先级 ClassLoader bootstrapClassLoader = new BootstrapClassLoader(ClassLoader.BOOTSTRP); ClassLoader extensionClassLoader = new ExtensionClassLoader(ClassLoader.EXTENSION); ClassLoader applicationClassLoader = new ApplicationClassLoader(ClassLoader.APPLICATION); //设置责任链条 bootstrap->extension->application, //优先级 1 2 3 //先传递给bootstrap可以加载则进行加载,如果不能传递给extension,以此类推。 //如果责任链单个结点优先级==类优先级则加载 //构造加载链 bootstrapClassLoader.setNextClassLoader(extensionClassLoader); extensionClassLoader.setNextClassLoader(applicationClassLoader); return bootstrapClassLoader; } public static void main(String args[]) { ClassLoader classLoader = buildLoaderChain(); classLoader.runLoader("BOOTSTRP", ClassLoader.BOOTSTRP); // bootstrap加载 1 classLoader.runLoader("EXTENSION", ClassLoader.EXTENSION); // extension加载 1->2 classLoader.runLoader("APPLICATION", ClassLoader.APPLICATION); // application加载 1->2->3 } }
运行结果:
当前加载器优先级:1--当前类优先级:1 BootstrapClassLoader:BOOTSTRP 当前加载器优先级:1--当前类优先级:2 当前加载器优先级:2--当前类优先级:2 ExtensionClassLoader:EXTENSION 当前加载器优先级:1--当前类优先级:3 当前加载器优先级:2--当前类优先级:3 当前加载器优先级:3--当前类优先级:3 ApplicationClassLoader:APPLICATION
参考资料:
https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html