类加载器特技:OSGi代码生成
2010-03-01 00:00:00 来源:WEB开发网把事情放到一起
所有关于这个类加载的传说可以被浓缩为下面的100行代码:
public class Enhancer {
private final ClassLoader privateSpace;
private final Namer namer;
private final Generator generator;
private final Map<ClassLoader , WeakReference<ClassLoader>> cache;
public Enhancer(ClassLoader privateSpace, Namer namer, Generator generator) {
this.privateSpace = privateSpace;
this.namer = namer;
this.generator = generator;
this.cache = new WeakHashMap<ClassLoader , WeakReference<ClassLoader>>();
}
@SuppressWarnings("unchecked")
public <T> Class<T> enhance(Class<T> target) throws ClassNotFoundException {
ClassLoader context = resolveBridge(target.getClassLoader());
String name = namer.map(target.getName());
return (Class<T>) context.loadClass(name);
}
private synchronized ClassLoader resolveBridge(ClassLoader targetSpace) {
ClassLoader bridge = null;
WeakReference<ClassLoader> ref = cache.get(targetSpace);
if (ref != null) {
bridge = ref.get();
}
if (bridge == null) {
bridge = makeBridge(targetSpace);
cache.put(appSpace, new WeakReference<ClassLoader>(bridge));
}
return bridge;
}
private ClassLoader makeBridge(ClassLoader targetSpace) {
/* Use the target space as a parent to be searched first */
return new ClassLoader(targetSpace) {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
/* Is this used privately by the enhancements? */
if (generator.isInternal(name)) {
return privateSpace.loadClass(name);
}
/* Is this a request for enhancement? */
String unpacked = namer.unmap(name);
if (unpacked != null) {
byte[] raw = generator.generate(unpacked, name, this);
return defineClass(name, raw, 0, raw.length);
}
/* Ask someone else */
throw new ClassNotFoundException(name);
}
};
}
}
public interface Namer {
/** Map a target class name to an enhancement class name. */
String map(String targetClassName);
/** Try to extract a target class name or return null. */
String unmap(String className);
}
public interface Generator {
/** Test if this is a private implementation class. */
boolean isInternal(String className);
/** Generate enhancement bytes */
byte[] generate(String inputClassName, String outputClassName, ClassLoader context);
}
更多精彩
赞助商链接