ServiceLoader加载接口的所有实现

什么是ServiceLoader?

ServiceLoader 是由 JDK 提供的,在 java.util 包下的一个工具类,使用该工具类,可以加载一个接口的所有实现类。

getBeansOfType()

在 Spring 框架中,ApplicationContext 类提供了 getBeansOfType() 方法,同样可以启到和 ServiceLoader 相同的效果,可以获取同一类接口的所有实现类。
不过这个方法仅限于被 Spring 管理的项目,如果一个项目没有被 Spring 管理,也就无法使用该方法,这时就可以考虑使用 ServiceLoader

ServiceLoader的使用

接口和实现类

public interface IService {
    void service();
}
public class UserServiceImpl implements IService {
    @Override
    public void service() {
        System.out.println("用户服务");
    }
}
public class RoleServiceImpl implements IService {
    @Override
    public void service() {
        System.out.println("角色服务");
    }
}
public class ResourcesServiceImpl implements IService {
    @Override
    public void service() {
        System.out.println("资源服务");
    }
}

配置META-INF/services

在项目的 resources 目录下,创建目录 META-INF/services,该目录为固定目录,ServiceLoader会默认读取该目录下的资源和文件。

META-INF/services 目录下创建一个文件,文件名为接口的全限定类名。
例如上述的 IService接口,应该在 META-INF/services 目录下创建 com.loader.IService 文件。

其中 com.loader 为自定义的包名称,并非定式包名。

resources
	|_META-INF
		|_services
			|_com.loader.IService

com.loader.IService

# 注释
com.loader.UserServiceImpl
com.loader.RoleServiceImpl
com.loader.ResourcesServiceImpl

load()方法

public class ServiceMain {
    public static void main(String[] args) {
        ServiceLoader<IService> services = ServiceLoader.load(IService.class);
        for (IService item : services) {
            item.service();
        }
    }
}

ServiceLoader的缺点

  • ServiceLoader 虽然可以加载一个接口的所有实现类,但是本质上还是通过 META-INF/services 目录下配置文件,通过 Java 反射功能进行加载的,并无法实现动态加载的效果。

  • ServiceLoader 因为是通过反射进行加载的,所有的接口实现类必须拥有一个无参构造函数,否则实现类无法被反射实例化。

Spring和ServiceLoader

Spring 的 getBeansOfType() 方法和 JDK 的 ServiceLoader 都可以实现类似的功能,那么在项目中应该优先使用哪个呢?

如果项目中使用了 Spring 框架,项目中的接口实现都已被 Spring 核心容器管理,那么建议优先使用 Spring 的 getBeansOfType() 方法,因为所有实现类被 Spring 核心容器管理的情况下,使用 getBeansOfType() 方法可以达到一种“伪动态”加载的效果,而且代码更具有扩展性。

如果项目只是一个普通的项目,那么可以使用 ServiceLoader 来进行接口实现类的加载。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值