美文网首页springboot
如何寻找一个类或者接口的子类或者实现

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

作者: 毛不翼 | 来源:发表于2019-09-26 09:56 被阅读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;
        }
    }
}

相关文章

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

    方法一:在spring环境中借助spring生命周期以及spring对bean的管理 在spring体系中,没有提...

  • 匿名内部类和包装类

    匿名内部类 匿名内部类会隐式的继承一个类或者实现一个接口,或者说,匿名内部类是一个继承了该类或者实现了该接口的子类...

  • UML六大关系

    继承 子类继承父类或者子接口继承父接口,在UML图中用实线空心箭头表示。 实现 类实现接口的功能,在UML图中用虚...

  • 多态 ---- 内部类

    多态: 父类的引用指向子类对象,或者接口指向实现类 Animal an = new Dog(); 前提:必须要有...

  • instanceof运算符

    使用格式: 引用类型变量 instanceof 类(接口) 作用: 用于判断变量是否属于后面的类或者其子类、实现类...

  • 接口测试哪几个点是需要特别关注的?

    接口和抽象类的区别: 1、都不能被实例化。 2、接口的实现类和抽象类的子类只有全部实现了接口或者抽象类中的方法后才...

  • 设计模式之策略模式

    需求:现在需要做一个简单计算器,有加法,减法。 类图如下: 接口或者父类:Arthmeric(算法) 实现类或子类...

  • 新手做接口测试哪几个点是需要特别关注的?

    接口和抽象类的区别:1、都不能被实例化。 2、接口的实现类和抽象类的子类只有全部实现了接口或者抽象类中的方法后才可...

  • 新手做接口测试哪几个点是需要特别关注的?

    接口和抽象类的区别:1、都不能被实例化。 2、接口的实现类和抽象类的子类只有全部实现了接口或者抽象类中的方法后才可...

  • Java基础-11 多态

    多态: 父类引用类型变量指向了子类的对象或者是接口的引用类型变量指向了接口实现类的对象。 (一个对象具备多种形态)...

网友评论

    本文标题:如何寻找一个类或者接口的子类或者实现

    本文链接:https://www.haomeiwen.com/subject/vlzvuctx.html