• java 的SPI机制


    今天看到spring mvc 使用Java Validation Api(JSR-303)进行校验,需要加载一个 其具体实现(比如Hibernate Validator), 本来没有什么问题,但是突然想到这其中到底是怎样一种加载过程呢,也就是说spring为什么能够找到Hibernate Validator来作为JSR-303的具体实现的呢?

    1. java中的SPI机制

    这篇文章对java的SPI机制讲的比较容易理解,就不多做记录. http://www.cnblogs.com/javaee6/p/3714719.html 

    下面的小例子,分别采用SPI机制和 反射类名的方式来获取服务(helloApi)

    首先给出服务接口,将它导出为一个jar包, hello-api.jar

    package helloApi;
    
    public interface Hello {
        String say();
    }

    下面是它的一个具体实现:

    package helloImpl;
    
    import helloApi.Hello;
    
    public class HelloImpl implements Hello {
        @Override
        public String say() {
            return "hello Massclouds";
        }
    }

    将这个实现导出为jar包,但是为了使用java 的SPI机制,我们需要在导出的jar包的META-INF中增加services文件夹,并在其中增加一个文件,以 所实现接口 helloApi.Hello 为名,以 具体实现类 helloImpl.HelloImpl为内容。

    最后就是分别使用SPI和反射的方式来获得服务。

            Hello hello = null;
            //使用java的SPI机制加载Hello api的实现类
            ServiceLoader<Hello> serviceLoader = ServiceLoader.load(Hello.class);
            Iterator<Hello> iter = serviceLoader.iterator();
            if(iter.hasNext()){
                hello = iter.next();
            }
            
            System.out.println(hello.say()); 
            
            //通过反射类名的方式来获得Hello api的实现
            hello = (Hello)Class.forName("helloImpl.HelloImpl").newInstance();
            System.out.println(hello.say());

    回过头来考虑jdbc的加载方式,跟我上面的例子是一样的。这两种方式肯定是SPI更好,采用类名反射的方式本质上还是硬编码嘛!

    2. 如何加载Hibernate Validator来作为JSR-303的实现

    我们打开Hibernate Validator的jar包来看看。

    而这个文件的内容正是具体实现 org.hibernate.validator.HibernateValidator。至于具体Spring是怎么做的我就不详细研究了,哈哈!!!

      

  • 相关阅读:
    前端从头再出发之表单
    百度前端学院第19天作业
    百度前端学院第17到18天和第16天的作业
    百度前端学院第九天到第11天笔记
    自己爬虫的几个案例
    Magnum Kubernetes源码分析(一)
    magnum devstack部署
    kubernetes service分析
    玩转docker镜像和镜像构建
    Dockerfile与Docker构建流程解读
  • 原文地址:https://www.cnblogs.com/zh1164/p/6247406.html
Copyright © 2020-2023  润新知