张昊

J-Hi(http://www.j-hi.net)

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  45 Posts :: 1 Stories :: 110 Comments :: 0 Trackbacks

#


我在博客发表的文章大部分均被51CTO网站所收录,并且51CTO还为J-Hi做了专访 

“J-Hi”Java开源平台的生力军




专题的URL为:http://developer.51cto.com/art/201103/250221.htm


posted @ 2011-04-04 21:07 张昊 阅读(1057) | 评论 (0)编辑 收藏


posted @ 2011-04-01 19:33 张昊 阅读(1583) | 评论 (0)编辑 收藏

首先描述最简单的身份验证后台的处理过程

1、 用户输入需要确认自己身份的信息,如账号与密码或许需要其它信息

2、 也许你希望提供多种有方式的验证形式,由系统选择最合适的那一种,如从数据库(DAO)或是通过身份验证中心的服务(ACS)统一管理等

3、 根据账号找到指定源中的用户、密码及所拥有的权限(如果没找到就抛出异常)等用户的身份信息,验证用户输入的信息与源中返回的信息是否一致(如密码)

4、 为了不至于每次都重复上面的过程,还要将验证后的信息缓存起来,如放到session

acegi结合分析

1、 用户提交后为了能进行上述的处理,acegi不是通过请求-影响模式,而是能过ServletFilter实现的。可以理解成这个身份验证的主入口,不同的处理机制采用不同的Filter,类名的规则为*ProcessingFilter,这些类全部都继承至javax.servlet.Filter接口。下面是几个常用的过滤器

模块

功能

BasicProcessingFilter

按照RFC1945处理基本的身份验证请求

CasProcessingFilter

处理耶鲁大学的中心身份验证服务器(CAS)许可

AnonymousProcessingFilter

对匿名身份的处理

AuthenticationProcessingFilter

处理类似于Servlet规范的j_security_checkHttp form post

Spring的配置过程中有些过滤器除了自身的信息外,还有可能需要切入点,以便切入到其它模块中的配置信息。如AuthenticationProcessingFilter验证不通过的处理页面或要采用的协议、CasProcessingFilter需要提交到CAS上的其他信息。它们的统一接口类为AuthenticationEntryPoint在此要注意的是,切入点与过滤器之间有着密切的联系与对应关系的。

2、 acegi为了实现多种方式的验证形式提供了AuthenticationManager接口,目的是对多种验证形式进行管理,并通过指定的验证形式返回用户的身份。所以上述的过滤器均会调用该接口的authenticate(Authentication authentication)方法以返回当前用户的身份信息。该接口主要的实现类是ProviderManager

AuthenticationProvider(身份验证供应器)接口有很多实现类,每个都致力于处理一个特定身份验证的具体实现,AuthenticationManager负责轮询AuthenticationProvider列表,并使用第一个能够处理给定的Authentication请求对象的AuthenticationProvider。身份验证供应器也就是上面说的验证形式。最常用的是DaoAuthenticationProvider,实现从数据库中获取用户的身份信息

3、 acegi中用户的身份信息存放到以Authentication接口的实现类的实例中。在介绍该接口之前先要了解一些关键术语

1) principal(主体)指可以执行操作的用户、服务或代理(agent),即身份验证的发启者

2) credential(凭证)指主体提供密码之类用于身份验证(authentication)的信息戳

3) authentication(身份验证)确定调用者身份的过程

4) authorization(授权)指决定哪个主体准许执行给定操作的过程

Authentication接口包含主体标示、主体的凭证以及主体所拥有的一组权限。

Authentication接口继承java.security.Principal接口,因此Authentication天生就要满足主体的类型。该接口实际上是上述几个关键词对象化的一个容器,它存储了身份验证的全部信息。由此会发现它与AuthenticationProvider(身份验证供应器)有着天然的联系,如对于数据库的供应器它只要记录用户的帐号和密码,但对于CAS它还可能还要记录服务器响应的列表,或是与认证相关的其它信息。因此该接口对应身份验证供应器有多个实现类。正因为于此,所有的实现类对于开发者来说几乎是隐藏在,可以理解成工具或是服务类

下面对Authentication接口中的方法做详细扩展说明

1) getPrincipal(获得主体)getCredential(获得凭证),它们的设置过程:无论何种验证形式用户都是通过用户输入帐号和密码开始的,过滤器会拦截用户的请求,由验证管理器(AuthenticationManager)找到合适的身份验证供应器(AuthenticationProvider)提供身份验证。在AuthenticationManager接口只有一个方法authenticate(…),而该方法的参数与返回类型均是Authentication。所以大多数过滤器在请求身份验证前总是创建一个简单的UsernamePasswordAuthenticationToken(该类是Authentication接口的子类)对象,将其作为AuthenticationManager.authenticate(…)方法中的参数,再由AuthenticationProvider依据自身的特点创建相应的Authentication接口子类的实例,因此身份验证的具体信息也是在这最后一步完成的,即是在AuthenticationProvider中被创建与赋值的。其中就包括主体与凭证。如对于数据库来说也是账号与密码。

2) getAuthorities()得到当前用户所拥有的全部权限。Acegi提供一个GrantedAuthority接口,用于对应应用系统中有真正意义的权限实现。常用的是GrantedAuthorityImpl,它存储主体的已获授权的String表示,即权限也就是字符串的表示。而GrantedAuthority仅对字符做一层简单的封装。

3) getDetails()获取详细资料,目的是得到当前用户的详细信息,如在应用系统可以是用户的一个Bean(所在的部门,真实姓名…)。为此Acegi提供了一个UserDetails接口.

l         isAccountNonExpired         帐号是否未过期

l         isAccountNonLocked           帐号是否未锁定

l         isCredentialsNonExpired密码是否未过期

l         isEnabled                             是否可用(激活)

我们会发现对于一个应用系统来说,用户的详细信息中除与身份验证相关的信息外还要很多其它的信息,如用户所在的部门、电话。为此acegi提供了另一个接口AuthenticationDetailsSource,它仅提供一个方法buildDetails(HttpServletRequest request)用以创建客户化的用户信息。在过滤器中在执行身份验证之前调用该方法。

4) isAuthenticated(),是否通过了身份验证

当通过主体(帐号)从源(DAOCASJAAS…)中返回的信息中创建出Authentication实例后,还要校验用户的凭证(密码)的一致性。对于提供了以PasswordEncoder接口为代表的一组密码编码器的实现

4、 在我们讨论对于身份验证(Authentication)对象的保存之前,先来说明一下对它的访问。为了确保任何对身份验证感兴趣的类型都可以访问它,acegi通过SecurityContextHolder(该类中提供的所有成员方法均是静态的)用来保持SecurityContextThreadLocal对象。

通过SecurityContext类图可以看出在它很简单只是对Authentication对象的一个引用,之所以又做了这样一层包装的目的是为了客户可以做任意的扩展。由于SecurityContextHolder引用的是线程ThreadLocal集合,而对于B/S系统来说,一个线程的生命期还是太短了,无法保证SecurityContext对象的信息在一个线程执行后不会被JVM垃圾回收。一般来说我们会将SecurityContext放到session中,但这样又无法保证在逻辑层中访问到session。对此acegi的解决方案是通过javax.servlet.Filter使不同与的访问范围与SecurityContextHolder做整合(session为例,每次请求过滤器都会从session中取得SecurityContext然后再将其赋到SecurityContextHolder)Acegi提供了多种整合过滤器,命名规则为*IntegrationFilter

模块

功能

HttpSessionContextIntegrationFilter

请求之间使用HttpSession存储SecurityContext

HttpRequestIntegrationFilter

HttpServletRequest.getUserPrincipal()获得身份验证,但在请求结束时不能将该身份验证写回该位置

JbossIntegrationFilter

Jbossjava:comp/env/security/subjectJNDI位置获取身份验证,但在请求结束时不能将该身份验证写回该位置

接下来再来讨论对Authentication的设置,当处理过滤器调用AuthenticationManager. Authentication(…)获得Authentication对象后,它会调用自身的成员方法successfulAuthentication(…)将其封装为SecurityContext并设置到SecurityContextHolder中。

注意successfulAuthentication(…)方法是在抽象类AbstractProcessingFilter中,而有一些处理过程器并没有继承该类,所以只有AbstractProcessingFilter的子类才会在当前线程中取得SecurityContext对象。

再来描述授权的后台的处理过程

1、 我们可能希望在三个地方做安全验证,即是否可以访问当前页面,是否可以调用当前方法,是否可以控制当前方法参数的对象域

2、 对于安全验证的判断可能希望提供不同的表决策略,如一票否决制,还是有一票同意就通过或是同意大于否决票时才通过。

3、 总之,所有需要的处理无非是在做这样的工作。当前用户所拥有的权限中,否则有(或匹配)与当前被调用者(页面、方法、域)所指定的权限

Acegi对于授权的技术实现

从技术上话,授权完全与日志一样是一个横切关注点,与具体业务没有任何关系。而Acegi只是借助SpringAOPjavax.servlet.Filter,对这授权方面的拦截。对于拦截器与其持有的对象Acegi提供如下实现:

拦截器

描述

持有的对象

描述

AbstractSecurityInterceptor

是所有拦截器的抽象父类,实际授权的全部验证过程均在该类beforeInvocation()afterInvocation()两个方法中完成,子类只是区别不同类型的安全对象。

FilterSecurityInterceptor

是一个web的过滤器,用于对页面(URL)的授权验证

FilterInvocation

仅是对简单crequestresponseFilterChain包装的实现

MethodSecurityInterceptor

用于验证Spring容器中bean的方法,并且需要使用Spring中的代理

MethodInvocation

AOP Alliance提供的被代理对象接口,运行时的实际对象类型是由Spring提供的ReflectiveMethodInvocationCglibMethodInvocation

AspectJSecurityInterceptor

该类是在指定切入点调用AspectJ

JoinPoint AspectJCallback

执行AspectJ的回调






AbstractSecurityInterceptor的执行过程:

首先查询应用于该调用的配置属性。如果没有任何配置属性,该调用被认为是公有的,并且继续进行该调用。如果找到配置属性,包含在SecurityContextHolder中的Authentication是通过AuthenticationManager验证的,并且请求AccessDecisionManager来批准该请求,如果成功RunAsManager可以替代该Authentication的标识,然后继续进行该调用。调用完成时,将通过更新SecurityContextHolder来包含实际的身份验证对象以清除RunAsManager的替代标识。最后调用AfterInvocationManager,如果定义了的话。

RunAsManager:该接口的主要作用成员方法是Authentication buildRunAs(Authentication authentication, Object object, ConfigAttributeDefinition config)目的是当执行特定操作时用于选择性的替换Authentication对象,该方法是在安全验证之后,安全对象执行之前被调用。在安全对象执行之后该方法对Authentication对象替换后被还原。

AfterInvocationManager:作用是修改从安全对象调用中返回的对象。这通常被用来过滤仅针对已包含、已验证元素的集合,或者如果信息是受保护的,转换实例变量。如果该主体没有针对返回对象的权限,它还可以抛出AccessDeniedException。主要的方法是

Object decide(Authentication authentication, Object object, ConfigAttributeDefinition config,        Object returnedObject) throws AccessDeniedException,它需要返回一个对象,然后该对象将变成安全对象调用的结果。轮询AfterInvocationProvider接口的具体类。

最后分析权限表决的原理,还是让我们虚拟这样一个场景:

1、 要求有两个表决器,1)判断当前用户是否为超级管理员,2)判断当前用户是否拥有当前所调用的方法或页面的权限

2、 如果其中任何一个表决器投出赞成票,就认为通过。这是一种表决策略

Acegi结合分析

2、表决策略作用是轮询所有的表决器,根据当前策略结合表决器的表决结果,做出最终判断结果。Acegi表决策略管理的接口是

1)      decide(…)根据当前用户所拥有的权限信息[authentication],拦截器所持有的对象[object]以及在配置文件中所持有对象所必要的权限s[config],轮询表决器做出决策。

2)      supports(ConfigAttribute)判断所有表决器是否有一个以上支持这种权限的表示形式

3)      supports(Class) 判断所有表决器是否有一个以上支持拦截器所持有的对象类型

后两个方法主要在是各种拦截器初始化时调用,以但Spring验证bean定义的合法性

对于表决策略来说最终可能会得到三个结果中的一个赞成、否决或是弃权(结果是由表决器结合策略得到的)。对于弃权的产生是由于拦截器所持有的对象在配置中没有设置任何权限。为此该接口的抽象子类提供allowIfAllAbstainDecisions开关,如果所有表决器投出的均为弃权票,表示没有通过授权则将该属性设为true,默认为false.

Acegi提供了多种表决策略

注意:一个表决器只能投一票

AffirmativeBased       有一个决策器投出赞成票就通过

ConsensusBased          赞成票大于否决票就通过,相同也算是没有通过授权

UnanimousBased        一票否决制,也就是只要有一个表决器投否决票就算不通过

因此对于上面的场景我们应该选择AffirmativeBased表决策略,在决策略下还要有两个表决器,下面介绍表决器

1

posted @ 2011-03-31 19:07 张昊 阅读(1972) | 评论 (1)编辑 收藏

系统日志就是记录管理员或用户对系统的历史操作信息,比如管理员添加或者修改、删除一个角色,这些操作都可以记录到系统日志表中,管理员可以通过“系统管理系统日志”菜单查询详细的日志信息。

系统日志的配置大致包括两个方面:系统日志缓存配置和系统日志类型配置,此两项配置信息在WEB-INF/config/appContext.xml

²        系统日志缓存配置:

系统产生的日志默认不是立即存入数据库的,而是存入日志缓存中,缓存中的日志信息达到设定的缓存策略时,系统将缓存中的日志信息存入数据库,缓存策略配置目前支持按照缓存大小、时间、日志条数设置

appContext.xml文件中找到如下配置

<bean id="cacheProcessor" class="org.hi.base.sysapp.interceptor.LogSizeCacheProcessor">

           <property name="size" value="10"/>

</bean>

此处是按照缓存大小设置的缓存策略,此处的缓存大小设置的值为10M

此行代码下方有两个类似的被注释的配置如下:

<!--

<bean id="cacheProcessor" class="org.hi.base.sysapp.interceptor.LogTimerCacheProcessor">

    <property name="period" value="1"/>

</bean>

<bean id="cacheProcessor" class="org.hi.base.sysapp.interceptor.LogLengthCacheProcessor">

    <property name="length" value="10"/>

</bean>

-->

此处两项配置也是缓存策略的设置,第一项配置是按照时间设置缓存策略,此处的时间值为1分钟,第二项配置是按照日志条数设置缓存策略,此处的日志条数值为10

注意:以上三项配置只能保留一项,也就是说当系统运行时只能选择一种日志缓存策略

²        系统日志类型配置:

系统日志类型根据操作的不同大概分为四种:添加和更新操作、删除操作、查询操作、其他操作,此四种类型分别对应于WEB-INF/config/appContext.xml配置文件中的四项配置

添加和更新操作

<bean id="saveLogAnalysisor" class="org.hi.base.sysapp.interceptor.LogSaveAnalysisor"/>

删除操作

<bean id="removeLogAnalysisor" class="org.hi.base.sysapp.interceptor.LogRemoveAnalysisor"/>

查询操作

<bean id="searchLogAnalysisor" class="org.hi.base.sysapp.interceptor.LogSearchAnalysisor"/>

其他操作

<bean id="noknowLogAnalysisor" class="org.hi.base.sysapp.interceptor.LogNoknowAnalysisor"/>

系统运行时,管理员可以根据关注的日志类型选择其中的一项或者多项,选择好后将其配置到以下代码处:

<bean id="methodLogInterceptor" class="org.hi.base.sysapp.interceptor.MethodLogInterceptor">

           <property name="saveProcessor" ref="saveProcessor"/>

           <property name="cacheProcessor" ref="cacheProcessor"/>

           <property name="unincludeMethodNames">

               <value>getEnumerations</value>

           </property>

           <property name="analysisors">

               <list><!—- 此处配置日志类型 -->

                  <ref bean="saveLogAnalysisor"/>

                  <ref bean="removeLogAnalysisor"/>

                  <ref bean="noknowLogAnalysisor"/>

               </list>

           </property>

</bean>

管理员可以将关注的日志类型添加到<property name="analysisors">下的<list>标签下,上面的代码配置了三项日志类型,即添加和更新操作、删除操作、其他操作产生的日志将会被记录到数据库,不建议将查询操作日志类型添加进去,因为查询操作将会产生大量日志,不便于管理员找到自己关注的日志内容,另外也会在较短时间内占用大量的数据库空间。

设计分析:通过上面的配置文件可以看出,系统日志的设计思想通过Spring的方法拦截器(methodLogInterceptor),该拦截器又分大的三个部分,保存处理器(saveProcessor);缓存处理器(cacheProcessor);日志分析器(analysisors)。保存处理器,的工作是将日志保存到指定的持久化介质中例如数据库表或是XML等,目前平台缺省提供的是保存到数据库表中,当然您也可以通过实现接口的方式自由控制日志保存的位置;缓存处理器,日志不是每生产一条就做一次保存的,而是通过缓存批量将日志信息保存起来,缓存处理器就是来完成日志的缓存功能,目前平台提供3种缓存机制;日志分析器,因为数据的增删查改等操作的描述信息各不相同,所以日志分析器的作用是分析日志数据的描述格式以方面管理员阅读日志。对于日志的处理流程来看,当调用某个业务层方法时日志的方法拦截器就是拦截住该方法,首先通过方法的类型调用相应日志分析器分析出日志描述信息与格式,然后将日志放到缓存中,缓存处理器会根据相应的触发条件,如果满足条件就调用保存处理器将日志信息批量保存起来。




                                           注:该文档由J-Hi爱好者"刀刀"提供,他的QQ号为150380807,欢迎大家与他在技术上多多交流

posted @ 2011-03-30 20:51 张昊 阅读(1870) | 评论 (2)编辑 收藏

     摘要: 目的 通过配置文件himenu-config.xml动态装配树型结构,要求不对V端(JSP或Javascript)不做任何修改,树的深度—深度包括两层含义1组件与组件之间的关联层次的深度2树本身的层次的深层—不做任何限制,动态—动态也包括两层含义1树本身的数据是动态的均应从数据库中调用2动态加载即只有点击当前层的节点时才去加载当前层的下一层数据—构建,多语言的支持要求可配置—从数据库取出的数据可以...  阅读全文
posted @ 2011-03-29 00:00 张昊 阅读(1837) | 评论 (1)编辑 收藏

     摘要:     安全管理是最复杂也是最难以理解的功能模块,理论上仅对系统管理员开放该功能。总的来看安全管理主要分为用户管理、用户权限、角色来分派权限。     在介绍安全管理之前,先让我们对一些关键字有所了解。 关键词: ü         ...  阅读全文
posted @ 2011-03-24 21:10 张昊 阅读(3264) | 评论 (1)编辑 收藏

您的产品能跟Apache,JBoss,Spring比么,是一个级别的东西么?他们的源代码都是放在网站上随便下载的,您的呢,还要填申请,还要加入 群,怎么这么多破事儿啊!您平台的开发工具用了Eclipse,IBM让您加入群或者填申请了么,Eclipse的源代码就放在IBM的网站上,随便用, 谁都可以下载。看好,这才叫开源!到了中国的开源为什么就会这样艰难呢?

       这位网友的言词很犀利,但他还是给我们留了一些余地没有把话说得那么明白。实际上这位网友的想说的不过是,你为什么要采用这样的开源模式?你到底想赚钱还是想开源?下面我针对这些问题逐一回答,如果我的理解有不当之处,也请各位网友提出自己的见解。

       首先,优秀的开源项目是一个综合性的问题,它不仅包括技术与产品本身还包括:

1、 合理的推广模式,例如Rod Johnson在推出Spring之前已为Spring的思想打下了坚实的基础写了好几本J2EE的书,这种影响力甚至深远到很多人都排斥EJB,以及于Spring一推出就受到了很多人的关注。当然我用Spring只是举个例子,推广有很多种形式但什么形式更适合J-Hi呢?我们还在探索。

2、 及时、有效的服务支持,例如JBoss这是免费的也是开源的,但它有优质的服务。7*24小时全年无休的为使用者解决实际问题。当然服务还包括很多大量的文档、清晰易懂的视频、有针对象的用例程序、可参考的运行系统、现场的技术支持等等。由此可见,服务是一个复杂的工程,需要投入大量的人力、物力、财力。

3、 有自身生存的条件,纵观很多开源项目与开源组织有很好的产品但还是半路夭折了。例如opensymphony组织,可能大家不熟但他们的产品我想大家都知道:webworkognlosworkflowosCache。我们以webwork为例,它在Struts1.X时就与之争占市场,最终还是败下阵来,甚至Struts2只是在webwork内核之上披上了一层外衣。究其原因是什么,为什么opensymphony组织失去了生命力,我觉得最主要的原因还是来自于自身,没有最起码的生存条件作为基础。实际上开源项目面临最重要的问题就是生存问题。只要是开源的参与者,都有一颗关爱他人与他人分享成果的心。然而做一件事情并且要长期的坚持下去只有激情还是远远不够的,我一直认为只有吃饱肚子才能干开源,而吃饱肚子是生存的前提。

4、 有基金或资金的支持,强而用力的基金与资金的支持是开源很重要的因素,比如Apache背后有无数的大企业的捐赠与资助,而在中国我们没有这个条件。再说深一点,webwork卖给了apachehibernate卖给了JBoss,起码这些产品卖出后还在继续开源继续维护,反过来看我们能卖给谁,即使是卖了还能再开源码?

总结上述几点可以看出,我们ApacheJBossSpring确实不能比不但不能比技术而且在所有的条件下都没法比。就是因为没法比所以我们也在探索一条适合中国国情的开源的路(采用这样的开源模式),我们从不否认自己的商业性,也不想否则。原因很简单,那就是生存,不过有一个论点我倒是想明确一下,我们不是为了想赚钱才开源,而是想开源必须要赚钱!

其次,开源项目是个长期的坚持不懈的过程,前一阵子流行一句话 “剩者为王”,那么如何才能成为“剩者”呢?一个开源项目如果要有长久的生命力,不是只靠一个团队或几个人事(几个人是做不过来这么多事情的),还要有推广(要有广告投入吧);要有服务(要有支持人员吧);要有收益(要支付人员工资吧)等等,真正的“剩者”就是能生存下来的人,如果生存都成为问题,何谈长期与坚持不懈呢?

最后,中国的开源不但需要大家的理解与支持,更需要大家的参与,有问题可以说出你的意见与解决方案,而不是批评与指责。如果真要这么说的话,那么我们已经把我们五年的劳动成果分享给大家,而您又为别人做了些什么呢?中国的开源以及中国开源所应采取的何种模式运作才算是合理?这是一道非常有深度的问题。我真心的希望大家在看到这篇文章后能发表一下自己的意见与建意。实质的问题的核心就是“在中国如何能在开源的前提下又能保证生存与发展

posted @ 2011-03-22 18:03 张昊 阅读(1802) | 评论 (2)编辑 收藏

cquireIncrement[3]         当连接池中的连接耗尽的时候c3p0一次同时获取的连接数

acquireRetryAttempts[30]    定义在从数据库获取新连接失败后重复尝试的次数

acquireRetryDelay[1000]     两次连接中间隔时间,单位毫秒

autoCommitOnClose[false]    连接关闭时默认将所有未提交的操作回滚

automaticTestTable[null] 如果值为Test则c3p0将建一张名为Test的空表,并使用其自带的查询语句进行测试。如果定义了这个参数那么属性preferredTestQuery将被忽略。你不能在这张Test表上进行任何操作,它将只供c3p0测试使用

breakAfterAcquireFailure[false]      获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试获取连接失败后该数据源将申明已断开并永久关闭

checkoutTimeout[0]              当连接池用完时客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待

connectionTesterClassName[com.mchange.v2.c3p0.impl.DefaultConnectionTester]                      通过实现ConnectionTester或QueryConnectionTester的类来测试连接。类名需制定全路径

factoryClassLocation[null]             指定c3p0 libraries的路径,如果(通常都是这样)在本地即可获得那么无需设置

forceIgnoreUnresolvedTransactions [false]    建议不使用的一个属性,如果为true时允许有程序bug在事务中

idleConnectionTestPeriod[0]   每隔X秒检查所有连接池中的空闲连接

initialPoolSize[3]     初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间

maxIdleTime[0]            最大空闲时间(秒),X秒内未使用则连接被丢弃。若为0则永不丢弃

maxPoolSize[15]    连接池中保留的最大连接数

maxStatements[0]  JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements属于单个 connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。如果maxStatements与 maxStatementsPerConnection均为0,则缓存被关闭

maxStatementsPerConnection[0]          maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数

numHelperThreads[3]           c3p0是异步操作的,缓慢的JDBC操作通过帮助进程完成。扩展这些操作可以有效的提升性能
通过多线程实现多个操作同时被执行

overrideDefaultUser[null]       当用户调用getConnection()时使root用户成为去获取连接的用户。主要用于连接池连接非c3p0的数据源时

overrideDefaultPassword[null] 与overrideDefaultUser参数对应使用的一个参数

password[null]        密码

preferredTestQuery[null]        定义所有连接测试都执行的测试语句。在使用连接测试的情况下这个一显著提高测试速度。注意:测试的表必须在初始数据源的时候就存在

propertyCycle[300]         用户修改系统配置参数执行前最多等待300秒

testConnectionOnCheckout[false]  因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable等方法来提升连接测试的性能

testConnectionOnCheckin[false]           如果设为true那么在取得连接的同时将校验连接的有效性

user[null]        用户名

usesTraditionalReflectiveProxies[false]         期的c3p0版本对JDBC接口采用动态反射代理。在早期版本用途广泛的情况下这个参数允许用户恢复到动态反射代理以解决不稳定的故障。最新的非反射代理更快并且已经开始广泛的被使用,所以这个参数未必有用。现在原先的动态反射与新的非反射代理同时受到支持,但今后可能的版本可能不支持动态反射代理

posted @ 2011-03-21 19:58 张昊 阅读(2013) | 评论 (0)编辑 收藏



VISO及JPG文件在附件中:
http://www.blogjava.net/Files/hao-zhang-hi/SpringContainerCalss.rar


posted @ 2011-03-19 23:41 张昊 阅读(2757) | 评论 (3)编辑 收藏

       我觉得从广义上来讲,“平台”这个词应该是承载事物的环境或实体。比如我们说某某电子商务平台更多的体现在它的环境上,而当我们说观景平台时更多的体现在它是一个物理的实体上。不过无论是环境也好实体也罢,虽然在应用领域上会千差万别,但它们都有一个共同的特性,即平台是一个载体。让人或信息工作的更高效,从本质来看,好像平台更像是一种传统模式的有有益的补充,而非必须要有的。比如以电子商务平台为例,没有电子商务平台人们就不能交易了嘛?好像不是这样。我这样说并不是说平台是可有可无的东西,而是说有了平台会使人家更效、舒适的生活。反过来说,平台是对我们生活模式的有益补充。既然平台是一个承载体,所以理论来说它并不应该限制人们的习惯或方式,比如谁说观景平台就只能看风景,我在它上面吃饭不可以嘛?这当然是没有问题的(虽然这样做有些不合适,但没人会说这是不可以的)。

       由上述对广义对平台的共同性特点来反观技术平台,好像在技术领域平台这个词很模糊javanet说自己是平台,还有一些以模型驱动的软件企业也说自己的产品是平台,在国内一些几个开源框架搭建起来带一些业务模型功能的也称自己是平台。对此我们应该简单的梳理一下:在技术领域好像平台是一个相对的概念,以java为例,java平台作为底层支撑着上述其它的平台。

       在此我不想评价各个平台类产品的优劣,只是觉得国内的平台做得还不够好,这种不好不只是指技术还包括市场的运作模式、开放程序等方面。下面我说一下我梦想中的平台应该是个什么样子:

1、 平台应该是开源的,既然是平台就应该有一个开放的心态,这样才能使更多的人在平台上去开发相应的产品,才会有更多的用户群。像java语言为什么会远远多于其它语言的使用者,其主要原因就是它开源,开放标准,从而在框架类产品中形成百家争鸣的盛况,并且这种趋势并没减退还在继续——即使Oracle收购了Sun。由此我们可以看出一个开放性的平台,用户群足够多、技术足够公开,那么它的发展方向并不是由一家或几家大公司可以掌控的,平台的开放性将是一种趋势。

2、 平台应该是高效的,平台的最终目的就是提高生产力降低成本。首先从技术角度分析,它要足够的快速,从而降低开发成本;它要足够的简单易用,从而降低学习成本;它要适应已有的开发习惯与管理方式,从而降低风险成本;它要有足够的抽象性与复用性(即使是以平台开发出的产品也是一样),从而降低重复劳动。其次,提高生产力降低成本是一个综合性的问题。平台应该不只是一个开发工具,应该是对应项目全生命期过程建立起自己的思想体系与解决方案,从而在整个项目周期内的每个环节都体现出它作用。例如从项目立项开始应该大体分为签定合同à需求调研à概要设计à详细设计à开发à测试à部署上线 (发布)à需求变更等,好的平台应该是对项目的全过程进行管理,例如现在项目开发存在一个很大的问题就是文档与代码不同步;再如测试用例与测试的覆盖率很低甚至没有测试代码或测试文档;再再如目前大多平台都没有整合打包的部署工具(跨操作系统、跨数据库、跨应用服务器),一键式远程部署;最后需求的变更也是头痛的问题,平台是如何适应不断的需求变化的,大多平台均没有合理的解决方案。因此可以看出,平台是一个综合性的工程,仅解决一、两个点上的问题是不足以从根本上提高生产力降低成本的。

3、 平台的技术是可选择的,我们前面说过平台它只是个载体,至于在这个载体上放些什么,怎么去搭配使用,平台应该为使用者提供各种可选择的权力,甚至是可扩展、可插拔的条件。每个使用者都有自己各自的技术倾向性,这种倾向性有可能是他对某种技术的熟练程度,或者是出去于具体业务所采用技术的适应性。总之平台应该适应这种倾向性,它不应该拘泥于某种技术或某个框架,把这些选择权开放给使用者,使自己成为一个容器或是一个载体这才是平台最应关注的东西。

4、 平台之上的平台,从本质来看平台还是个实体是个工具,是人与机器的交流,而非人与人的交流。我觉得好的平台除了人与机器的交流外,更应该是一个社区一个人与人交流的平台,这样大家可以在这个平台实现资源共享,分享劳动成果。只有形成一个开放的生态社区或生态环境,大多数人都能融入其中,大家可以在这样平台之上的平台上共同工作,从而实现双赢,使每个付出的人都有收益。

posted @ 2011-03-18 16:41 张昊 阅读(1720) | 评论 (1)编辑 收藏

仅列出标题
共5页: 上一页 1 2 3 4 5 下一页