获取某接口的所有实现类并初始化

白诗秀儿 关注

收藏于 : 2018-08-24 11:34   被转藏 : 1   

        日前项目中遇到一个问题:

        有一个接口,这个接口定义了一种规范和标志,接口中只有一个初始化方法,接口的实现类可能会有非常多,所以现在容器启动过程中我们去手动初始化这个接口的所有实现类,虽然在spring中我们可以直接配置,但是维护与使用时却不够优雅。

       1. 以一个Config接口为例:

public interface Config {

    /**
     * 初始化
     */
    void initialize();
}

        接口很简单,只有一个初始化方法。

        2.然后Config接口可能会有很多种实现,比如:

public class RedisConfig implements Config {

    @Override
    public void initialize() {
        // 初始化实现
    }

}

        然而像这种实现可能会非常多且不受控制,但是我们又想对这些实现统一进行初始化,第一步我们就会想到利用ClassLoader来实现,但是如果这些实现类在不同的包中就非常麻烦,随后我们又想到了ServiceLoader,但是需要配置且不同包下也失败了。

        在这里我选择了Reflections类库,Reflections使用起来非常简单比Java自身的反射要简便的多,而且好用的多。

        3.导入Maven配置

<dependency>
	<groupId>org.reflections</groupId>
	<artifactId>reflections-spring</artifactId>
	<version>0.9.9-RC1</version>
	<exclusions>
		<exclusion>
			<groupId>javassist</groupId>
			<artifactId>javassist</artifactId>
		</exclusion>
	</exclusions>
</dependency>

        注意不要选错了。

        4.编写相关工具

public class ConfigUtil {

    // 初始化方法名称
    private static final String INIT_METHOD_NAME = "initialize";
    // 要扫描的包名
    private static final String PACKAGE_NAME     = "com.xxxx";

    public static void main(String[] args) {
        List<String> list = getConfigNameList();
        for (String name : list) {
            System.out.println(name);
            //初始化
	    manualInitialize(name);
        }
    }

    /**
     * 获取所有模块名称
     *
     * @return
     */
    public static List<String> getConfigNameList() {
        List<String> nameList = new ArrayList<String>();
        Reflections reflections = new Reflections(PACKAGE_NAME);
        Set<Class<? extends Config>> classes = reflections.getSubTypesOf(Config.class);
        if (monitorClasses != null) {
            for (Class<? extends Config> config: classes) {
                boolean isAbstract = Modifier.isAbstract(config.getModifiers());
		//过滤抽象类
                if (!isAbstract) {
                    nameList.add(config.getName());
                }
            }
        }
        return nameList;
    }

    /**
     * 获取所有实现
     *
     * @return
     */
    public static List<Class> getConfigList() {
        List<Class> configList= new ArrayList<Class>();
        Reflections reflections = new Reflections(PACKAGE_NAME);
        Set<Class<? extends Config>> classes = reflections.getSubTypesOf(Config.class);
        if (monitorClasses != null) {
            for (Class<? extends Config> config : classes) {
                boolean isAbstract = Modifier.isAbstract(config.getModifiers());
                if (!isAbstract) {
                    configList.add(config);
                }
            }
        }
        return moduleList;
    }

    /**
     * 调用初始化方法
     *
     * @param fullClassName 全限定名
     */
    @SuppressWarnings("unchecked")
    public static void manualInitialize(String fullClassName) {
        try {
            Class clazz = Class.forName(fullClassName);
            Constructor[] constructors = clazz.getDeclaredConstructors();
            AccessibleObject.setAccessible(constructors, true);
            for (Constructor con : constructors) {
                if (con.isAccessible()) {
                    Object classObject = con.newInstance();
                    Method method = clazz.getMethod(INIT_METHOD_NAME);
                    method.invoke(classObject);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

        最终我们调用manualInitialize(name);方法进行了初始化。

 

 

 阅读文章全部内容  
点击查看
文章点评
相关文章
白诗秀儿 关注

文章收藏:1308

TA的最新收藏