springboot

如何寻找一个类或者接口的子类或者实现

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;
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读