如何寻找一个类或者接口的子类或者实现
2019-09-26 本文已影响0人
毛不翼
方法一:在spring环境中借助spring生命周期以及spring对bean的管理
在spring体系中,没有提供类似的功能,然而这种需求却经常出现在实际应用中,为了曲线救国,只能在spring初始化bean的时候,把bean的类型分类记录下来,当每一个bean初始化完成的时候,我们拿到这个bean,用instanceof来判断bean的类型,从而放到pool里,当然这里业务是可以拓展的,因为有了bean之后,能拿到bean的class,能拿到class上的注解,通过这些特征也可以对bean进行分类,放在pool里,这样一来,我们需要使用的时候,直接从pool里取就可以了。
BeanPostProcessor代码
public class HandlerBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof AbstractCommandHandler) {
AbstractCommandHandler commandHandler = (AbstractCommandHandler) bean;
CommandHandlerFactory.addHandler(commandHandler, (synchronize, handlerPool) -> {
if (synchronize) {
handlerPool.addSynchronizedHandler(commandHandler);
} else {
handlerPool.addAsynchronousHandler(commandHandler);
}
});
}
if (bean instanceof AbstractEventHandler) {
AbstractEventHandler eventHandler = (AbstractEventHandler) bean;
EventHandlerFactory.addHandler(eventHandler, (synchronize, handlerPool) -> {
if (synchronize) {
handlerPool.addSynchronizedHandler(eventHandler);
} else {
handlerPool.addAsynchronousHandler(eventHandler);
}
});
}
return bean;
}
}
CommandHandlerFactory 代码
public class CommandHandlerFactory {
private static ConcurrentHashMap<Class,HandlerPool> handlerPoolMap = new ConcurrentHashMap<>(8);
public static void addHandler(AbstractCommandHandler handler, BiConsumer<Boolean, HandlerPool> biConsumer) {
HandlerDefinition annotation = handler.getClass().getAnnotation(HandlerDefinition.class);
Class<?> aClass = annotation.commandClass();
boolean synchronize = annotation.isSynchronize();
HandlerPool handlerPool = getHandlerPool(aClass);
biConsumer.accept(synchronize, handlerPool);
}
private static HandlerPool getHandlerPool(Class<?> aClass) {
HandlerPool handlerPool = handlerPoolMap.get(aClass);
if (handlerPool==null) {
handlerPool = new HandlerPool();
handlerPoolMap.put(aClass,handlerPool);
}
return handlerPool;
}
public static HandlerPool create(AbstractCommand command){
return handlerPoolMap.get(command.getClass());
}
}
方法二:访问class文件搜索
寻找FilterStrategy的子类并按照规则放在strategyPool里边
private static void initFromJar(URL resource,String pkgPath) throws Exception {
URLConnection urlConnection = resource.openConnection();
JarURLConnection result = (JarURLConnection) urlConnection;
JarFile jarFile = ((JarURLConnection) urlConnection).getJarFile();
JarInputStream jarInputStream = new JarInputStream(result.getJarFileURL().openConnection().getInputStream());
JarEntry entry;
while ((entry = jarInputStream.getNextJarEntry()) != null) {
if(!entry.isDirectory()) {
String entryName = entry.getName();
if (entryName.startsWith(pkgPath)) {
Class<?> aClass = Class.forName(entryName.substring(0, entryName.length() - 6).replace('/','.'));
if (aClass.equals(FilterStrategy.class) || !FilterStrategy.class.isAssignableFrom(aClass)){
continue;
}
strategies.add((Class<? extends FilterStrategy>) aClass);
strategyPool.put(aClass.getSimpleName().substring(0,aClass.getSimpleName().length()-14).toLowerCase(),(Class<? extends FilterStrategy>) aClass);
}
}
}
}
private static void initFromFile(URL resource,String pkgName) throws Exception {
String file = resource.getFile();
File file1 = new File(file);
File[] files = file1.listFiles();
for (File file2 : files) {
if (!file2.isDirectory()) {
String name1 = file2.getName();
Class<?> aClass = Class.forName((pkgName + "." + name1.substring(0, name1.length() - 6)).replace('/','.'));
if (aClass.equals(FilterStrategy.class) || !FilterStrategy.class.isAssignableFrom(aClass)){
continue;
}
strategies.add((Class<? extends FilterStrategy>) aClass);
strategyPool.put(name1.substring(0,name1.length()-20).toLowerCase(),(Class<? extends FilterStrategy>) aClass);
}
}
}
public class FilterStrategyFactory {
private FilterStrategyFactory() {
throw new IllegalStateException();
}
private static List<Class<? extends FilterStrategy>> strategies = new ArrayList<>();
private static Map<String,Class<? extends FilterStrategy>> strategyPool = new HashMap<>();
static {
try {
String pkgName = FilterStrategy.class.getPackage().getName();
String pkgPath = pkgName.replace(".", "/");
URL resource = Thread.currentThread().getContextClassLoader().getResource(pkgPath);
String protocol = resource.getProtocol();
if (protocol.equalsIgnoreCase("jar")) {
initFromJar(resource,pkgPath);
}else if(protocol.equalsIgnoreCase("file")){
initFromFile(resource,pkgPath);
}
} catch (Exception e) {
Logger.getLogger("context").log(Level.INFO,"init strategy error:",e);
}
}
public static FilterStrategy produce(String describe){
try {
String substring = describe.substring(describe.lastIndexOf('/')+1,describe.indexOf(".json")).toLowerCase();
return strategyPool.get(substring).newInstance();
} catch (InstantiationException | IllegalAccessException e) {
Logger.getLogger("context").log(Level.INFO,"init strategy error:",e);
return null;
}
}
}