1 16 17 package org.springframework.core; 18 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.util.Collections ; 22 import java.util.HashSet ; 23 import java.util.Iterator ; 24 import java.util.Set ; 25 26 import org.springframework.util.Assert; 27 import org.springframework.util.FileCopyUtils; 28 29 41 public class OverridingClassLoader extends ClassLoader { 42 43 private static final String CLASS_FILE_SUFFIX = ".class"; 44 45 46 private final Set excludedPackages = Collections.synchronizedSet(new HashSet ()); 47 48 private final Set excludedClasses = Collections.synchronizedSet(new HashSet ()); 49 50 51 55 public OverridingClassLoader(ClassLoader parent) { 56 super(parent); 57 this.excludedPackages.add("java."); 58 this.excludedPackages.add("javax."); 59 } 60 61 62 68 public void excludePackage(String packageName) { 69 Assert.notNull(packageName, "Package name must not be null"); 70 this.excludedPackages.add(packageName); 71 } 72 73 79 public void excludeClass(String className) { 80 Assert.notNull(className, "Class name must not be null"); 81 this.excludedClasses.add(className); 82 } 83 84 85 protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { 86 Class result = null; 87 88 if (isEligibleForOverriding(name)) { 89 result = findLoadedClass(name); 90 if (result == null) { 91 String internalName = name.replace('.', '/') + CLASS_FILE_SUFFIX; 92 InputStream is = getParent().getResourceAsStream(internalName); 93 if (is != null) { 94 try { 95 byte[] bytes = FileCopyUtils.copyToByteArray(is); 97 byte[] transformed = transformIfNecessary(name, bytes); 99 result = defineClass(name, transformed, 0, transformed.length); 100 } 101 catch (IOException ex) { 102 throw new ClassNotFoundException ("Cannot load resource for class [" + name + "]", ex); 103 } 104 } 105 } 106 } 107 108 if (result != null) { 109 if (resolve) { 110 resolveClass(result); 111 } 112 return result; 113 } 114 else { 115 return super.loadClass(name, resolve); 116 } 117 } 118 119 128 protected boolean isEligibleForOverriding(String className) { 129 if (this.excludedClasses.contains(className)) { 130 return false; 131 } 132 for (Iterator it = this.excludedPackages.iterator(); it.hasNext();) { 133 String packageName = (String ) it.next(); 134 if (className.startsWith(packageName)) { 135 return false; 136 } 137 } 138 return true; 139 } 140 141 142 150 protected byte[] transformIfNecessary(String name, byte[] bytes) { 151 return bytes; 152 } 153 154 } 155
| Popular Tags
|