阅读77 返回首页    go iPhone_iPad_Mac_apple


Alfresco 2.0 解读

Alfresco 2.0 解读
 
https://www.alfresco.com
Alfresco is the Open Source Alternative for Enterprise Content Management (ECM), providing Document Management, Collaboration, Records Management, Knowledge Management, Web Content Management and Imaging.
 
采用的技术
Java
Spring Aspect-Oriented Framework
ACEGI – Aspect-Oriented Security Framework
MyFaces JSF Implementation
Hibernate ORM Persistence
Lucene Text Search Engine
JLAN
POI File Format Conversion
PDFBox – PDF Conversion
OpenOffice
jBPM
Rhino JavaScript engine
支持的接口
CIFS/SMB Microsoft File Share Protocol
JSR-168 Portlet Specification
JSR-127 Java Server Faces
FTP
WebDAV
Web Services
REST
更多的技术规范详见: https://www.alfresco.com/products/ecm/specifications/
 

1、从web.xml开始入手
其它的略过,在 web.xml 中可以看到加载了如下 Spring 配置文件
<context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
     classpath:alfresco/web-client-application-context.xml
     classpath:web-services-application-context.xml
     classpath:alfresco/web-api-application-context.xml
     classpath:alfresco/application-context.xml
 </param-value>
            <description>Spring config file locations</description>
</context-param>
alfresco/web-client-application-context.xml
打开它可以看到它引入了所有的 alfresco/web-client*.xml & alfresco/extension/web-client*.xml & jar:*!/META-INF/web-client*.xml
alfresco/web-api-application-context.xml
打开它可以看到它引入了 alfresco/web-api-config.xml & alfresco/extension/web-api-config-custom.xml
web-services-application-context.xml
刚开始找这个文件时,居然没有找到,怪事!not exist???why?
于是后来才发现这个文件是在 remote-api.jar 包里,晕,不是很好的做法啊。
bean 配置定义关键的文件
    <import resource="classpath:alfresco/core-services-context.xml"/>
    <import resource="classpath:alfresco/public-services-context.xml"/>
    <import resource="classpath:alfresco/model-specific-services-context.xml"/>
    <import resource="classpath:alfresco/action-services-context.xml"/>
    <import resource="classpath:alfresco/rule-services-context.xml"/>
    <import resource="classpath:alfresco/node-services-context.xml"/>
    <import resource="classpath:alfresco/scheduled-jobs-context.xml"/>
    <import resource="classpath:alfresco/network-protocol-context.xml"/>
    <import resource="classpath:alfresco/content-services-context.xml"/>
    <import resource="classpath:alfresco/hibernate-context.xml"/>
    <import resource="classpath:alfresco/ownable-services-context.xml"/>
    <import resource="classpath:alfresco/template-services-context.xml"/>
    <import resource="classpath:alfresco/script-services-context.xml"/>
    <import resource="classpath:alfresco/index-recovery-context.xml"/>
    <import resource="classpath:alfresco/authority-services-context.xml"/>
    <import resource="classpath:alfresco/authentication-services-context.xml"/>
    <import resource="classpath:alfresco/policy-context.xml"/>
    <import resource="classpath:alfresco/import-export-context.xml"/>
    <import resource="classpath:alfresco/bootstrap-context.xml"/>
    <import resource="classpath:alfresco/workflow-context.xml"/>
    <import resource="classpath:alfresco/jcr-api-context.xml"/>
    <import resource="classpath:alfresco/avm-services-context.xml"/>
    <import resource="classpath:alfresco/audit-services-context.xml"/>
    <import resource="classpath*:alfresco/patch/*-context.xml"/>
    <import resource="classpath*:alfresco/domain/*-context.xml"/>
 
    <!--
         Import all modules and related components.
         Extensions are explicitly imported after this so that the default
         mechanism can still be used to override module-specific beans.
    -->
    <import resource="classpath*:alfresco/module-context.xml"/>
 
    <!--
         Import of general extensions and bean overrides.
 
         To give developers final control over the tuning
         of their own local build, the dev-context.xml file
         is processed last (note: dev-context.xml isn't
         part of the source tree itself). 
        
         For details, see:
         https://wiki.alfresco.com/wiki/Developer_Runtime_Configuration
    -->
    <import resource="classpath*:alfresco/extension/*-context.xml"/>
    <import resource="classpath*:alfresco/extension/dev-context.xml"/>
 
可以看到分层次地进行加载不同的 bean ,并且在后面提供可扩展的 bean 定义的引入,方便进行扩展,而不需要更变这个配置文件
 
继续一个个往下看,并把一些重要的 bean 配置拿出来:
看到配置了 JMX 的服务
<!-- Custom MBeanServer -->
<bean id="alfrescoMBeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"/>
 
<bean id="registry"   class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
    <property name="port" value="${avm.remote.port}"/>
</bean>
<!-- MBeanServer Connector (registers itself with custom alfrescoMBeanServer) -->
<bean id="serverConnector"
      class="org.springframework.jmx.support.ConnectorServerFactoryBean"
      depends-on="registry">
 
    <property name="server"      ref="alfrescoMBeanServer"/>
    <property name="objectName" value="connector:name=rmi"/>
    <property name="serviceUrl" value="service:jmx:rmi://localhost/jndi/rmi://localhost:${avm.remote.port}/alfresco/jmxrmi"/>
 
    <property name="environment">
        <map>
            <!-- The following keys are only valid when sun jmx is used -->
            <entry key="jmx.remote.x.password.file" value="${alfresco.jmx.dir}/alfresco-jmxrmi.password"/>
            <entry key="jmx.remote.x.access.file"   value="${alfresco.jmx.dir}/alfresco-jmxrmi.access"/>
        </map>
    </property>
</bean>
<!-- MBeans registered with alfrescoMBeanServer -->
<bean id="VirtServerRegistry"
      class="org.alfresco.mbeans.VirtServerRegistry"
      init-method="initialize">
 
JMX 服务暴露
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
  <property name="server" ref="alfrescoMBeanServer"/>
   <property name="beans">
     <map>
       <!-- MBeans to register with alfrescoMBeanServer -->
       <entry key="Alfresco:Name=VirtServerRegistry,Type=VirtServerRegistry" value-ref="VirtServerRegistry"/>
       <entry key="Alfresco:Name=FileServerConfig,Type=FileServerConfig" value-ref="FileServerConfig"/>
     </map>
   </property>
</bean>
 
同时暴露了 RMI 的服务
RMI
<!-- The RMI export of the repo remote transport. -->
<bean id="repoRemoteTransportRMI" class="org.springframework.remoting.rmi.RmiServiceExporter">
            <property name="service">
                        <ref bean="repoRemoteTransport"/>
            </property>
            <property name="serviceInterface">
                        <value>org.alfresco.service.cmr.remote.RepoRemoteTransport</value>
            </property>
            <property name="serviceName">
                        <value>repo</value>
            </property>
            <property name="registryPort">
                        <value>${avm.remote.port}</value>
            </property>
</bean>
 
验证 bean 配置,也是同时暴露了 RMI 的服务
<!-- Here for now. Probably want remote-context.xml file. -->
<!-- The AuthenticationService exported as an RMI service. -->
<bean id="rmiAuthenticationService" class="org.springframework.remoting.rmi.RmiServiceExporter">
            <property name="service">
                        <ref bean="AuthenticationService"/>
            </property>
            <property name="serviceInterface">
                        <value>org.alfresco.service.cmr.security.AuthenticationService</value>
            </property>
            <property name="serviceName">
                        <value>authentication</value>
            </property>
            <property name="registryPort">
                        <value>${avm.remote.port}</value>
            </property>
</bean>
 
avm 里也暴露了 RMI 的服务
<!-- The RMI wrapper around the AVM remote interface. -->
 
<bean id="avmRemoteService" class="org.springframework.remoting.rmi.RmiServiceExporter">
            <property name="service">
                        <ref bean="avmRemoteTransport"/>
            </property>
            <property name="serviceInterface">
                        <value>org.alfresco.service.cmr.remote.AVMRemoteTransport</value>
            </property>
            <property name="serviceName">
                        <value>avm</value>
            </property>
            <property name="registryPort">
                        <value>${avm.remote.port}</value>
            </property>
</bean>
                       
<bean id="avmSyncServiceTransport" class="org.alfresco.repo.avm.AVMSyncServiceTransportImpl">
    <property name="authenticationService">
        <ref bean="AuthenticationService"/>
    </property>
    <property name="avmSyncService">
        <ref bean="AVMSyncService"/>
    </property>
</bean>
                       
<bean id="avmSyncServiceTransportRMI" class="org.springframework.remoting.rmi.RmiServiceExporter">
    <property name="service">
        <ref bean="avmSyncServiceTransport"/>
    </property>
    <property name="serviceInterface">
        <value>org.alfresco.service.cmr.remote.AVMSyncServiceTransport</value>
    </property>
    <property name="serviceName">
        <value>avmsync</value>
    </property>
    <property name="registryPort">
        <value>${avm.remote.port}</value>
    </property>
</bean>
 
通过上面的 JMX 与 RMI 暴露在不同的配置文件里可以看到,如果我要去掉 JMX 或 RMI 服务的话,需要修改 N 个的配置文件,实在是麻烦。
建议要二次开发时根据需要进行整理,合并到一个文件里进行暴露即可,或者没有需要的话就直接 delete 掉这些:)
 
而且这个 JMX RMI 服务的暴露,导致你不能仅重启应用就可以,而非得重启整个应用服务器才行,要不然会报服务已启动,即默认的端口50500被占用了,而整个应用启动不了,麻烦。除非你在重启应用之前再去修改一下配置文件里的端口号,呵呵。
 
不过,最终的解决办法是象我在 Jmx4Log4J 里那样自己去再封装一个获取端口号的类,发现有人用了,就找下一个:)这样就OK了。
 
<!-- Datasource bean -->
数据库连接池用的居然是 org.apache.commons.dbcp.BasicDataSource ,大家自己改吧 c3p0 等等
 
邮件
<!-- MAIL SERVICE           -->
<bean id="mailService" class="org.springframework.mail.javamail.JavaMailSenderImpl">
 
Lucene 索引和搜索 API
     <!-- Indexing and Search API -->
    <bean id="indexerComponent" class="org.alfresco.repo.search.IndexerComponent">
    <bean id="searchService" class="org.alfresco.repo.search.SearcherComponent">
 
    <!-- Indexer and searchers for lucene -->
    <bean id="luceneIndexerAndSearcherFactory"
        class="org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcherFactory2">
 
    <!-- Indexer and searchers for lucene -->
    <bean id="luceneCategoryService" class="org.alfresco.repo.search.impl.lucene.LuceneCategoryServiceImpl">
 
    <!-- Lock Service           -->
    <bean id="lockService" class="org.alfresco.repo.lock.LockServiceImpl" init-method="initialise">
 
版本控制
    <!-- Version Service   -->
    <bean id="versionService" class="org.alfresco.repo.version.VersionServiceImpl" init-method="initialise">
 
数据库
    <!-- Data Dictionary -->
    <bean id="dictionaryBootstrap" parent="dictionaryModelBootstrap" depends-on="resourceBundles">
        <property name="models">
            <list>
                <!-- System models -->
                <value>alfresco/model/dictionaryModel.xml</value>
                <value>alfresco/model/systemModel.xml</value>
                <value>org/alfresco/repo/security/authentication/userModel.xml</value>
 
                <!-- Content models -->
                <value>alfresco/model/contentModel.xml</value>
                <value>alfresco/model/bpmModel.xml</value>
                <value>alfresco/model/wcmModel.xml</value>
                <value>alfresco/model/forumModel.xml</value>
 
                <!-- Content models -->
                <value>alfresco/model/applicationModel.xml</value>
                <value>alfresco/model/wcmAppModel.xml</value>
               
                <!-- Implementation models -->
                <value>org/alfresco/repo/action/actionModel.xml</value>
                <value>org/alfresco/repo/rule/ruleModel.xml</value>
                <value>org/alfresco/repo/version/version_model.xml</value>
               
                <!-- Deprecated types -->
                <value>alfresco/model/deprecated/deprecated_contentModel.xml</value>
            </list>
        </property>
        <property name="labels">
            <list>
                <value>alfresco/model/dataTypeAnalyzers</value>
                <value>alfresco/messages/system-model</value>
                <value>alfresco/messages/dictionary-model</value>
                <value>alfresco/messages/content-model</value>
                <value>alfresco/messages/bpm-messages</value>
                <value>alfresco/messages/application-model</value>
                <value>alfresco/messages/forum-model</value>
            </list>
        </property>
    </bean>
 
拷贝
    <!-- Copy Service    -->
    <!-- Note this uses the node service that enforces permissions so you can only copy what you can see -->
    <bean id="copyService" class="org.alfresco.repo.copy.CopyServiceImpl" init-method="init">
 
检出 / 检入
    <!-- CheckOut/CheckIn Service -->
    <bean id="checkOutCheckInService" class="org.alfresco.repo.coci.CheckOutCheckInServiceImpl">
 
全文搜索
    <!-- Bean to support full text search -->
    <bean id="LuceneFullTextSearchIndexer"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
 
Lucene 索引文件备份
    <!-- Bean to backup Lucene indexes -->
   <bean id="luceneIndexBackupComponent"
          class="org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcherFactory2$LuceneIndexBackupComponent">
 
    <!-- Registry service -->
    <bean id="registryService" class="org.alfresco.repo.admin.registry.RegistryServiceImpl" init-method="init">
 
    <!-- A Simple Filesystem like API for the repo implementation.
                 Unfinished, experimental, and probably ephemeral. -->
    <bean id="repoRemoteService" class="org.alfresco.repo.remote.RepoRemoteService">
 
            <!-- Transactionally wrapped version of above. -->
    <bean id="RepoRemoteService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
当中引入了
    <import resource="classpath:alfresco/public-services-security-context.xml"/>
使用的是 Acegi 组件,当中引入了
    <import resource="classpath:alfresco/cache-context.xml" />
 
cache-context.xml Cache 相关的,使用的是 EHCache
   <bean name="transactionalEHCacheManager" class="org.alfresco.repo.cache.EhCacheManagerFactoryBean">
      <property name="configLocation">
         <value>classpath:alfresco/ehcache-transactional.xml</value>
      </property>
   </bean>
    <!-- Service Registry -->
    <bean id="ServiceRegistry" class="org.alfresco.repo.service.ServiceDescriptorRegistry"/>
 
基本上服务都从这里注入并从中获取,树结构,当中有Spring Bean Factory
 
   <!-- File/folder specific service -->
   <bean name="fileFolderService" class="org.alfresco.repo.model.filefolder.FileFolderServiceImpl" init-method="init">
 
   <bean name="tempFileMarkerInterceptor" class="org.alfresco.repo.model.filefolder.TempFileMarkerInterceptor">
 
   <!-- Multilingual specific service -->
   <bean name="multilingualContentService" class="org.alfresco.repo.model.ml.MultilingualContentServiceImpl">
用 Thread local containing the current action chain
    <!-- Action Service -->
    <bean id="actionService" class="org.alfresco.repo.action.ActionServiceImpl">
<!-- Rules Service -->
<bean id="ruleService" class="org.alfresco.repo.rule.RuleServiceImpl">
<!-- Rules Aspect -->
<bean id="rulesAspect" class="org.alfresco.repo.rule.RulesAspect" init-method="init">
<!-- Rule triggers -->
<bean id="rule-trigger-base" abstract="true" init-method="registerRuleTrigger">
<!-- Beans pertinent to node persistence and services -->
<!-- Task scheduler -->
<!-- Triggers should not appear here - the scheduler should be injected into the trigger definition -->
<!-- This bean should not need to apear else where in extension configuration -->
<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="waitForJobsToCompleteOnShutdown">
        <value>true</value>
    </property>
    <property name="configLocation">
        <value>classpath:alfresco/domain/quartz.properties</value>
    </property>
    <property name="schedulerName">
        <value>DefaultScheduler</value>
    </property>
</bean>
 
# Quartz thread settings 默认的线程优先级为 3
org.quartz.threadPool.threadPriority=3
需要相关的文件配置信息在 file-servers.xml
MIME OpenOffice PDF Mail MP3 ...
<!-- load hibernate configuration properties -->   
<bean id="hibernateConfigProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="locations">
        <list>
            <value>classpath:alfresco/domain/hibernate-cfg.properties</value>
        </list>
    </property>
</bean>
<!-- load hibernate entity cache strategies -->   
<bean id="cacheStrategiesPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="ignoreUnresolvablePlaceholders">
        <value>true</value>
    </property>
    <property name="locations">
        <list>
            <value>classpath:alfresco/domain/cache-strategies.properties</value>
        </list>
    </property>
</bean>
 
<!-- Hibernate session factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" parent="sessionFactoryBase">
 
<!-- Hibernate session factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" parent="sessionFactoryBase">
    <property name="dataSource">
        <ref bean="dataSource"/>
    </property>
</bean>
<bean id="sessionFactoryBase" abstract="true">
    <property name="hibernateProperties" ref="hibernateConfigProperties"/>
    不同的Cache策略
    <property name="entityCacheStrategies">
    <property name="collectionCacheStrategies">
Ownership service support. Use in permissions framework as dynamic authority.
<bean id="ownableService" class="org.alfresco.repo.ownable.impl.OwnableServiceImpl">
script-services-context.xml 脚本引擎 Rhino JavaScript engine.
<!-- index recovery and validation -->
<!--
 Recovery types are:
     NONE:     Ignore
     VALIDATE: Checks that the last transaction for each store is represented in the indexes
     AUTO:     Validates and auto-recovers if validation fails
     FULL:     Full index rebuild, processing all transactions in order. The server is temporarily suspended.
-->
<bean
     id="indexRecoveryComponent"
     class="org.alfresco.repo.node.index.FullIndexRecoveryComponent"
     parent="indexRecoveryComponentBase">
 <property name="recoveryMode">
      <value>${index.recovery.mode}</value>
 </property>
</bean>
 
<!-- Bean that attempts to index content that was previously missing -->
<bean
     id="missingContentReindexComponent"
     class="org.alfresco.repo.node.index.MissingContentReindexComponent"
     parent="indexRecoveryComponentBase">
</bean>
<!-- The configuration of the Authority Service Implementation -->
<!-- This implementation supports the identification of users as admin users. -->
<!-- It also supports groups and allows groups and users to be arranged into -->
<!-- hierarchies.                                                             -->
 
<bean id="authorityService" class="org.alfresco.repo.security.authority.AuthorityServiceImpl">
    <!-- A list of users with admin rights.                               -->
    <!--                                                                  -->
    <!-- If the security framework is case sensitive these values should -->
    <!-- be case sensitive user names. If the security framework is not   -->
    <!-- case sensitive these values should be the lower-case user names. -->
    <!--                                                                  -->
    <!-- By default this includes:                                        -->
    <!--    admin (the user name of default alfresco admin user)          -->
    <!--    administrator (the windows default admin user)                -->
    <!--                                                                  -->
    <!-- This assumes that user names are not case sensitive.             -->
    <!--                                                                  -->
    <property name="adminUsers">
        <set>
                                    <value>admin</value>
                                    <value>administrator</value>
                        </set>
    </property>
 
<!-- Authority DAO that stores group information along with user information, -->
<!-- in the repository.                                                       -->
<!--                                                                          -->
<!-- This bean uses the userToAuthorityCache configured in cache-context.xml -->
<!--                                                                          -->
<bean id="authorityDAO" class="org.alfresco.repo.security.authority.AuthorityDAOImpl">  
<!-- This file contains the bean definitions that support authentication -->
<!-- Policy Support -->
如:数据库、AVM、文件服务器、FTP、NFS、CIFS等等。。。
Repository Bootstrap Sequence.
<!-- ensure that the schema is bootstrapped -->
<bean id="schemaBootstrap" class="org.alfresco.repo.domain.schema.SchemaBootstrap">
 <property name="localSessionFactory">
     <ref bean="&amp;sessionFactory"></ref> <!-- inject the actual factory, not a session -->
 </property>
<!-- Workflow Service Implementation -->
 
jcr-api-context.xml 实现JCR 170相关的API,即1.0版本的API
Alfresco implementation of a JCR Repository
<!-- ID Issuers. -->
 
<!-- DAOs for persistent data types -->
<!-- Issuers are not actual entities. More like pseudo entities. -->
<!-- Use substitution values in this config. -->
 
avm-console.properties 默认配置为本地MySQL的数据库
# Database specifics.
db.driver=org.gjt.mm.mysql.Driver
db.url=jdbc:mysql://127.0.0.1/avm
db.username=root
db.password=
db.pool.initial=4
db.pool.max=32
# Hibernate properties
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
hibernate.current_session_context_class=thread
hibernate.connection.isolation=2
hibernate.

最后更新:2017-04-02 00:06:21

  上一篇:go 跟我一起写 Makefile
  下一篇:go 忍无可忍,决定宁可错杀千万,也不漏掉一个,弹已出膛,剑已出鞘!