|
|
看过#getImplementations()之后,来看一下#startServices()方法,这个方法就是启动服务了,前面看到的JDBC服务就是在这里启动的(addProperty("derby.service.jdbc", "org.apache.derby.jdbc.InternalDriver");)
public void startServices(Properties properties, boolean bootAll) {if (properties == null)return;for (Enumeration e = properties.propertyNames(); e.hasMoreElements();) {/* 获得服务的键值 */String key = (String) e.nextElement();if (key.startsWith(SERVICE)) {// 判断是否以"derby.service."开头/* 返回服务名 */String name = key.substring(SERVICE.length());/* 服务的协议或类型,其实就是类名 */String protocolOrType = properties.getProperty(key);try {/* 如果协议名等于"serviceDirectory" */if (protocolOrType.equals(Monitor.SERVICE_TYPE_DIRECTORY)) {if (bootAll)findProviderAndStartService(name, properties, true);} else {/* 开启服务 */bootService((PersistentService) null, protocolOrType, name, (Properties) null, false);}} catch (StandardException se) {if (!protocolOrType.equals(Monitor.SERVICE_TYPE_DIRECTORY))reportException(se);}}}}
这里需要重点留意的是协议名不等于"serviceDirectory"的情况,也就是进入#bootService()方法的分支。
这个方法也是非常长的,我们来研究下,
protected Object bootService(PersistentService provider, String factoryInterface, String serviceName,Properties properties, boolean create) throws StandardException {/* * 以 "derby.service.jdbc", "org.apache.derby.jdbc.InternalDriver" 为例 * provider = null factoryInterface = protocolOrType * (org.apache.derby.jdbc.InternalDriver) serviceName = name (jdbc) * properties = null create = false */if (provider != null)serviceName = provider.getCanonicalServiceName(serviceName);/* ProtocolKey里存了两个属性factoryInterface和serviceName */ProtocolKey serviceKey = ProtocolKey.create(factoryInterface, serviceName);if (SanityManager.DEBUG && reportOn) {report("Booting service " + serviceKey + " create = " + create);}ContextManager previousCM = contextService.getCurrentContextManager();ContextManager cm = previousCM;Object instance;TopService ts = null;Context sb = null;try {synchronized (this) {if (inShutdown) {throw StandardException.newException(SQLState.CLOUDSCAPE_SYSTEM_SHUTDOWN);}/* * 这里services这个变量实在BaseMonitor的构造函数中初始化的 services = new * Vector(0, 1); services.addElement(new TopService(this)); // */for (int i = 1; i < services.size(); i++) {TopService ts2 = (TopService) services.elementAt(i);if (ts2.isPotentialService(serviceKey)) {// if the service already exists then just return nullreturn null;}}/* 取得Locale */Locale serviceLocale = null;if (create) {properties = new Properties(properties);serviceLocale = setLocale(properties);properties.put(Property.SERVICE_PROTOCOL, factoryInterface);serviceName = provider.createServiceRoot(serviceName, Boolean.valueOf(properties.getProperty(Property.DELETE_ON_CREATE)).booleanValue());serviceKey = ProtocolKey.create(factoryInterface, serviceName);} else if (properties != null) {String serverLocaleDescription = properties.getProperty(Property.SERVICE_LOCALE);if (serverLocaleDescription != null)serviceLocale = staticGetLocaleFromString(serverLocaleDescription);}/* TopService代表了对module实例的描述 */ts = new TopService(this, serviceKey, provider, serviceLocale);services.addElement(ts);}if (SanityManager.DEBUG) {if (provider != null) {SanityManager.ASSERT(provider.getCanonicalServiceName(serviceName).equals(serviceName),"mismatched canonical names " + provider.getCanonicalServiceName(serviceName) + " != "+ serviceName);SanityManager.ASSERT(serviceName.equals(serviceKey.getIdentifier()), "mismatched names "+ serviceName + " != " + serviceKey.getIdentifier());}}if (properties != null) {properties.put(PersistentService.ROOT, serviceName);properties.put(PersistentService.TYPE, provider.getType());}if (SanityManager.DEBUG && reportOn) {dumpProperties("Service Properties: " + serviceKey.toString(), properties);}if (previousCM == null) {cm = contextService.newContextManager();contextService.setCurrentContextManager(cm);}sb = new ServiceBootContext(cm);UpdateServiceProperties usProperties;Properties serviceProperties;boolean inRestore = (properties != null ? properties.getProperty(Property.IN_RESTORE_FROM_BACKUP) != null: false);if ((provider != null) && (properties != null)) {usProperties = new UpdateServiceProperties(provider, serviceName, properties, !(create || inRestore));serviceProperties = usProperties;} else {usProperties = null;serviceProperties = properties;}/* 这个方法比较重要,进行module的启动 */instance = ts.bootModule(create, null, serviceKey, serviceProperties);if (create || inRestore) {provider.saveServiceProperties(serviceName, usProperties.getStorageFactory(), BaseMonitor.removeRuntimeProperties(properties), false);usProperties.setServiceBooted();}if (cm != previousCM)cm.cleanupOnError(StandardException.closeException());} catch (Throwable t) {StandardException se;if ((t instanceof StandardException)&& (((StandardException) t).getSeverity() == ExceptionSeverity.DATABASE_SEVERITY))se = (StandardException) t;elsese = Monitor.exceptionStartingModule(t);if (cm != previousCM) {cm.cleanupOnError(se);}if (ts != null) {ts.shutdown();synchronized (this) {services.removeElement(ts);}boolean deleteOnError = (properties != null ? properties.getProperty(Property.DELETE_ROOT_ON_ERROR) != null: false);if (create || deleteOnError)provider.removeServiceRoot(serviceName);}Throwable nested = se.getCause();if (nested instanceof ThreadDeath)throw (ThreadDeath) nested;throw se;} finally {if ((previousCM == cm) && (sb != null))sb.popMe();if (previousCM == null)contextService.resetCurrentContextManager(cm);}/* 这个方法把module实例加入到protocolTable这个Hashtable中 */ts.setTopModule(instance);Thread.yield();return instance;}
这里instance = ts.bootModule(create, null, serviceKey, serviceProperties);这一步比较重要,这步会找到module的实现类,然后返回module的实例。
Object bootModule(boolean create, Object service, ProtocolKey key, Properties properties) throws StandardException {synchronized (this) {if (inShutdown)throw StandardException.newException(SQLState.SHUTDOWN_DATABASE, getKey().getIdentifier());}/* 查看是否已经启动了这个module,在protocolTable这个Hashtable中先查找实例 */Object instance = findModule(key, false, properties);if (instance != null)// 如果有,直接返回return instance;if (monitor.reportOn) {monitor.report("Booting Module " + key.toString() + " create = " + create);}synchronized (this) {for (int i = 0; i < moduleInstances.size(); i++) {// 在运行中的module中查找/* module的包装类 */ModuleInstance module = (ModuleInstance) moduleInstances.elementAt(i);if (!module.isTypeAndName((PersistentService) null, key.getFactoryInterface(), key.getIdentifier()))continue;instance = module.getInstance();if (!BaseMonitor.canSupport(instance, properties))continue;// 把实例加入到protocolTable中if (!addToProtocol(key, module))continue;if (monitor.reportOn) {monitor.report("Started Module " + key.toString());monitor.report(" Implementation " + instance.getClass().getName());}return instance;}}/* 这步就是载入module实例了,以我们之前的JDBC module为例,会找到与当前JDBC版本对应的Driver */instance = monitor.loadInstance(key.getFactoryInterface(), properties);if (instance == null) {throw Monitor.missingImplementation(key.getFactoryInterface().getName());}ModuleInstance module = new ModuleInstance(instance, key.getIdentifier(), service,topModule == null ? (Object) null : topModule.getInstance());moduleInstances.addElement(module);try {/* 这里会调用module的#boot()方法 */BaseMonitor.boot(instance, create, properties);} catch (StandardException se) {moduleInstances.removeElement(module);throw se;}synchronized (this) {/* 加入到Hashtable中 */if (addToProtocol(key, module)) {if (monitor.reportOn) {monitor.report("Started Module " + key.toString());monitor.report(" Implementation " + module.getInstance().getClass().getName());}return module.getInstance();}}/* 如果加入失败,那么就不能使用这个module了,要shutdown掉 */TopService.stop(instance);moduleInstances.removeElement(module);return findModule(key, true, properties);}
这个方法有两处还需要重点的研究下,一个是BaseMonitor的#loadInstance(),它负责找到实例。
protected Object loadInstance(Class factoryInterface, Properties properties) {Object instance = null;Vector localImplementations = getImplementations(properties, false);if (localImplementations != null) {instance = loadInstance(localImplementations, factoryInterface, properties);}/* implementationSets存了前面BaseMonitor的#runWithState()方法中找到的全部实例 */for (int i = 0; i < implementationSets.length; i++) {instance = loadInstance(implementationSets[i], factoryInterface, properties);if (instance != null)break;}return instance;}private Object loadInstance(Vector implementations, Class factoryInterface, Properties properties) {for (int index = 0; true; index++) {index = findImplementation(implementations, index, factoryInterface);if (index < 0)return null;Object instance = newInstance((Class) implementations.elementAt(index));if (BaseMonitor.canSupport(instance, properties))return instance;}}private static int findImplementation(Vector implementations, int startIndex, Class factoryInterface) {for (int i = startIndex; i < implementations.size(); i++) {Class factoryClass = (Class) implementations.elementAt(i);/* 这里用#isAssignableFrom方法来匹配是否是module的实例 */if (!factoryInterface.isAssignableFrom(factoryClass)) {continue;}return i;}return -1;}
这里第二个需要关注的是BaseMonitor.boot(instance, create, properties);方法,这个方法会调用module实例的#boot()方法,
static void boot(Object module, boolean create, Properties properties) throws StandardException {if (module instanceof ModuleControl)((ModuleControl) module).boot(create, properties);}
在EmbeddedDriver的载入过程中,以最新的JDK1.6为例,对应的是JDBC4.0。JDBC module(org.apache.derby.jdbc.InternalDriver)会找到的实现类是org.apache.derby.jdbc.Driver40(这个是在module.properties中定义的)。这里BaseMonitor#boot()就会调用Driver40的boot()方法了。最后会把InternalDriver的一个内部静态变量activeDriver设定成当前找到的这个Driver40,这个代码还是很容易理解的,这里就不再列出来了。
至此,Derby的启动部分就分析完了。 |
|