- 浏览: 243037 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
feifei435:
不错的文章,但是有一点忘了提,创建了新的sessionid后, ...
Tomcat的Session管理(一) - Session的生成 -
yangcheng33:
博主你为什么这么棒!!!
Tomcat的Session管理(一) - Session的生成 -
u010323779:
哈哈,非常不错,昨天看了一天源代码,不知从何入手,现在看来您的 ...
Tomcat的Session管理(二) - Session后台处理 -
hdwmp123:
...
Tomcat请求处理(一) -- 服务器端口监听 -
tinguo002:
...
Tomcat的Session管理(一) - Session的生成
2. 嵌入式方式
在开始这部分前,有一些必须的Derby架构的东西需要好好的了解下,可以在Derby的官方网站看一下,地址是http://db.apache.org/derby/papers/derby_arch.html
首先,Derby是由monitor和一系列的module组成的,每个module都代表了一个独立的功能,并且基接口通常是在java.sql包中定义的接口,比如JDBC驱动,锁管理等等。而monitor可以把对module的请求映射到module的具体实现上。比如JDBC驱动,monitor会把来自JDK1.3的请求转给JDBC2.0的实现,而JDK1.4的则转给JDBC3.0的实现。
对Derby的结构的描述就大致说这些吧,有兴趣的可以去官网仔细的了解下。下面转入正题,
一个应用程序和使用嵌入式方式的Derby进行连接代码通常来说是这样的:
可以先研究下Class.forName("org.apache.derby.jdbc.EmeddedDriver").newInstance();这句的初始化里都做了什么。
这个在第1部分中网络服务器方式的启动中也是有涉及的,在网络服务器方式下也载入了嵌入式的驱动,这里正好可以一并的来进行了解,
下边就是JDBCBoot类的boot()方法了,
这里就涉及到了Monitor的启动了,
这里初始化了一个FileMonitor的实例,而在FileMonitor的构造函数里会调用它的父类BaseMonitor中的runWithState()方法,这里就要正式进入重点了。
顺带说下,这个方法我用eclipse是调试不过去了,会报出各种各样的无解错误,有些地方我也不清楚是到底实现什么的。
这个方法的前半部分主要是找各个module的实现类,然后放到implementationSets这个变量中,后半部分就是module的启动了,有两个方法要重点的关注下,一个是#getImplementations(),一个是#startServices()。
首先来看getImplementations()方法,
通过这个方法,就找到了属性中定义的module实现,为了对属性的内容有个直观的了解,可以看一下modules.properties中的内容。
在开始这部分前,有一些必须的Derby架构的东西需要好好的了解下,可以在Derby的官方网站看一下,地址是http://db.apache.org/derby/papers/derby_arch.html
首先,Derby是由monitor和一系列的module组成的,每个module都代表了一个独立的功能,并且基接口通常是在java.sql包中定义的接口,比如JDBC驱动,锁管理等等。而monitor可以把对module的请求映射到module的具体实现上。比如JDBC驱动,monitor会把来自JDK1.3的请求转给JDBC2.0的实现,而JDK1.4的则转给JDBC3.0的实现。
对Derby的结构的描述就大致说这些吧,有兴趣的可以去官网仔细的了解下。下面转入正题,
一个应用程序和使用嵌入式方式的Derby进行连接代码通常来说是这样的:
try { /* 如果使用的是JDK1.6,那么嵌入式方式是不需要载入驱动的 */ Class.forName("org.apache.derby.jdbc.EmeddedDriver").newInstance(); } catch (Exception e) { throw new SQLException("初始化数据库连接失败"); } String url = "jdbc:derby:data;create=true"; conn = DriverManager.getConnection(url, "username", "password");
可以先研究下Class.forName("org.apache.derby.jdbc.EmeddedDriver").newInstance();这句的初始化里都做了什么。
这个在第1部分中网络服务器方式的启动中也是有涉及的,在网络服务器方式下也载入了嵌入式的驱动,这里正好可以一并的来进行了解,
/* 构造函数 */ public EmbeddedDriver() { EmbeddedDriver.boot(); } static void boot() { PrintStream ps = DriverManager.getLogStream(); if (ps == null) ps = System.err; /* 交给JDBCBoot去继续执行 */ new JDBCBoot().boot(Attribute.PROTOCOL, ps); }
下边就是JDBCBoot类的boot()方法了,
public void boot(String protocol, PrintStream logging) { if (org.apache.derby.jdbc.InternalDriver.activeDriver() == null) { /* InternalDriver(JDBC)和授权服务 */ addProperty("derby.service.jdbc", "org.apache.derby.jdbc.InternalDriver"); /* AuthenticationService.MODULE = org.apache.derby.iapi.jdbc.AuthenticationService */ addProperty("derby.service.authentication", AuthenticationService.MODULE); Monitor.startMonitor(bootProperties, logging); /* 启动网络模块 */ if (Boolean.valueOf(PropertyUtil.getSystemProperty(Property.START_DRDA)).booleanValue()) { try { /* NETWORK_SERVER_AUTOSTART_CLASS_NAME = org.apache.derby.iapi.jdbc.DRDAServerStarter */ Monitor.startSystemModule(NETWORK_SERVER_AUTOSTART_CLASS_NAME); } catch (StandardException se) { Monitor.logTextMessage(MessageId.CONN_NETWORK_SERVER_START_EXCEPTION, se.getMessage()); } } } }
这里就涉及到了Monitor的启动了,
public class Monitor { ...... public static void startMonitor(Properties bootProperties, PrintStream logging) { new org.apache.derby.impl.services.monitor.FileMonitor(bootProperties, logging); } ...... } public final class FileMonitor extends BaseMonitor implements java.security.PrivilegedExceptionAction { ...... public FileMonitor(java.util.Properties properties, java.io.PrintStream log) { runWithState(properties, log); } ...... }
这里初始化了一个FileMonitor的实例,而在FileMonitor的构造函数里会调用它的父类BaseMonitor中的runWithState()方法,这里就要正式进入重点了。
顺带说下,这个方法我用eclipse是调试不过去了,会报出各种各样的无解错误,有些地方我也不清楚是到底实现什么的。
protected final void runWithState(Properties properties, PrintStream log) { /* * 这里properties有两个属性: * "derby.service.jdbc", "org.apache.derby.jdbc.InternalDriver" * "derby.service.authentication", "org.apache.derby.iapi.jdbc.AuthenticationService" */ bootProperties = properties; logging = log; /* * 这里会读取org/apache/derby/info/DBMS.properties这个配置文件,Derby源代码里没有,可以下一个binary版的看一下 * ,就是一些数据库的版本之类的信息 * 然后会初始化derby.system.home属性 */ if (!initialize(false)) return; if (!Monitor.setMonitor(this)) return; Object msgService = MessageService.setFinder(this); /* 新开一个后台线程引用这个FileMonitor,还有一个Monitor实例和msgService实例,防止GC */ Object[] keepItems = new Object[3]; keepItems[0] = this; keepItems[1] = new Monitor(); keepItems[2] = msgService; dontGC = new AntiGC(keepItems); final Thread dontGCthread = getDaemonThread(dontGC, "antiGC", true); try { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { dontGCthread.setContextClassLoader(null); return null; } }); } catch (SecurityException se1) { } /* 开启后台线程 */ dontGCthread.start(); if (SanityManager.DEBUG) { reportOn = Boolean.valueOf(PropertyUtil.getSystemProperty("derby.monitor.verbose")).booleanValue(); } /* 这里要读取derby.system.home目录下的derby.properties文件,这个可以进一步控制Derby数据库引擎的操作 */ applicationProperties = readApplicationProperties(); /* 获得系统属性 */ Properties systemProperties = null; if (SanityManager.DEBUG) { try { systemProperties = System.getProperties(); } catch (SecurityException se) { } } /* 返回属性中定义的实现类,对于bootProperties中的两个属性,此处返回null */ Vector bootImplementations = getImplementations(bootProperties, false); Vector systemImplementations = null; Vector applicationImplementations = null; if (true || SanityManager.DEBUG) { // Don't allow external code to override our implementations. systemImplementations = getImplementations(systemProperties, false); applicationImplementations = getImplementations(applicationProperties, false); } /* 这里要返回org/apache/derby/modules.properties中默认的module实现 */ /* 可以看看这个文件,基本的模块对应的实现都是在这个文件中定义的 */ Vector defaultImplementations = getDefaultImplementations(); int implementationCount = 0; if (bootImplementations != null) implementationCount++; if (true || SanityManager.DEBUG) { if (systemImplementations != null) implementationCount++; if (applicationImplementations != null) implementationCount++; } if (defaultImplementations != null) implementationCount++; /* Vector数组,这个implementationSets变量很重要,载入模块对应的实现的时候会在这个Vector数组中找 */ implementationSets = new Vector[implementationCount]; /* 把前面找到的所有模块实现都放进implementationSets中 */ implementationCount = 0; if (bootImplementations != null) implementationSets[implementationCount++] = bootImplementations; if (true || SanityManager.DEBUG) { if (systemImplementations != null) implementationSets[implementationCount++] = systemImplementations; if (applicationImplementations != null) implementationSets[implementationCount++] = applicationImplementations; } if (defaultImplementations != null) implementationSets[implementationCount++] = defaultImplementations; if (SanityManager.DEBUG) { if (applicationProperties != null) { addDebugFlags(applicationProperties.getProperty(Monitor.DEBUG_FALSE), false); addDebugFlags(applicationProperties.getProperty(Monitor.DEBUG_TRUE), true); } addDebugFlags(PropertyUtil.getSystemProperty(Monitor.DEBUG_FALSE), false); addDebugFlags(PropertyUtil.getSystemProperty(Monitor.DEBUG_TRUE), true); } try { /* 这里要启动几个总是要启动的module */ systemStreams = (InfoStreams) Monitor .startSystemModule("org.apache.derby.iapi.services.stream.InfoStreams"); if (SanityManager.DEBUG) { SanityManager.SET_DEBUG_STREAM(systemStreams.stream().getPrintWriter()); } contextService = new ContextService(); uuidFactory = (UUIDFactory) Monitor.startSystemModule("org.apache.derby.iapi.services.uuid.UUIDFactory"); timerFactory = (TimerFactory) Monitor .startSystemModule("org.apache.derby.iapi.services.timer.TimerFactory"); Monitor.startSystemModule(Module.JMX); } catch (StandardException se) { reportException(se); dumpTempWriter(true); return; } dumpTempWriter(false); if (SanityManager.DEBUG && reportOn) { dumpProperties("-- Boot Properties --", bootProperties); dumpProperties("-- System Properties --", systemProperties); dumpProperties("-- Application Properties --", applicationProperties); } determineSupportedServiceProviders(); boolean bootAll = Boolean.valueOf(PropertyUtil.getSystemProperty(Property.BOOT_ALL)).booleanValue(); /* 开启"derby.service."开头的服务,这个也要仔细看一下 */ startServices(bootProperties, bootAll); startServices(systemProperties, bootAll); startServices(applicationProperties, bootAll); if (bootAll) bootPersistentServices(); }
这个方法的前半部分主要是找各个module的实现类,然后放到implementationSets这个变量中,后半部分就是module的启动了,有两个方法要重点的关注下,一个是#getImplementations(),一个是#startServices()。
首先来看getImplementations()方法,
private Vector getImplementations(Properties moduleList, boolean actualModuleList) { if (moduleList == null) return null; Vector implementations = actualModuleList ? new Vector(moduleList.size()) : new Vector(0, 1); /* 获得当前的JDK版本信息 */ int theJDKId = JVMInfo.JDK_ID; /* 如果某个module需要最低的JDK版本,记录每个JDK版本的module数量 */ int[] envModuleCount = new int[theJDKId + 1]; /* 循环处理传进来的Properties中包括的模块 */ nextModule: for (Enumeration e = moduleList.propertyNames(); e.hasMoreElements();) { /* 键值 */ String key = (String) e.nextElement(); /* module名 */ String tag; // derby.module.<modulename>=<class name> // derby.subSubProtocol.<modulename>=<classname> /* 判断键值是不是以"derby.module."或者"derby.subSubProtocol."开头,如果都不是放弃这次循环 */ if (key.startsWith(Property.MODULE_PREFIX)) { tag = key.substring(Property.MODULE_PREFIX.length()); } else if (key.startsWith(Property.SUB_SUB_PROTOCOL_PREFIX)) { tag = key.substring(Property.MODULE_PREFIX.length()); } else { continue nextModule; } /* 判断是否还同时存在名字为"derby.env.jdk."+<module name>的属性 */ /* 这个属性应该是启动这个服务所需要的最低JDK版本 */ String envKey = Property.MODULE_ENV_JDK_PREFIX.concat(tag); String envJDK = moduleList.getProperty(envKey); int envJDKId = 0; /* 这里会根据版本来确定是否继续启动 */ if (envJDK != null) { envJDKId = Integer.parseInt(envJDK.trim()); if (envJDKId > theJDKId) { continue nextModule; } } /* 判断是否还同时存在名字为"derby.env.classes."+<module name>的属性 */ /* 这个属性应该是启动这个服务所需要的其他类信息 */ envKey = Property.MODULE_ENV_CLASSES_PREFIX.concat(tag); String envClasses = moduleList.getProperty(envKey); if (envClasses != null) { StringTokenizer st = new StringTokenizer(envClasses, ","); for (; st.hasMoreTokens();) { try { /* 这里会尝试找这个类或者接口 */ Class.forName(st.nextToken().trim()); } catch (ClassNotFoundException cnfe) { continue nextModule; } catch (LinkageError le) { continue nextModule; } } } /* 获得module的类名 */ String className = moduleList.getProperty(key); if (SanityManager.DEBUG && reportOn) { report("Accessing module " + className + " to run initializers at boot time"); } try { /* 尝试载入这个类 */ Class possibleModule = Class.forName(className); /* 判断是否是某些特殊的module:PersistentService和StorageFactory */ if (getPersistentServiceImplementation(possibleModule)) continue; if (StorageFactory.class.isAssignableFrom(possibleModule)) { storageFactories.put(tag, className); continue; } if (envJDKId != 0) { /* 这里在Vector中会把需要JDK版本高的模块排在前面 */ /* 后面在载入模块实现的时候会有用处,比如保证JDK6在启动JDBC服务时会找到JDBC4的实现而不是JDBC3 */ int offset = 0; for (int eji = theJDKId; eji > envJDKId; eji--) { offset += envModuleCount[eji]; } /* 插入Vector中 */ implementations.insertElementAt(possibleModule, offset); envModuleCount[envJDKId]++; } else { /* 插入Vector中 */ implementations.addElement(possibleModule); } if (SanityManager.DEBUG) {// DEBUG的先不去关心 Class[] csParams = { new java.util.Properties().getClass() }; try { possibleModule.getMethod("canSupport", csParams); if (!ModuleSupportable.class.isAssignableFrom(possibleModule)) { SanityManager .THROWASSERT("Module does not implement ModuleSupportable but has canSupport() - " + className); } } catch (NoSuchMethodException nsme) {/* ok */ } // ModuleControl boolean eitherMethod = false; Class[] bootParams = { Boolean.TYPE, new java.util.Properties().getClass() }; try { possibleModule.getMethod("boot", bootParams); eitherMethod = true; } catch (NoSuchMethodException nsme) {/* ok */ } Class[] stopParams = {}; try { possibleModule.getMethod("stop", stopParams); eitherMethod = true; } catch (NoSuchMethodException nsme) {/* ok */ } if (eitherMethod) { if (!ModuleControl.class.isAssignableFrom(possibleModule)) { SanityManager.THROWASSERT("Module does not implement ModuleControl but has its methods - " + className); } } } } catch (ClassNotFoundException cnfe) { report("Class " + className + " " + cnfe.toString() + ", module ignored."); } catch (LinkageError le) { report("Class " + className + " " + le.toString() + ", module ignored."); } } if (implementations.isEmpty()) return null; implementations.trimToSize(); return implementations; }
通过这个方法,就找到了属性中定义的module实现,为了对属性的内容有个直观的了解,可以看一下modules.properties中的内容。
发表评论
-
Derby源代码分析 -- SQL层实现(一) -- LanguageConnectionContext
2009-10-15 10:36 4122前段时间事情太多,一直没有继续看Derby的源代码。国庆过去了 ... -
Derby源代码分析 -- JDBC实现(三)
2009-08-31 08:46 2838在开始下面的分析前,先补一下课,插播下Derby的代码结构, ... -
Derby源代码分析 -- JDBC实现(二)
2009-08-19 09:11 1966前面已经知道了对于JDBC4.0,java.sql.Conne ... -
Derby源代码分析 -- JDBC实现(一)
2009-08-02 01:28 3446谈起JDBC的实现,还是从获取Connection开始吧。 ... -
Derby源代码分析 -- 服务器启动(三)
2009-07-28 22:41 2010看过#getImplementations()之后,来看一下# ... -
Derby源代码分析 -- 服务器启动(一)
2009-07-13 13:54 3976一直以来都想研究下数据库的实现原理,Derby在我眼里绝对是一 ...
相关推荐
Apache Derby,也被称为Java DB,是一款轻量级、开源的关系型数据库管理系统,完全用Java编写,遵循Apache软件基金会的开放源代码协议。这个名为"db-derby-10.11.1.1-bin.zip"的压缩包包含了Apache Derby 10.11.1.1...
"db-derby-10.11.1.1-src.zip" 是Apache Derby的10.11.1.1版本的源代码包,对于开发者来说,这是一个宝贵的资源,可以深入了解Derby的内部工作原理和实现细节。 Apache Derby的核心特性包括: 1. **完全用Java编写...
### 源代码检查工具SONAR使用经验 #### Sonar概述 Sonar作为一个代码质量管理的开放平台,通过灵活的插件机制集成了多种测试工具、代码分析工具以及持续集成工具。与传统持续集成工具(如Hudson/Jenkins)相比,...
源代码的提供意味着用户可以查看、学习甚至修改系统的内部实现,以适应特定需求或进行二次开发。 Swing是Java的一个图形用户界面(GUI)工具包,它是Java Foundation Classes (JFC)的一部分,用于构建桌面应用。...
在本教程中,读者将了解如何下载、安装并启动Derby数据库服务器,以及如何连接到数据库并执行基本的SQL操作。 2. **MyBatis框架**:MyBatis是一个持久层框架,它允许开发者编写SQL语句,并将这些SQL语句与Java代码...
- **javadoc 子目录**:包含通过源代码注释生成的 API 文档。 - **docs 子目录**:包含 JavaDB 文档。 - **lib 子目录**:包含 JavaDB jar 文件。 3. **在 NetBeans IDE 中注册数据库**: - 在“服务”窗口中,...
用户可以直接运行这个文件启动聊天软件,而无需查看或修改源代码。"src"目录包含了项目的源代码,开发者可以研究这些代码来学习Swing和Derby的结合使用,了解如何创建GUI、处理用户输入、连接数据库以及执行数据库...
- **编辑器(Editor)**:用于编写和编辑源代码。 - **常见概念和操作**: - **项目(Project)**:一组相关文件的集合。 - **工作区(Workspace)**:存放项目的文件夹。 - **导入、导出Java项目**:便于项目...
- **CVS团队源代码管理**: 介绍如何使用CVS进行源代码管理。 - **字符编码设置**: 说明如何修改文件的字符编码。 #### 五、数据库管理 - **功能概述**: 概述MyEclipse Database Explorer的主要功能。 - **透视图...
- **手工和自动编译**:手动或自动编译 Java 源代码。 - **直接粘贴 Java 源码为类文件**:直接粘贴代码生成文件。 - **复制项目中的文件**:复制文件到其他位置。 - **断点和调试器**:设置断点进行调试。 - **快速...
oozie-4.3.1目录下包含了Oozie的源代码、构建脚本、文档和配置文件等。主要目录结构如下: - `src/main`:存放主要的源代码,包括Java类和XML配置文件。 - `src/test`:包含单元测试代码。 - `build.xml`:Ant构建...