原文出自: http://blog.csdn.net/anxpp/article/details/52295168 ,转载请注明出处,谢谢!

准备做一个IM,实现服务端的时候,准备将所有消息处理器(MessageHandler)使用 责任链设计模式 ,但是又不希望增加处理器的时候修改责任链的实现。

这时想到了Spring框架的实现,我们在使用Spring Boot 时,只需要实现一些接口,Spring能自动处理。

所以就想到通过指定接口和要扫描的包路径来获取所有处理器接口的实现,这样动态添加处理器就不需要修改责任链的实现了。

具体代码如下:

package com.anxpp.im.config;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import com.anxpp.im.server.handler.MessageHandler;
 * 通过接口获取所有实现
 * @author http://anxpp.com/ 时间:2016年8月23日 下午10:16:53
@SuppressWarnings("rawtypes")
public class ClassUtil {
	private Class clazz;
	private String packagePath;
	public ClassUtil(Class clazz, String packagePath) {
		this.clazz = clazz;
		this.packagePath = packagePath;
	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws ClassNotFoundException, IOException, InstantiationException, IllegalAccessException {
		List<Class> handlers = new ClassUtil(MessageHandler.class, "com.anxpp.im.server.controller").getAllClassByPackage();
		for (Class<MessageHandler> handler : handlers) {
			handler.newInstance().dealMessage();
	 * 通过包名获取所有实现(可以将包名配置到统一配置文件中)
	 * @param packageName
	 * @return
	@SuppressWarnings("unchecked")
	public List<Class> getAllClassByPackage() {
		ArrayList<Class> returnClassList = new ArrayList<Class>();
		try {
			List<Class> allClass = getClasses(packagePath);
			// 判断是否是一个接口
			for (int i = 0; i < allClass.size(); i++) {
				if (clazz.isAssignableFrom(allClass.get(i))) {
					if (!clazz.equals(allClass.get(i))) {
						returnClassList.add(allClass.get(i));
		} catch (Exception e) {
		return returnClassList;
	private List<Class> getClasses(String packageName) throws ClassNotFoundException, IOException {
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		String path = packageName.replace(".", "/");
		Enumeration<URL> resources = classLoader.getResources(path);
		List<File> dirs = new ArrayList<File>();
		while (resources.hasMoreElements()) {
			URL resource = resources.nextElement();
			dirs.add(new File(resource.getFile()));
		ArrayList<Class> classes = new ArrayList<Class>();
		for (File directory : dirs) {
			classes.addAll((Collection<? extends Class>) findClass(directory, packageName));
		return classes;
	private List<Class> findClass(File directory, String packageName) throws ClassNotFoundException {
		List<Class> classes = new ArrayList<Class>();
		if (!directory.exists()) {
			return classes;
		File[] files = directory.listFiles();
		for (File file : files) {
			if (file.isDirectory()) {
				assert !file.getName().contains(".");
				classes.addAll(findClass(file, packageName + "." + file.getName()));
			} else if (file.getName().endsWith(".class")) {
				classes.add((Class) Class.forName(packageName + "." + file.getName().substring(0, file.getName().length() - 6)));
		return classes;

    处理器接口:

package com.anxpp.im.server.handler;
 * 客户端消息处理器接口
 * @author http://anxpp.com/  时间:2016年8月23日  下午8:18:05
public interface MessageHandler {
	void dealMessage();

    其中一个处理器实现如下:

package com.anxpp.im.server.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.anxpp.im.server.handler.Handler;
import com.anxpp.im.server.handler.MessageHandler;
@Handler
public class LoginHandler implements MessageHandler{
	private static final Logger log = LoggerFactory.getLogger(LoginHandler.class);
	@Override
	public void dealMessage() {
		log.info("登陆消息");
}
    这里只是简单的实现,并没有完全贴出责任链的代码。

    其中的@Handler注解还没用上,本意是判断接口同时判断是否注解为处理器。

原文出自:http://blog.csdn.net/anxpp/article/details/52295168,转载请注明出处,谢谢!    准备做一个IM,实现服务端的时候,准备将所有消息处理器(MessageHandler)使用责任链设计模式,但是又不希望增加处理器的时候修改责任链的实现。    这时想到了Spring框架的实现,我们在使用Spring Boot 时,只需要实现一些接 public class ClassUtils { //给一个接口,返回这个接口的所有实现类 public static List<Class> getAllClassByInterface(Class c) { List<Class> returnClassList = new ArrayList<Class>(); // 返回结果 // 如果不是一个接口,则不做处理
URLClassLoader classLoader = new URLClassLoader(new URL[]{new URL("jar 本地路径,例如:file:D:/project/inputsplit-1.0-SNAPSHOT.jar")}, Thread.currentThread().getContextClassLoader()); Reflections reflectio...
想在自己开发的项目上加一个算法工具类用来整合不同的算法,并且要求低耦合符合开闭原则,于是想到了《大话设计模式》里的策略模式,但是书中的策略模式还没有达到完全符合开闭原则,同时我在文章结尾看见说可以运用反射机制来大幅降低代码的耦合度,因此开始在学习如何实现,在学习过程中发现需要写一个方法用来找到指定接口实现类,因此开启了这趟学习之旅。 二、寻求答案的路途 刚开始看到根据指定接...
最近有个需求,我需要获取所有同一类型的定时任务的对象,并自动执行。我想的方案是:直接获取某个接口下面所有的实现类的对象集合,方便以后只需要 实现这个接口,就能自动被加载执行。话不多说,说说我的实现方案。开始想着用反射自己写一个工具类,后面懒得去折腾,就直接用第三方工具包了 , 这里我用的是org.reflections .maven配置: org.reflections reflectio
前面做的在mybatis通过注解自动创建更新表结构的项目,其中在spring加载完毕之后需要去获取所有实体类的class,用来获取实体类属性上的注解,进而分析表结构达到创建修改表结构的目的。 所以就需要一个功能,通过包名获取该包下的所有class,那么直接贴代码: package com.sunchenbin.store.utils; import java.io.File; import
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; impo...
测试demo; git仓库 :  https://github.com/alwaysInRoad/test-forEach-package.git                   csdn下载地址:https://download.csdn.net/download/weixin_40841731/10707911 demo为普通项目,引入普通java project就可以了 1、说明:...