服务提供者

211 阅读3分钟

一、概念

多个服务提供者实现一个服务,系统为服务提供者的客户端提供多个实现,并把他们从多个实现中解耦出来。提供者为框架的用户提供了多个API实现,框架必须提供一种机制来注册这些实现以便用户能够使用它们;框架的客户直接使用API,无需关心自己到底在使用哪个实现。

服务接口(Service Interface):定义了抽象的服务,以及一个或多个方法

服务实现类(Service Interface Impl):实现服务接口,实现具体的方法

服务提供者接口(Service Provider Interface):定义了抽象的服务提供者,提供一个获取服务的方法

服务提供者实现类(Service Provider Interface Impl):实现服务提供者接口,实现具体的方法

服务提供者注册API(Provider Registration API):提供一个注册服务提供者接口

服务访问API(Service Access API):提供一个调用服务的方法,是客户端用来获取服务的实例的

二、例子

服务接口(Service Interface)

/**
 * 服务者接口
 */
public interface IService {
   /**
    * 实现方法doService()
    */
   void doService();  
  
  /**
   * 实现方法doServiceTest
   */
   void doServiceTest();  
}

服务实现类(Service Interface Impl)

/**
 * 服务者接口实现类
 */
public class ServiceImpl implements IService {
   /**
    * 实现方法doService
    */
   public void doService() {
	System.out.println("do service ...");
   }
       
   /**
    * 实现方法doServiceTest
    */
   public void doServiceTest() {
	System.out.println("do service test ...");
   }
}

服务提供者接口(Service Provider Interface)

/**
 * 提供者接口
 */
public interface IProvider {
   /**
    * 
    * 关联IService,用来获取服务者接口
    */
   public IService getService();
}

服务提供者实现类(Service Provider Interface Impl)

/**
 * 提供者接口的实现类
 */
public class ProviderImpl implements IProvider {
   /**
    * 实现静态的注册
    */
   private static final String DEFAULT_PROVIDER = "test";

   static {
	ServiceManager.registerProvider(DEFAULT_PROVIDER, new ProviderImpl());
   }
 
   /**
    * 关联IService,用来获取服务接口
    */
   public IService getService() {
	return new ServiceImpl();
   }
}

服务提供者注册API(Provider Registration API)& 服务访问API(Service Access API)

/**
 * 服务提供者管理类
 */
public class ServiceManager {
   private ServiceManager() {
 
   }
 
   private static final Map<String, IProvider> providers = new ConcurrentHashMap<String, IProvider>();
  
   /**
    * 服务提供者注册API,注册服务提供者接口
    */
   public static void registerProvider(String name, IProvider p) {
	providers.put(name, p);
   }
   /**
    * 服务访问API,通过提供者来获取服务者接口
    */
   public static IService getService(String name) {
 
	IProvider p = providers.get(name);
	if (p == null) {
	     throw new IllegalArgumentException(
		    "No provider registered with name:" + name);
	    }
	    return p.getService();
	}
 
}

客户端测试类

/**
 * 客户端测试类
 */
public class Client {
    /** 
     * @param args 
     * @throws ClassNotFoundException  
     */  
    public static void main(String[] args) throws ClassNotFoundException {  
        Class.forName("com.lzw.provider.impl.ProviderImpl");  
        IService service = ServiceManager.getService("test");  
        service.doService();
        service.doServiceTest();
    }  
}

三、数据库驱动服务提供者

服务接口(Service Interface)

public interface Connection  extends Wrapper, AutoCloseable {
		
		Statement createStatement() throws SQLException;
		
		PreparedStatement prepareStatement(String sql)
        throws SQLException;

		.......省略其他代码.......
}

服务实现类(Service Interface Impl)

package com.mysql.jdbc;

public class ConnectionImpl extends ConnectionPropertiesImpl implements MySQLConnection {
		public java.sql.Statement createStatement() throws SQLException {
        return this.createStatement(1003, 1007);
    }

		public PreparedStatement prepareStatement(String sql) throws SQLException {
        return this.prepareStatement(sql, 1003, 1007);
    }
		
		.......省略其他代码.......
}

服务提供者接口(Service Provider Interface)

public interface Driver {
		Connection connect(String url, java.util.Properties info)
        throws SQLException;
  
 		boolean acceptsURL(String url) throws SQLException;
  	
  	.......省略其他代码.......
}

服务提供者实现类(Service Provider Interface Impl)

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

    static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
    
    
    public Connection connect(String url, Properties info) throws SQLException {
        if (url == null) {
            throw SQLError.createSQLException(Messages.getString("NonRegisteringDriver.1"), "08001", (ExceptionInterceptor)null);
        } else if (StringUtils.startsWithIgnoreCase(url, "jdbc:mysql:loadbalance://")) {
            return this.connectLoadBalanced(url, info);
        } else if (StringUtils.startsWithIgnoreCase(url, "jdbc:mysql:replication://")) {
            return this.connectReplicationConnection(url, info);
        } else {
            Properties props = null;
            if ((props = this.parseURL(url, info)) == null) {
                return null;
            } else if (!"1".equals(props.getProperty("NUM_HOSTS"))) {
                return this.connectFailover(url, info);
            } else {
                try {
                    com.mysql.jdbc.Connection newConn = ConnectionImpl.getInstance(this.host(props), this.port(props), props, this.database(props), url);
                    return newConn;
                } catch (SQLException var6) {
                    throw var6;
                } catch (Exception var7) {
                    SQLException sqlEx = SQLError.createSQLException(Messages.getString("NonRegisteringDriver.17") + var7.toString() + Messages.getString("NonRegisteringDriver.18"), "08001", (ExceptionInterceptor)null);
                    sqlEx.initCause(var7);
                    throw sqlEx;
                }
            }
        }
    }
}

服务提供者注册API(Provider Registration API)& 服务访问API(Service Access API)

public class DriverManager {

	
    // 服务提供者信息列表
    private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();
	
    private DriverManager(){}
    
    static {
        loadInitialDrivers();
        println("JDBC DriverManager initialized");
    }
    
    private static void loadInitialDrivers() {
        String drivers;
        try {
            drivers = AccessController.doPrivileged(new PrivilegedAction<String>() {
                public String run() {
                    return System.getProperty("jdbc.drivers");
                }
            });
        } catch (Exception ex) {
            drivers = null;
        }

        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            public Void run() {

                ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
                Iterator<Driver> driversIterator = loadedDrivers.iterator();
                try{
                    while(driversIterator.hasNext()) {
                        driversIterator.next();
                    }
                } catch(Throwable t) {
                // Do nothing
                }
                return null;
            }
        });

        println("DriverManager.initialize: jdbc.drivers = " + drivers);

        if (drivers == null || drivers.equals("")) {
            return;
        }
        String[] driversList = drivers.split(":");
        println("number of Drivers:" + driversList.length);
        for (String aDriver : driversList) {
            try {
                println("DriverManager.Initialize: loading " + aDriver);
                Class.forName(aDriver, true,
                        ClassLoader.getSystemClassLoader());
            } catch (Exception ex) {
                println("DriverManager.Initialize: load failed: " + ex);
            }
        }
    }
    
    /**
     * 服务提供者注册API
     */
    public static synchronized void registerDriver(java.sql.Driver driver)
        throws SQLException {

        registerDriver(driver, null);
    }
    
    /**
     * 服务访问API
     */
     @CallerSensitive
    public static Connection getConnection(String url,
        java.util.Properties info) throws SQLException {

        return (getConnection(url, info, Reflection.getCallerClass()));
    }
}    
    

四、附件

ServiceLoader源码分析可以看我另一篇文章:juejin.cn/post/684490…