您的位置:首页 > Web前端

Liferay 启动过程分析3-处理启动事件(第三部分)

2012-06-22 16:49 429 查看
在配置完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));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息