在配置完2个模板引擎之后,它就开始注册索引器:
(7)注册索引器:
- // Indexers
- IndexerRegistryUtil.register(new MBIndexer());
- IndexerRegistryUtil.register(new PluginPackageIndexer());
这里看出,这里注册两种索引器,一个是为MessageBoard注册索引器,一个是为所有的PluginPackage(portlet,layout-template,theme)注册索引器,他们都实现了Indexer接口,所以它必须能完成大多数Indexer的基本操作,比如查询,排序,重建索引,删除等,因为比较简单,就不说了。
(8)数据库升级器:
- // Upgrade
- if (_log.isDebugEnabled()) {
- _log.debug("Upgrade database");
- }
- DBUpgrader.upgrade();
它会让DBUpgrader执行升级的动作,在DBUpgrader的upgrade()方法中。
首先,它禁用数据库的缓存:
- // Disable database caching before upgrade
- if (_log.isDebugEnabled()) {
- _log.debug("Disable cache registry");
- }
- CacheRegistryUtil.setActive(false);
CacheRegistryUtil的setActive()方法,最终会调用CacheRegistryImpl的setActive()方法:
- public void setActive(boolean active) {
- _active = active;
- if (!active) {
- clear();
- }
- }
当传入false值时,它会调用CacheRegistryImpl的clear()方法:
- public void clear() {
- for (Map.Entry<String, CacheRegistryItem> entry :
- _cacheRegistryItems.entrySet()) {
- CacheRegistryItem cacheRegistryItem = entry.getValue();
- if (_log.isDebugEnabled()) {
- _log.debug(
- "Invalidating " + cacheRegistryItem.getRegistryName());
- }
- cacheRegistryItem.invalidate();
- }
- }
可以看出,禁用数据库缓存的本质是是调用所有cacheRegistryItem的invalidate()方法。
当禁用完数据库缓存之后,我们可以正式开始升级数据库,我们回到DBUpgrader类的
upgrader中,它首先获取buildNumber号:
- int buildNumber = ReleaseLocalServiceUtil.getBuildNumberOrCreate();
这个版本号,ReleaseLocalServiceUtil中进行了调用封装,最终来自ReleaseLocalServiceImpl类的getBuildNumberOrCreate()方法,它会从数据库中取得buildNumber:
- public int getBuildNumberOrCreate()
- throws PortalException, SystemException {
- // Get release build number
- ..
- try {
- con = DataAccess.getConnection();
- ps = con.prepareStatement(_GET_BUILD_NUMBER);
- ps.setLong(1, ReleaseConstants.DEFAULT_ID);
- rs = ps.executeQuery();
- if (rs.next()) {
- int buildNumber = rs.getInt("buildNumber");
- if (_log.isDebugEnabled()) {
- _log.debug("Build number " + buildNumber);
- }
- testSupportsStringCaseSensitiveQuery();
- return buildNumber;
- }
- }
- catch (Exception e) {
- if (_log.isWarnEnabled()) {
- _log.warn(e.getMessage());
- }
- }
- finally {
- DataAccess.cleanUp(con, ps, rs);
- }
- // Create tables and populate with default data
- if (GetterUtil.getBoolean(
- PropsUtil.get(PropsKeys.SCHEMA_RUN_ENABLED))) {
- releaseLocalService.createTablesAndPopulate();
- testSupportsStringCaseSensitiveQuery();
- Release release = getRelease(
- ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME,
- ReleaseInfo.getBuildNumber());
- return release.getBuildNumber();
- }
- else {
- throw new NoSuchReleaseException(
- "The database needs to be populated");
- }
- }
然后它会吧这个buildNumber和服务器的releaseNumber还有5.0.0进行比较,确保数据库的版本高于5.0.0,并且不高于服务器的版本号:
- if (buildNumber > ReleaseInfo.getBuildNumber()) {
- ..
- else if (buildNumber < ReleaseInfo.RELEASE_5_0_0_BUILD_NUMBER) {
- String msg = "You must first upgrade to Liferay Portal 5.0.0";
- }
一旦数据库版本号满足 5.0.0<=DB版本号<=服务器版本号,则DB就可以进行升级了。它先重新加载SQL语句:
- // Reload SQL
- CustomSQLUtil.reloadCustomSQL();
- SQLTransformer.reloadSQLTransformer();
这2个语句对应的内容都会先判断db的方言,然后选用正确的语句执行,第二个语句,主要执行的是Hibernate的HQL和JPA的JPQL之间的转换。
然后,它还会做一系列的数据库升级动作,就不一一展开了。
(9)初始化消息总线:
- // Messaging
- if (_log.isDebugEnabled()) {
- _log.debug("Initialize message bus");
- }
- MessageBus messageBus = (MessageBus)PortalBeanLocatorUtil.locate(
- MessageBus.class.getName());
- MessageSender messageSender =
- (MessageSender)PortalBeanLocatorUtil.locate(
- MessageSender.class.getName());
- SynchronousMessageSender synchronousMessageSender =
- (SynchronousMessageSender)PortalBeanLocatorUtil.locate(
- SynchronousMessageSender.class.getName());
- MessageBusUtil.init(
- messageBus, messageSender, synchronousMessageSender);
它会向ClassLoader所要MessageBus 和 MessageSender的对象:然后执行初始化动作。
(10)初始化ClusterExecutor,其实是初始化自身的集群节点信息(因为它不能假定自己是否在一个集群环境中,所以还是吧自己的节点信息初始化之)
- // Cluster executor
- ClusterExecutorUtil.initialize();
它最终会调用ClusterExecutorImpl的initialize()方法:
- public void initialize() {
- if (!isEnabled()) {
- return;
- }
- PortalUtil.addPortalPortEventListener(this);
- _localAddress = new AddressImpl(_controlChannel.getLocalAddress());
- try {
- initLocalClusterNode();
- }
- catch (SystemException se) {
- _log.error("Unable to determine local network address", se);
- }
- ObjectValuePair<Address, ClusterNode> localInstance =
- new ObjectValuePair<Address, ClusterNode>(
- _localAddress, _localClusterNode);
- _liveInstances.put(localInstance, Long.MAX_VALUE);
- _clusterNodeAddresses.put(
- _localClusterNode.getClusterNodeId(), _localAddress);
- _clusterRequestReceiver.initialize();
- _scheduledExecutorService = Executors.newScheduledThreadPool(
- 1,
- new NamedThreadFactory(
- ClusterExecutorImpl.class.getName(), Thread.NORM_PRIORITY,
- Thread.currentThread().getContextClassLoader()));
- _scheduledExecutorService.scheduleWithFixedDelay(
- new HeartbeatTask(), 0,
- PropsValues.CLUSTER_EXECUTOR_HEARTBEAT_INTERVAL,
- TimeUnit.MILLISECONDS);
- }
就不往下展开了。
(11)初始化定时器:
- // Scheduler
- if (_log.isDebugEnabled()) {
- _log.debug("Initialize scheduler engine lifecycle");
- }
- SchedulerEngineUtil.initialize();
它会调用SchedulerEngineUtil的initialize()方法:
- public static void initialize() throws SchedulerException {
- _instance._initialize();
- SchedulerLifecycle schedulerLifecycle = new SchedulerLifecycle();
- schedulerLifecycle.registerPortalLifecycle(PortalLifecycle.METHOD_INIT);
- }
从第02行跟踪下去,会发现它仍然是和集群相关的,它会去调用ClusterSchedulerEngine的initialize()方法,进而调用initMemoryClusteredJobs()方法,这里就不展开了:
- protected void initMemoryClusteredJobs() throws Exception {
- List<SchedulerResponse> schedulerResponses =
- (List<SchedulerResponse>)callMaster(
- _getScheduledJobsMethodKey3, StorageType.MEMORY_CLUSTERED);
- for (SchedulerResponse schedulerResponse : schedulerResponses) {
- Trigger oldTrigger = schedulerResponse.getTrigger();
- String jobName = schedulerResponse.getJobName();
- String groupName = SchedulerEngineUtil.namespaceGroupName(
- schedulerResponse.getGroupName(), StorageType.MEMORY_CLUSTERED);
- Trigger newTrigger = TriggerFactoryUtil.buildTrigger(
- oldTrigger.getTriggerType(), jobName, groupName,
- oldTrigger.getStartDate(), oldTrigger.getEndDate(),
- oldTrigger.getTriggerContent());
- schedulerResponse.setTrigger(newTrigger);
- TriggerState triggerState = SchedulerEngineUtil.getJobState(
- schedulerResponse);
- Message message = schedulerResponse.getMessage();
- message.remove(JOB_STATE);
- _memoryClusteredJobs.put(
- getFullName(jobName, groupName),
- new ObjectValuePair<SchedulerResponse, TriggerState>(
- schedulerResponse, triggerState));
- }
- }