`
qinwei6060
  • 浏览: 6821 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类
最新评论

Jforum启动

    博客分类:
  • Java
阅读更多
启动:
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);
		}
	}
}
分享到:
评论

相关推荐

    JForum3 jforum java 开源论坛 论坛

    JForum3 jforum java 开源论坛 论坛

    JForum论坛数据库表结构.rar

    1、附件关系表JFORUM_ATTACH 2 2、附件详细信息表JFORUM_ATTACH_DESC 2 3、附件配置限定关系表JFORUM_ATTACH_QUOTA 2 4、封锁表JFORUM_BANLIST 2 5、标识表JFORUM_BANNER 3 6、书签表JFORUM_BOOKMARKS 3 7、...

    jforum3.0所需要的jar包

    jforum3.0所需要的jar包

    jforum功能说明

    JForum是著名的开源论坛,支持多达数十种的多国语言,其中包括简体中文。JForum功能强大,界面美观,加上代码结构清晰,而且采用的是BSD授权,不必担心不必要的版权纠纷。可以说JForum是论坛二次开发的绝佳选择。 ...

    Jforum数据库

    JForum - Java论坛系统 数据库表结构,如:附件关系表JFORUM_ATTACH,附件详细信息表JFORUM_ATTACH_DESC,用户分组表JFORUM_GROUPS等表结构说明,如帖子表JFORUM_POSTS说明: 名称 字段名 字段类型 字段说明 帖子...

    Jforum论坛数据库架构

    Jforum论坛数据库架构Jforum论坛数据库架构

    jforum漏洞利用源代码

    jforum漏洞利用源代码

    jforum开源的论坛文档

    jforum开源的论坛文档jforum开源的论坛文档jforum开源的论坛文档

    JForum3 完整项目

    jforum 完整源代码,从svn上 导出 没有任何修改

    JForum数据库ER图

    JForum 开源论坛系统的 数据库ER图,很详细。

    JForum2.6.2.rar

    1、包含jforum2.6.2的war包、源码包 2、war包可直接放在tomcat的webapps目录下 3、2.6.2版本里面自带汉化功能,在http://localhost:8080/jforum/install.jsp安装时,注意选择中文

    JForum 2.1.9 源码包.zip

    JForum 是采用Java开发的功能强大且稳定的论坛系统。它提供了抽象的接口、高效的论坛引擎以及易于使用的管理界面,同时具有完全的权限控制、多语言支持(包括中文)、高性能、可自定义的用户接口、安全、支持多...

    jforum说明文档 源码解析 单点登录 jforum缓存

    jforum的开发文档,以及源码解析 数据库 重要配置文件和包,缓存 权限控制 单点登录

    jforum安装部署指南

    jforum安装部署指南:修改对应的数据库文件JFORUM\WEB-INF\config\database下面。例如:mysql.properties修改其中的数据库信息

    jforum3源代码 数据库

    jforum3源代码数据库

    jforum论坛图片资源

    用于配置中文jforum,里面包含各种语言的图片文件,将其中的zh_CN目录复制到jforum安装目录下的templates\default\images。就可以显示中文图片

    JForum_SSO_-_JForum单点登陆原理与配置

    对于我们已有的WEB应用中的用户,若该用户已经登陆,并通过 联结迁移到JForum页面时,JForum要能够识别该用户已经登陆(不需要二次登陆)才不会让用户感到别扭(对用户来说,就好像使用的是同一个系统似的)。...

    Jforum二次开发成果

    Jforum二次开发成果 Jforum 二次开发 eclipse 给予JForum 2.1.8开发的一个小论坛。 增加了很多功能。(子论坛、主页、热门帖子、推荐帖子等)

    jforum+ckeditor整合案例

    jforum与ckeditor整合,替换自带的编辑器

    jforum 源码

    JForum 开源代码,是很好的freeMaker学习素材。

Global site tag (gtag.js) - Google Analytics