在配置完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
_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");
_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
_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));
本文轉自 charles_wang888 51CTO部落格,原文連結:http://blog.51cto.com/supercharles888/905946,如需轉載請自行聯系原作者