Roller在初始化时候,主要做:
getPropertiesManager().initialize(); // Manages global properties for Roller. getThemeManager().initialize(); // Manager interface for accessing Theme related objects. getThreadManager().initialize(); // Thread management for executing scheduled and asynchronous tasks. getIndexManager().initialize(); // Lucene implementation fo IndexManager
PropertiesManager:
这个类好像除了保存配置外,没有其他作用
PropertiesManager的初始化过程:
初始化过程:
/** * @inheritDoc */ public void initialize() throws InitializationException { Map props = null; try { props = this.getProperties(); // 从表:roller_properties: 通过 strategy.getNamedQuery("RuntimeConfigProperty.getAll") JPA的命名查询, // 在persistence.xml文件中加载的org/apache/roller/planet/pojos/RuntimeConfigProperty.orm.xml中定义 // 以下2句一样的,为什么区分开? // 作用:将本地配置中和从数据库中读取的属性设置对比一下,如果数据库中没有配置,就加上 // 本地的配置文件为: /org/apache/roller/weblogger/config/runtimeConfigDefs.xml if(props.size() < 1) { // empty props table ... load defaults props = initializeMissingProps(props); } else { // found existing props ... check for new props props = initializeMissingProps(props); } // 把这些Property配置,都持久化 // save our changes this.saveProperties(props); } catch (Exception e) { log.fatal("Failed to initialize runtime configuration properties."+ "Please check that the database has been upgraded!", e); throw new RuntimeException(e); } }
ThemeManagerImpl
ThemeManagerImpl 使用的是: org.apache.roller.weblogger.business.themes 中的 ThemeManagerImpl
这个类的初始化,非常简单,就是加载磁盘上的Theme。
public void initialize() throws InitializationException { log.debug("Initializing Theme Manager"); if(themeDir != null) { // rather than be lazy we are going to load all themes from // the disk preemptively and cache them this.themes = loadAllThemesFromDisk(); log.info("Loaded "+this.themes.size()+" themes from disk."); } }
加载磁盘上的Theme,还有一个内部类:FilenameFilter
加载的Theme,从WebloggerConfig.getProperty("themes.dir") 中加载(初始化时候,在servletContext.getRealPath("/")+File.separator+"themes" 目录)
每个Theme文件,生成一个SharedThemeFromDir类。
JPAThreadManagerImpl
JPAThreadManagerImpl 在 org.apache.roller.weblogger.business.runnable.ThreadManagerImpl 基础上,增加了一个由数据库管理的锁定机制。ThreadManagerImpl 实现了 Interface ThreadManager。
在ThreadManager中,主要有2类线程:
// our own scheduler thread 定时线程 private Thread schedulerThread = null; // a simple thread executor 一个线程池 serviceScheduler = Executors.newCachedThreadPool(); private final ExecutorService serviceScheduler;
在initlialize中,主要完成:
对线程的初始化,每种线程在数据库保留一个锁。
通过配置文件中的 tasks.enabled , 设置需要哪几类线程
系统的缺省配置为:
tasks.enabled=ScheduledEntriesTask,ResetHitCountsTask,TurnoverReferersTask,PingQueueTask
ScheduledEntriesTask:
继承 RollerTaskwithLeasing --> 继承 RollerTask ---> 实现Runnable接口;
如果publication时间到了,进行定时出示weblog entries进入到Published status
ResetHitCountsTask:
继承 RollerTaskwithLeasing --> 继承 RollerTask ---> 实现Runnable接口;
重置weblog hit counts (点击数量)
TurnoverReferersTask:
继承 RollerTaskwithLeasing --> 继承 RollerTask ---> 实现Runnable接口;
Reset referer counts : 重置引用数量
PingQueueTask:
继承 RollerTaskwithLeasing --> 继承 RollerTask ---> 实现Runnable接口;
定时处理ping queue,在context 初始化的时候进行设置(由org.apache.roller.weblogger.ui.core.RollerContext)
目前队列间隔时间只在 org.apache.roller.weblooger.config.Pingconfig启动的时候进行设置
-----------------------------------------------
以上4个线程都放在一个List<RollerTask>中,然后被TaskScheduler包装后,放入到schedulerThread中,
public void initialize() throws InitializationException { // initialize tasks, making sure that each task has a tasklock record in the db List<RollerTask> webloggerTasks = new ArrayList<RollerTask>(); String tasksStr = WebloggerConfig.getProperty("tasks.enabled"); /* 现在实际的配置情况如下: # Tasks which are enabled. Only tasks listed here will be run. tasks.enabled=ScheduledEntriesTask,ResetHitCountsTask,TurnoverReferersTask,PingQueueTask */ // 按照逗号,进行分割 String[] tasks = StringUtils.stripAll(StringUtils.split(tasksStr, ",")); for ( String taskName : tasks ) { // 每个Task,具体有哪个类处理,也都是从配置文件中获取 String taskClassName = WebloggerConfig.getProperty("tasks."+taskName+".class"); if(taskClassName != null) { log.info("Initializing task: "+taskName); try { // 得到类的实例 Class taskClass = Class.forName(taskClassName); RollerTask task = (RollerTask) taskClass.newInstance(); task.init(); // make sure there is a tasklock record in the db // 每个线程,都在数据库中保存一个lock TaskLock taskLock = getTaskLockByName(task.getName()); if (taskLock == null) { log.debug("Task record does not exist, inserting empty record to start with"); // insert an empty record taskLock = new TaskLock(); taskLock.setName(task.getName()); taskLock.setLastRun(new Date(0)); taskLock.setTimeAquired(new Date(0)); taskLock.setTimeLeased(0); // save it this.saveTaskLock(taskLock); } // add it to the list of configured tasks webloggerTasks.add(task); } catch (ClassCastException ex) { log.warn("Task does not extend RollerTask class", ex); } catch (WebloggerException ex) { log.error("Error scheduling task", ex); } catch (Exception ex) { log.error("Error instantiating task", ex); } } } // create scheduler TaskScheduler scheduler = new TaskScheduler(webloggerTasks); // start scheduler thread, but only if it's not already running if (schedulerThread == null && scheduler != null) { log.debug("Starting scheduler thread"); schedulerThread = new Thread(scheduler, "Roller Weblogger Task Scheduler"); // set thread priority between MAX and NORM so we get slightly preferential treatment schedulerThread.setPriority((Thread.MAX_PRIORITY + Thread.NORM_PRIORITY)/2); schedulerThread.start(); } }