- 浏览: 6933 次
- 性别:
- 来自: 南京
最新评论
启动:
net.jforum.JForum.java是核心Servlet,启动方法:
对文件的加载大体都在这个类里:net.jforum.ConfigLoader,分析一下文件修改的监听:
文件修改监听器net.jforum.util.FileMonitor:
论坛启动:net.jforum.ForumStartup
net.jforum.JForum.java是核心Servlet,启动方法:
public class JForum extends JForumBaseServlet { public void init(ServletConfig config) throws ServletException{ //调用父类JForumBaseServlet的init方法初始化 super.init(config); super.startApplication(); //根据配置文件实例化DBConnection的具体类,并初始化数据源 // Start database isDatabaseUp = ForumStartup.startDatabase(); try { Connection conn = DBConnection.getImplementation().getConnection(); conn.setAutoCommit(!SystemGlobals.getBoolValue(ConfigKeys.DATABASE_USE_TRANSACTIONS)); //解决MYSQL的问题,确定MYSQL版本,根据版本调整具体使用的JFORUM的MYSQL数据库驱动 // Try to fix some MySQL problems MySQLVersionWorkarounder dw = new MySQLVersionWorkarounder(); dw.handleWorkarounds(conn); //每个线程一个JForumExecutionContext // Continues loading the forum JForumExecutionContext ex = JForumExecutionContext.get(); ex.setConnection(conn); JForumExecutionContext.set(ex); //初始化缓存 //将论坛目录,论坛,最多在线用户数,用户数量,最近注册用户等信息放到缓存中 // Init general forum stuff ForumStartup.startForumRepository(); RankingRepository.loadRanks(); SmiliesRepository.loadSmilies(); BanlistRepository.loadBanlist(); } catch (Throwable e) { e.printStackTrace(); throw new ForumStartupException("Error while starting jforum", e); } finally { //启动完毕释放资源 JForumExecutionContext.finish(); } } }
public class JForumBaseServlet extends HttpServlet { private static Logger logger = Logger.getLogger(JForumBaseServlet.class); protected boolean debug; protected void startApplication() { try { //加载通用的SQL语句 SystemGlobals.loadQueries(SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_GENERIC)); //加载对于某一种数据库的驱动(专属某一库的SQL)相同的key将覆盖通用SQL中的值(properties.put) SystemGlobals.loadQueries(SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_DRIVER)); //获取quartz配置文件名 String filename = SystemGlobals.getValue(ConfigKeys.QUARTZ_CONFIG); //根据quartz配置文件路径加载quartz配置 SystemGlobals.loadAdditionalDefaults(filename); //生成用户认证类(net.jforum.sso.LoginAuthenticator)放到全局map(SystemGlobals.objectProperties)中默认的实现类是:net.jforum.sso.DefaultLoginAuthenticator,不是SSO ConfigLoader.createLoginAuthenticator(); // 加载net.jforum.dao.DataAccessDriver并初始化,具体的实现类在系统安装时生成的jforum-custom.conf文件中 ConfigLoader.loadDaoImplementation(); //监听文件修改(见下面对FileMonitor.java的分析) ConfigLoader.listenForChanges(); //初始化SearchFacade,被代理给SearchManager具体实现类在SystemGlobals.properties中配置,默认实现是net.jforum.search.LuceneManager ConfigLoader.startSearchIndexer(); //调度发送邮件 ConfigLoader.startSummaryJob(); } catch (Exception e) { throw new ForumStartupException("Error while starting JForum", e); } } public void init(ServletConfig config) throws ServletException { super.init(config); try { String appPath = config.getServletContext().getRealPath(""); debug = "true".equals(config.getInitParameter("development")); //初始化LOG4J DOMConfigurator.configure(appPath + "/WEB-INF/log4j.xml"); logger.info("Starting JForum. Debug mode is " + debug); //加载配置文件,在从配置文件中取值时遇到${}格式的会被当作变量进行扩展,与许多脚本语言类似 ConfigLoader.startSystemglobals(appPath); //启动缓存引擎 ConfigLoader.startCacheEngine(); //配置freemarker引擎 // Configure the template engine Configuration templateCfg = new Configuration(); templateCfg.setTemplateUpdateDelay(2); templateCfg.setSetting("number_format", "#"); templateCfg.setSharedVariable("startupTime", new Long(new Date().getTime())); //配置freemarker模板的加载目录 // Create the default template loader String defaultPath = SystemGlobals.getApplicationPath() + "/templates"; FileTemplateLoader defaultLoader = new FileTemplateLoader(new File(defaultPath)); String extraTemplatePath = SystemGlobals.getValue(ConfigKeys.FREEMARKER_EXTRA_TEMPLATE_PATH); if (StringUtils.isNotBlank(extraTemplatePath)) { // An extra template path is configured, we need a MultiTemplateLoader FileTemplateLoader extraLoader = new FileTemplateLoader(new File(extraTemplatePath)); TemplateLoader[] loaders = new TemplateLoader[] { extraLoader, defaultLoader }; MultiTemplateLoader multiLoader = new MultiTemplateLoader(loaders); templateCfg.setTemplateLoader(multiLoader); } else { // An extra template path is not configured, we only need the default loader templateCfg.setTemplateLoader(defaultLoader); } ModulesRepository.init(SystemGlobals.getValue(ConfigKeys.CONFIG_DIR)); this.loadConfigStuff(); if (!this.debug) { templateCfg.setTemplateUpdateDelay(3600); } //将模板的配置放到net.jforum.JForumExecutionContext JForumExecutionContext.setTemplateConfig(templateCfg); } catch (Exception e) { throw new ForumStartupException("Error while starting JForum", e); } } protected void loadConfigStuff() { //加载urlPattern.properties文件 ConfigLoader.loadUrlPatterns(); //加载i18n文件 I18n.load(); //加载templatesMapping.properties文件,供freemarker使用 Tpl.load(SystemGlobals.getValue(ConfigKeys.TEMPLATES_MAPPING)); // BB Code BBCodeRepository.setBBCollection(new BBCodeHandler().parse()); } }
对文件的加载大体都在这个类里:net.jforum.ConfigLoader,分析一下文件修改的监听:
public class ConfigLoader { public static void listenForChanges() { int fileChangesDelay = SystemGlobals.getIntValue(ConfigKeys.FILECHANGES_DELAY); if (fileChangesDelay > 0) { //这里用了单例和观察者模式,临听通用SQL语句配置文件的修改 // Queries FileMonitor.getInstance().addFileChangeListener(new QueriesFileListener(), SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_GENERIC), fileChangesDelay); //监听对某种数据库的SQL配置文件修改 FileMonitor.getInstance().addFileChangeListener(new QueriesFileListener(), SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_DRIVER), fileChangesDelay); //监听SystemGlobals.properties的修改 // System Properties FileMonitor.getInstance().addFileChangeListener(new SystemGlobalsListener(), SystemGlobals.getValue(ConfigKeys.DEFAULT_CONFIG), fileChangesDelay); ConfigLoader.listenInstallationConfig(); } } }
文件修改监听器net.jforum.util.FileMonitor:
public class FileMonitor { private static Logger logger = Logger.getLogger(FileMonitor.class); private static final FileMonitor instance = new FileMonitor(); private Timer timer; private Map timerEntries; private FileMonitor() { this.timerEntries = new HashMap(); this.timer = new Timer(true); } public static FileMonitor getInstance() { return instance; } public void addFileChangeListener(FileChangeListener listener, String filename, long period) { this.removeFileChangeListener(filename); logger.info("Watching " + filename); //通过JDK的TimerTask实现 FileMonitorTask task = new FileMonitorTask(listener, filename); this.timerEntries.put(filename, task); //定时调度 this.timer.schedule(task, period, period); } public void removeFileChangeListener(String filename) { FileMonitorTask task = (FileMonitorTask)this.timerEntries.remove(filename); if (task != null) { task.cancel(); } } //继承TimerTask private static class FileMonitorTask extends TimerTask { private FileChangeListener listener; private String filename; private File monitoredFile; private long lastModified; public FileMonitorTask(FileChangeListener listener, String filename) { this.listener = listener; this.filename = filename; this.monitoredFile = new File(filename); if (!this.monitoredFile.exists()) { return; } this.lastModified = this.monitoredFile.lastModified(); } public void run() { long latestChange = this.monitoredFile.lastModified(); //判断是否修改 if (this.lastModified != latestChange) { this.lastModified = latestChange; //修改触发事件 this.listener.fileChanged(this.filename); } } } }搜索:net.jforum.search.LuceneManager
public class LuceneManager implements SearchManager { private LuceneSearch search; private LuceneSettings settings; private LuceneIndexer indexer; /** * @see net.jforum.search.SearchManager#init() */ public void init() { try { //分词器根据配置文件中的配置实例化具体的分词器,配置文件中默认分词器:org.apache.lucene.analysis.standard.StandardAnalyzer Analyzer analyzer = (Analyzer)Class.forName(SystemGlobals.getValue( ConfigKeys.LUCENE_ANALYZER)).newInstance(); this.settings = new LuceneSettings(analyzer); //根据配置文件确定索引目录 this.settings.useFSDirectory(SystemGlobals.getValue(ConfigKeys.LUCENE_INDEX_WRITE_PATH)); this.removeLockFile(); this.indexer = new LuceneIndexer(this.settings); this.search = new LuceneSearch(this.settings, new LuceneContentCollector(this.settings)); this.indexer.watchNewDocuDocumentAdded(this.search); //将搜索配置放到全局对象中 SystemGlobals.setObjectValue(ConfigKeys.LUCENE_SETTINGS, this.settings); } catch (Exception e) { throw new ForumException(e); } } public LuceneSearch luceneSearch() { return this.search; } public LuceneIndexer luceneIndexer() { return this.indexer; } public void removeLockFile() { try { if (IndexReader.isLocked(this.settings.directory())) { IndexReader.unlock(this.settings.directory()); } } catch (IOException e) { throw new ForumException(e); } } /** * @see net.jforum.search.SearchManager#create(net.jforum.entities.Post) */ public void create(Post post) { this.indexer.create(post); } /** * @see net.jforum.search.SearchManager#update(net.jforum.entities.Post) */ public void update(Post post) { this.indexer.update(post); } /** * @see net.jforum.search.SearchManager#search(net.jforum.search.SearchArgs) */ public SearchResult search(SearchArgs args) { return this.search.search(args); } /** * @see net.jforum.search.SearchManager#delete(net.jforum.entities.Post) */ public void delete(Post p) { this.indexer.delete(p); } }
论坛启动:net.jforum.ForumStartup
public class ForumStartup { private static final Logger log = Logger.getLogger(ForumStartup.class); /** * Starts the database implementation * @return <code>true</code> if everthing were ok * @throws DatabaseException if something were wrong */ public static boolean startDatabase() { try { if (DBConnection.createInstance()) { DBConnection.getImplementation().init(); // Check if we're in fact up and running Connection conn = DBConnection.getImplementation().getConnection(); DBConnection.getImplementation().releaseConnection(conn); } } catch (Exception e) { throw new DatabaseException("Error while trying to start the database: " + e, e); } return true; } /** * Starts the cache control for forums and categories. * @throws RepositoryStartupException is something were wrong. */ public static void startForumRepository() { try { //使用单例 ForumDAO fm = DataAccessDriver.getInstance().newForumDAO(); CategoryDAO cm = DataAccessDriver.getInstance().newCategoryDAO(); ConfigDAO configModel = DataAccessDriver.getInstance().newConfigDAO(); //将论坛目录,论坛,最多在线用户数,用户数量,最近注册用户等信息放到缓存中 ForumRepository.start(fm, cm, configModel); } catch (Exception e) { log.error("Unable to bootstrap JForum repository.", e); throw new RepositoryStartupException("Error while trying to start ForumRepository: " + e, e); } } }
相关推荐
初始化流程是Jforum启动时执行的一系列操作,如加载配置、初始化核心组件、注册监听器等。这个过程保证了论坛在启动后能正确地提供服务。开发者可以通过跟踪源代码或日志来理解这一过程,以便在出现问题时快速定位...
《深入解析jforum3.0所需jar包》 在Java Web开发领域,...开发者通常会将这些jar包放在WEB-INF/lib目录下,以便Web服务器在启动时自动加载。理解这些jar包的作用和功能,有助于我们更好地理解和维护jForum3.0应用。
具体的配置步骤可能涉及修改`forum.properties`或其他相关配置文件,确保JForum在启动时加载并使用自定义的SSO实现。 通过以上步骤,JForum就可以识别已登录主应用的用户,从而实现单点登录。这种方式简化了用户在...
然后,启动服务器,如果一切配置正确,JForum应该可以正常运行。 10. **安全性与权限**:在实际部署中,确保对JForum进行了适当的权限和安全配置,以防止未授权访问和潜在的安全漏洞。 11. **测试与调试**:部署后...
运行服务器,如果配置正确,Jforum应该可以在指定端口上启动。 5. **调试与优化**:使用MyEclipse的调试工具进行代码调试,检查和修复可能出现的问题。根据性能监控结果进行必要的优化,如调整缓存策略、数据库查询...
下载JForum3源码后,使用构建工具导入项目,配置好数据库连接,即可启动服务器进行测试和开发。 总结来说,JForum3是一个成熟的Java论坛解决方案,它的完整源代码对于Java Web开发者来说是一个宝贵的资源,无论是...
4. 启动Tomcat,访问JForum的安装页面,根据提示完成论坛的初始化设置。 5. 版面设计:根据需求设计论坛的版块,可以创建多个版块并分配不同的权限。 6. 用户管理:设置用户分组,如管理员、版主和普通用户,定义...
然后,启动Tomcat服务器,JForum会自动解压并部署。访问`http://localhost:8080/jforum`(假设Tomcat默认端口为8080),如果出现JForum的安装向导页面,说明部署成功。 在安装向导中,你需要配置数据库连接信息,...
5. **部署应用**:将WAR文件部署到Web服务器的应用目录下,启动服务器完成部署。 6. **初始化数据**:访问安装URL,按照向导完成论坛的初始化设置,如管理员账户、默认板块等。 7. **运行论坛**:安装完成后,通过...
6. **启动应用服务**:通过命令行或IDE启动jForum应用程序。 7. **访问首页**:在浏览器中输入http://localhost:8080/jforum即可看到论坛首页。 #### 五、常见问题解答 1. **如何解决安装过程中的错误提示?** - ...
启动Tomcat服务器,浏览器访问`http://localhost:8080/jforum`(假设Tomcat默认端口为8080),你应该能看到jForum的欢迎页面。通过注册新用户或使用管理员账号登录,你可以开始体验并管理你的论坛。 通过以上步骤...
4. **运行与安装**:将WAR文件部署到Tomcat或其他Servlet容器,启动后访问`install`目录进行初始设置,包括创建数据库表、设置管理员账户等。 5. **升级与维护**:若已有旧版本JForum,需按照官方文档进行数据迁移...
2. **启动Tomcat**:启动Tomcat服务。 3. **访问安装页面**:通过浏览器访问`http://127.0.0.1:8080/jforum/install.jsp`,按照提示填写相关信息。 - **数据库编码**:选择`UTF-8`。 - **数据库名称**:与步骤3.1...
5. 运行:点击运行,Eclipse将启动服务器并加载JForum应用,通过浏览器访问`http://localhost:8080/jforum`即可查看和使用论坛。 四、JForum核心组件与技术 1. **Struts框架**:JForum采用Struts作为MVC框架,处理...
完成这些步骤后,就可以启动论坛并进行基本设置了。 5. **社区与开发** JForum有一个活跃的开发者社区,提供技术支持和插件开发,不断推动软件的更新和完善。此外,JForum的源代码开放,允许开发者进行二次开发,...
4. **启动服务器**:如果服务器未运行,启动它。当Tomcat检测到新的WAR文件时,它会自动解压文件并创建对应的Web应用目录。 5. **数据库配置**:JForum需要连接到一个数据库来存储论坛数据。根据你的需求,可以是...
该文件用于设置MySQL服务器的启动参数,包括端口号、最大连接数、日志设置等。了解这些参数对于优化数据库性能至关重要。 JForum的数据访问层(DAO)通常使用Hibernate框架,它简化了Java与数据库之间的交互。...