openfire源码分析—3
接着openfire源码分析2中的XMPPServer的start()函数,如下所示
...
if (!setupMode) {
verifyDataSource();
// First load all the modules so that modules may access other modules while
// being initialized
loadModules();
// Initize all the modules
initModules();
// Start all the modules
startModules();
}
...
verifyDataSource用来验证数据库,loadModules、initModules和startModules三个函数分别调用每个模块的构造函数、initialize函数和start函数。
verifyDataSource
private void verifyDataSource() {
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = DbConnectionManager.getConnection();
pstmt = con.prepareStatement("SELECT count(*) FROM ofID");
rs = pstmt.executeQuery();
rs.next();
}
catch (Exception e) {
System.err.println("Database setup or configuration error: " +
"Please verify your database settings and check the " +
"logs/error.log file for detailed error messages.");
logger.error("Database could not be accessed", e);
throw new IllegalArgumentException(e);
}
finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
}
这里简单说就是通过执行一个简单的SQL语句判断是否开启了数据库服务。
loadModules
private void loadModules() {
// Load boot modules
loadModule(RoutingTableImpl.class.getName());
loadModule(AuditManagerImpl.class.getName());
loadModule(RosterManager.class.getName());
loadModule(PrivateStorage.class.getName());
// Load core modules
loadModule(PresenceManagerImpl.class.getName());
loadModule(SessionManager.class.getName());
loadModule(PacketRouterImpl.class.getName());
loadModule(IQRouter.class.getName());
loadModule(MessageRouter.class.getName());
loadModule(PresenceRouter.class.getName());
loadModule(MulticastRouter.class.getName());
loadModule(PacketTransporterImpl.class.getName());
loadModule(PacketDelivererImpl.class.getName());
loadModule(TransportHandler.class.getName());
loadModule(OfflineMessageStrategy.class.getName());
loadModule(OfflineMessageStore.class.getName());
loadModule(VCardManager.class.getName());
// Load standard modules
loadModule(IQBindHandler.class.getName());
loadModule(IQSessionEstablishmentHandler.class.getName());
loadModule(IQAuthHandler.class.getName());
loadModule(IQPingHandler.class.getName());
loadModule(IQPrivateHandler.class.getName());
loadModule(IQRegisterHandler.class.getName());
loadModule(IQRosterHandler.class.getName());
loadModule(IQTimeHandler.class.getName());
loadModule(IQEntityTimeHandler.class.getName());
loadModule(IQvCardHandler.class.getName());
loadModule(IQVersionHandler.class.getName());
loadModule(IQLastActivityHandler.class.getName());
loadModule(PresenceSubscribeHandler.class.getName());
loadModule(PresenceUpdateHandler.class.getName());
loadModule(IQOfflineMessagesHandler.class.getName());
loadModule(IQPEPHandler.class.getName());
loadModule(IQPEPOwnerHandler.class.getName());
loadModule(MulticastDNSService.class.getName());
loadModule(IQSharedGroupHandler.class.getName());
loadModule(AdHocCommandHandler.class.getName());
loadModule(IQPrivacyHandler.class.getName());
loadModule(DefaultFileTransferManager.class.getName());
loadModule(FileTransferProxy.class.getName());
loadModule(MediaProxyService.class.getName());
loadModule(PubSubModule.class.getName());
loadModule(IQDiscoInfoHandler.class.getName());
loadModule(IQDiscoItemsHandler.class.getName());
loadModule(UpdateManager.class.getName());
loadModule(FlashCrossDomainHandler.class.getName());
loadModule(InternalComponentManager.class.getName());
loadModule(MultiUserChatManager.class.getName());
loadModule(ClearspaceManager.class.getName());
loadModule(IQMessageCarbonsHandler.class.getName());
// Load this module always last since we don't want to start listening for clients
// before the rest of the modules have been started
loadModule(ConnectionManagerImpl.class.getName());
// Keep a reference to the internal component manager
componentManager = getComponentManager();
}
这里对每个模块调用loadModule,
private void loadModule(String module) {
try {
Class modClass = loader.loadClass(module);
Module mod = (Module) modClass.newInstance();
this.modules.put(modClass, mod);
}
catch (Exception e) {
e.printStackTrace();
logger.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
因此这里就是实例化每个模块(调用其中的构造函数),并把模块放进一个LinkedHashMap(modules)中。
initModules
private void initModules() {
for (Module module : modules.values()) {
boolean isInitialized = false;
try {
module.initialize(this);
isInitialized = true;
}
catch (Exception e) {
e.printStackTrace();
// Remove the failed initialized module
this.modules.remove(module.getClass());
if (isInitialized) {
module.stop();
module.destroy();
}
logger.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
}
这里就是依次调用每个模块的initialize函数。
startModules
private void startModules() {
for (Module module : modules.values()) {
boolean started = false;
try {
module.start();
}
catch (Exception e) {
if (started && module != null) {
module.stop();
module.destroy();
}
logger.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
}
和initModules一样,这里就是调用每个模块的start函数。
到这里,每个模块的功能可以先按照模块名称了解其意思,在后面的分析中,会慢慢的讲到这些模块各自的作用。下一章会首先重点分析其中的一个模块ConnectionManagerImpl,这个模块和Socket的连接、收发数据有关。