??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产日韩成人综合天堂,亚洲国产人成在线观看69网站 ,亚洲AV无码国产一区二区三区http://m.tkk7.com/hk2000c/archive/2008/01/24/177387.htmlhk2000chk2000cWed, 23 Jan 2008 16:04:00 GMThttp://m.tkk7.com/hk2000c/archive/2008/01/24/177387.htmlhttp://m.tkk7.com/hk2000c/comments/177387.htmlhttp://m.tkk7.com/hk2000c/archive/2008/01/24/177387.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/177387.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/177387.html 可以扩展C切的业务对象?br /> 包括基础ҎQ操作?br /> 甚至安全对象本n
有点学的味道?br />
可能是因为采用其他被创造者不知道的机Ӟ所以被创造者无法理解和知晓?br />




hk2000c 2008-01-24 00:04 发表评论
]]>
关于要求hibernate事务报session讄为auto标志异常问题http://m.tkk7.com/hk2000c/archive/2007/11/30/164252.htmlhk2000chk2000cFri, 30 Nov 2007 06:01:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/11/30/164252.htmlhttp://m.tkk7.com/hk2000c/comments/164252.htmlhttp://m.tkk7.com/hk2000c/archive/2007/11/30/164252.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/164252.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/164252.html
  <aop:config>
        <aop:pointcut id="systemDaoMethods" expression="execution(* com.unitedbiz.system.dao.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="systemDaoMethods"/>
    </aop:config>

x一下就可以?br />


hk2000c 2007-11-30 14:01 发表评论
]]>
BO设计定稿http://m.tkk7.com/hk2000c/archive/2007/11/15/160825.htmlhk2000chk2000cThu, 15 Nov 2007 11:26:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/11/15/160825.htmlhttp://m.tkk7.com/hk2000c/comments/160825.htmlhttp://m.tkk7.com/hk2000c/archive/2007/11/15/160825.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/160825.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/160825.html
{过些时候重新审视自q设计再说




hk2000c 2007-11-15 19:26 发表评论
]]>
一般性data bind 程 http://m.tkk7.com/hk2000c/archive/2007/11/12/159848.htmlhk2000chk2000cSun, 11 Nov 2007 21:22:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/11/12/159848.htmlhttp://m.tkk7.com/hk2000c/comments/159848.htmlhttp://m.tkk7.com/hk2000c/archive/2007/11/12/159848.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/159848.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/159848.htmlorg.springframework.web.bind.ServletRequestDataBinder@27ca12


DataBinder: applyPropertyValues(MutablePropertyValues mpvs)


org.springframework.beans.BeanWrapperImpl: wrapping object [com.unitedbiz.model.User@996f0e]
AbstractPropertyAccessor::setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)

 

org.springframework.beans.BeanWrapperImpl: wrapping object [com.unitedbiz.model.User@996f0e]::setPropertyValue(PropertyValue pv)

 



hk2000c 2007-11-12 05:22 发表评论
]]>
filter 位置不能颠?/title><link>http://m.tkk7.com/hk2000c/archive/2007/11/08/159149.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Thu, 08 Nov 2007 11:29:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2007/11/08/159149.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/159149.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2007/11/08/159149.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/159149.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/159149.html</trackback:ping><description><![CDATA[<p>filter 位置不能颠?/p> <p>一般位|顺序ؓ</p> <p>encoding</p> <p>hibernate</p> <p><font face="Arial">localeFilter</font></p> <p><font face="Arial">securityFilter</font></p> <p><font face="Arial">sitemesh</font></p> <img src ="http://m.tkk7.com/hk2000c/aggbug/159149.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2007-11-08 19:29 <a href="http://m.tkk7.com/hk2000c/archive/2007/11/08/159149.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在validation.xml中进行相关的验证配置http://m.tkk7.com/hk2000c/archive/2007/11/08/158969.htmlhk2000chk2000cWed, 07 Nov 2007 17:10:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/11/08/158969.htmlhttp://m.tkk7.com/hk2000c/comments/158969.htmlhttp://m.tkk7.com/hk2000c/archive/2007/11/08/158969.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/158969.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/158969.html <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE form-validation PUBLIC "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.0//EN" "validator_1_0.dtd" >
<form-validation>
<formset>
<form name="loginForm">//struts-config.xml中formBean的名?br /> <field property="username" depends="required,maxlength,minlength">
//property相关验证字段的名Uͼdepends所对应的验证器
<arg0 key="用户? resource="false"/>
//当resource为TRUEӞ表示使用来自resource Bundle中的消息Q反之指定key中消?br /> <arg1 name="maxlength" resource="false" key="${var:maxlength}"/>
<var>
<var-name>maxlength</var-name>
<var-value>8</var-value>
</var>
<arg2 name="minlength" resource="false" key="${var:minlength}"/>
<var>
<var-name>minlength</var-name>
<var-value>2</var-value>
</var>

</field>
</form>
</formset>

所注意的问题:1、如<arg0 key="用户? resource="false"/>在arg0中如果不讄验证器,那么p所有的验证器通用
2、如<arg1 name="maxlength" resource="false" key="${var:maxlength}"/>中的arg1要与错误信息中所对应的该验证器的参数一臻Ierrors.maxlength={0} can not be greater than {1} characters.Q?br /> 如果Qerrors.maxlength={0} can not be greater than {2} characters.Q的话,那么必d2改ؓ1

7.jsp中的前台验证Q?br /> <htm:form arction =”” onsubmit=” return validateLoginForm(this) ”>
<html:javascript formName="loginForm"/>
//对应formBean的名?br />

hk2000c 2007-11-08 01:10 发表评论
]]>
OSCache 避免死锁http://m.tkk7.com/hk2000c/archive/2007/11/07/158791.htmlhk2000chk2000cWed, 07 Nov 2007 05:09:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/11/07/158791.htmlhttp://m.tkk7.com/hk2000c/comments/158791.htmlhttp://m.tkk7.com/hk2000c/archive/2007/11/07/158791.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/158791.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/158791.html
在正常更?cache 后, 不要调用 

               cache.cancelUpdate(url);

Ҏ


否则会引Ll死?br />




hk2000c 2007-11-07 13:09 发表评论
]]>
详解spring事务属?http://m.tkk7.com/hk2000c/archive/2007/11/01/157521.htmlhk2000chk2000cThu, 01 Nov 2007 08:13:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/11/01/157521.htmlhttp://m.tkk7.com/hk2000c/comments/157521.htmlhttp://m.tkk7.com/hk2000c/archive/2007/11/01/157521.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/157521.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/157521.htmlSpring声明式事务让我们从复杂的事务处理中得到解脱。得我们再也无需要去处理获得q接、关闭连接、事务提交和回滚{这些操作。再也无需要我们在与事务相关的Ҏ中处理大量的try…catch…finally代码?
我们在用Spring声明式事务时Q有一个非帔R要的概念是事务属性。事务属性通常׃务的传播行ؓQ事务的隔离U别Q事务的时值和事务只读标志l成。我们在q行事务划分Ӟ需要进行事务定义,也就是配|事务的属性?
Spring?strong>TransactionDefinition接口中定义这些属?以供PlatfromTransactionManager使用, PlatfromTransactionManager是spring事务理的核心接口?
代码
  1. TransactionDefinition   
  2. public interface TransactionDefinition {   
  3.     int getPropagationBehavior();   
  4.     int getIsolationLevel();   
  5.     int getTimeout();   
  6.     boolean isReadOnly();   
  7. }  

 

getTimeout()ҎQ它q回事务必须在多秒内完成?
isReadOnly(),事务是否只读Q事务管理器能够Ҏq个q回D行优化,保事务是只ȝ?
getIsolationLevel()Ҏq回事务的隔ȝ别,事务理器根据它来控制另外一个事务可以看到本事务内的哪些数据?/p>

在TransactionDefinition接口中定义了五个不同的事务隔ȝ?
ISOLATION_DEFAULT q是一个PlatfromTransactionManager默认的隔ȝ别,使用数据库默认的事务隔离U别.另外四个与JDBC的隔ȝ别相对应
ISOLATION_READ_UNCOMMITTED q是事务最低的隔离U别Q它充许别外一个事务可以看到这个事务未提交的数据。这U隔ȝ别会产生脏读Q不可重复读和像读?
例如:
Mary的原工资?000,财务人员Mary的工资改Z8000Q但未提交事?

代码
  1. Connection con1 = getConnection();   
  2. con.setAutoCommit(false);   
  3. update employee set salary = 8000 where empId ="Mary";  

与此同时QMary正在d自己的工?
代码
  1. Connection con2 = getConnection();   
  2. select  salary from employee where empId ="Mary";   
  3. con2.commit();  

 

Mary发现自己的工资变Z8000Q欢天喜圎ͼ
而胦务发现操作有误,而回滚了事务,Mary的工资又变ؓ?000

代码
  1. //con1   
  2.   con1.rollback();  

像这?Mary记取的工资数8000是一个脏数据?

 

ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这U事务隔ȝ别可以避免脏d玎ͼ但是可能会出C可重复读和像读?/p>

ISOLATION_REPEATABLE_READ q种事务隔离U别可以防止脏读Q不可重复读。但是可能出现像读。它除了保证一个事务不能读取另一个事务未提交的数据外Q还保证了避免下面的情况产生(不可重复??/p>

在事?中,Mary d了自q工资?000,操作q没有完?

代码
  1. con1 = getConnection();   
  2. select salary from employee empId ="Mary";  

 

在事?中,q时财务人员修改了Mary的工资ؓ2000,q提交了事务.

代码
  1. con2 = getConnection();   
  2. update employee set salary = 2000;   
  3. con2.commit();  

 

在事?中,Mary 再次d自己的工资时Q工资变Z2000

代码
  1. //con1   
  2. select salary from employee empId ="Mary";  

 

在一个事务中前后两次d的结果ƈ不致Q导致了不可重复诅R?
使用ISOLATION_REPEATABLE_READ可以避免q种情况发生?/p>

ISOLATION_SERIALIZABLE q是p最高代价但是最可靠的事务隔ȝ别。事务被处理为顺序执行。除了防止脏读,不可重复dQ还避免了像读?/p>

目前工资?000的员工有10人?
事务1,d所有工资ؓ1000的员工?

代码
  1. con1 = getConnection();   
  2. Select * from employee where salary =1000;  
p?0条记?

 

q时另一个事务向employee表插入了一条员工记录,工资也ؓ1000

代码
  1. con2 = getConnection();   
  2. Insert into employee(empId,salary) values("Lili",1000);   
  3. con2.commit();  

 

事务1再次d所有工资ؓ1000的员?

代码
  1. //con1   
  2. select * from employee where salary =1000;  

 

p取到?1条记录,q就产生了像读?
ISOLATION_SERIALIZABLE能避免这L情况发生。但是这样也耗费了最大的资源?/p>

getPropagationBehavior()q回事务的传播行为,由是否有一个活动的事务来决定一个事务调用?/p>

在TransactionDefinition接口中定义了七个事务传播行ؓ?/p>

PROPAGATION_REQUIRED 如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务?/p>

代码
  1. //事务属?nbsp;PROPAGATION_REQUIRED   
  2. methodA{   
  3. ……   
  4. methodB();   
  5. ……   
  6. }   
  7.   
  8. //事务属?nbsp;PROPAGATION_REQUIRED   
  9. methodB{   
  10.    ……   
  11. }  

使用spring声明式事务,spring使用AOP来支持声明式事务Q会Ҏ事务属性,自动在方法调用之前决定是否开启一个事务,q在Ҏ执行之后军_事务提交或回滚事务?

 

单独调用methodBҎ

代码
  1. main{   
  2.   metodB();   
  3. }  

相当?
代码
  1. Main{   
  2. Connection con=null;   
  3.   
  4.    rry{   
  5.       con = getConnection();   
  6.       con.setAutoCommit(false);   
  7. //Ҏ调用   
  8. methodB();   
  9. //提交事务   
  10. con.commit();   
  11. }   
  12. Catch(RuntimeException ex){   
  13.   //回滚事务   
  14.   con.rollback();     
  15. }   
  16. finally{   
  17.   //释放资源   
  18.   closeCon();   
  19. }   
  20. }  

Spring保证在methodBҎ中所有的调用都获得到一个相同的q接。在调用methodBӞ没有一个存在的事务Q所以获得一个新的连接,开启了一个新的事务?

 

单独调用MethodAӞ在MethodA内又会调用MethodB.

执行效果相当?

代码
  1. main{   
  2.    Connection con = null;   
  3.    try{   
  4.       con = getConnection();   
  5.       methodA();   
  6.       con.commit();   
  7. }   
  8. cathc(RuntimeException ex){   
  9.  con.rollback();   
  10. }   
  11. finally{   
  12.   closeCon();   
  13. }    
  14. }  

调用MethodAӞ环境中没有事务,所以开启一个新的事?
当在MethodA中调用MethodBӞ环境中已l有了一个事务,所以methodB加入当前事务?

 

PROPAGATION_SUPPORTS 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。但是对于事务同步的事务理器,PROPAGATION_SUPPORTS与不使用事务有少怸同?/p>

代码
  1. //事务属?nbsp;PROPAGATION_REQUIRED    
  2. methodA(){   
  3.   methodB();   
  4. }   
  5.   
  6. //事务属?nbsp;PROPAGATION_SUPPORTS    
  7. methodB(){   
  8.   ……   
  9. }  

单纯的调用methodBӞmethodBҎ是非事务的执行的?
当调用methdA?methodB则加入了methodA的事务中,事务地执行?

 

PROPAGATION_MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务Q则抛出异常?/p>

代码
  1. //事务属?nbsp;PROPAGATION_REQUIRED    
  2. methodA(){   
  3.   methodB();   
  4. }   
  5.   
  6. //事务属?nbsp;PROPAGATION_MANDATORY    
  7. methodB(){   
  8.   ……   
  9. }  

当单独调用methodBӞ因ؓ当前没有一个活动的事务Q则会抛出异?
throw new IllegalTransactionStateException("Transaction propagation 'mandatory' but no existing transaction found");

 

当调用methodAӞmethodB则加入到methodA的事务中Q事务地执行?/p>

PROPAGATION_REQUIRES_NEW L开启一个新的事务。如果一个事务已l存在,则将q个存在的事务挂赗?/p>

代码
  1. //事务属?nbsp;PROPAGATION_REQUIRED    
  2. methodA(){   
  3.   doSomeThingA();   
  4. methodB();   
  5. doSomeThingB();   
  6. }   
  7.   
  8. //事务属?nbsp;PROPAGATION_REQUIRES_NEW    
  9. methodB(){   
  10.   ……   
  11. }  

当单独调用methodBӞ相当于把methodb声明为REQUIRED。开启一个新的事务,事务地执行?

 

当调用methodA?

代码
  1. main(){   
  2.   methodA();   
  3. }  
情况有些大不一?相当于下面的效果?
代码
  1. main(){   
  2.  TransactionManager tm = null;   
  3. try{   
  4.   //获得一个JTA事务理?  
  5.    tm = getTransactionManager();   
  6.    tm.begin();//开启一个新的事?  
  7.    Transaction ts1 = tm.getTransaction();   
  8.    doSomeThing();   
  9.    tm.suspend();//挂v当前事务   
  10.    try{   
  11.      tm.begin();//重新开启第二个事务   
  12.      Transaction ts2 = tm.getTransaction();   
  13.      methodB();   
  14.      ts2.commit();//提交W二个事?  
  15.         
  16.    }   
  17.   Catch(RunTimeException ex){   
  18.      ts2.rollback();//回滚W二个事?  
  19.   }   
  20.   finally{   
  21.     //释放资源   
  22.   }   
  23.    //methodB执行完后Q复恢第一个事?  
  24.    tm.resume(ts1);   
  25. doSomeThingB();   
  26.    ts1.commit();//提交W一个事?  
  27. }   
  28. catch(RunTimeException ex){   
  29.   ts1.rollback();//回滚W一个事?  
  30. }   
  31. finally{   
  32.   //释放资源   
  33. }   
  34. }  

在这里,我把ts1UCؓ外层事务Qts2UCؓ内层事务。从上面的代码可以看出,ts2与ts1是两个独立的事务Q互不相qӀTs2是否成功q不依赖于ts1。如果methodAҎ在调用methodBҎ后的doSomeThingBҎp|了,而methodBҎ所做的l果依然被提交。而除了methodB之外的其它代码导致的l果却被回滚了?
使用PROPAGATION_REQUIRES_NEW,需要用JtaTransactionManager作ؓ事务理器?

 

PROPAGATION_NOT_SUPPORTED L非事务地执行Qƈ挂vM存在的事务?/p>

代码
  1. //事务属?nbsp;PROPAGATION_REQUIRED    
  2. methodA(){   
  3.   doSomeThingA();   
  4. methodB();   
  5. doSomeThingB();   
  6. }   
  7.   
  8. //事务属?nbsp;PROPAGATION_NOT_SUPPORTED    
  9. methodB(){   
  10.   ……   
  11. }  

当单独调用methodBӞ不启用Q何事务机Ӟ非事务地执行?
当调用methodAӞ相当于下面的效果

 

代码
  1. main(){   
  2.  TransactionManager tm = null;   
  3. try{   
  4.   //获得一个JTA事务理?  
  5.    tm = getTransactionManager();   
  6.    tm.begin();//开启一个新的事?  
  7.    Transaction ts1 = tm.getTransaction();   
  8.    doSomeThing();   
  9.    tm.suspend();//挂v当前事务   
  10.      methodB();   
  11.    //methodB执行完后Q复恢第一个事?  
  12.    tm.resume(ts1);   
  13. doSomeThingB();   
  14.    ts1.commit();//提交W一个事?  
  15. }   
  16. catch(RunTimeException ex){   
  17.   ts1.rollback();//回滚W一个事?  
  18. }   
  19. finally{   
  20.   //释放资源   
  21. }   
  22. }  
使用PROPAGATION_NOT_SUPPORTED,也需要用JtaTransactionManager作ؓ事务理器?

 

PROPAGATION_NEVER L非事务地执行Q如果存在一个活动事务,则抛出异?/p>

代码
  1. //事务属?nbsp;PROPAGATION_REQUIRED    
  2. methodA(){   
  3.   doSomeThingA();   
  4. methodB();   
  5. doSomeThingB();   
  6. }   
  7.   
  8. //事务属?nbsp;PROPAGATION_NEVER    
  9. methodB(){   
  10.   ……   
  11. }  
单独调用methodBQ则非事务的执行?
调用methodA则会抛出异常
throw new IllegalTransactionStateException(
"Transaction propagation 'never' but existing transaction found");

 

PROPAGATION_NESTED如果一个活动的事务存在Q则q行在一个嵌套的事务? 如果没有zd事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执?/p>

q是一个嵌套事?使用JDBC 3.0驱动?仅仅支持DataSourceTransactionManager作ؓ事务理器。需要JDBC 驱动的java.sql.SavepointcR有一些JTA的事务管理器实现可能也提供了同样的功能?/p>

使用PROPAGATION_NESTEDQ还需要把PlatformTransactionManager的nestedTransactionAllowed属性设为true;
而nestedTransactionAllowed属性值默认ؓfalse;

代码
  1. //事务属?nbsp;PROPAGATION_REQUIRED    
  2. methodA(){   
  3.   doSomeThingA();   
  4. methodB();   
  5. doSomeThingB();   
  6. }   
  7.   
  8. //事务属?nbsp;PROPAGATION_NESTED   
  9. methodB(){   
  10.   ……   
  11. }  

如果单独调用methodBҎQ则按REQUIRED属性执行?

 

如果调用methodAҎQ相当于下面的效?

代码
  1. main(){   
  2. Connection con = null;   
  3. Savepoint savepoint = null;   
  4. try{   
  5.   con = getConnection();   
  6.   con.setAutoCommit(false);   
  7.   doSomeThingA();   
  8.   savepoint = con2.setSavepoint();   
  9.   try  
  10.       methodB();   
  11.   }catch(RuntimeException ex){   
  12.      con.rollback(savepoint);   
  13.   }   
  14.   finally{   
  15.     //释放资源   
  16.   }   
  17.   
  18.   doSomeThingB();   
  19.   con.commit();   
  20. }   
  21. catch(RuntimeException ex){   
  22.   con.rollback();   
  23. }   
  24. finally{   
  25.   //释放资源   
  26. }   
  27. }  
当methodBҎ调用之前Q调用setSavepointҎQ保存当前的状态到savepoint。如果methodBҎ调用p|Q则恢复C前保存的状态。但是需要注意的是,q时的事务ƈ没有q行提交Q如果后l的代码(doSomeThingB()Ҏ)调用p|Q则回滚包括methodBҎ的所有操作?

 

嵌套事务一个非帔R要的概念是内层事务依赖于外层事务。外层事务失败时Q会回滚内层事务所做的动作。而内层事务操作失败ƈ不会引v外层事务的回?/strong>?/p>

PROPAGATION_NESTED 与PROPAGATION_REQUIRES_NEW的区?/strong>:它们非常cM,都像一个嵌套事务,如果不存在一个活动的事务Q都会开启一个新的事务。用PROPAGATION_REQUIRES_NEWӞ内层事务与外层事务就像两个独立的事务一P一旦内层事务进行了提交后,外层事务不能对其q行回滚。两个事务互不媄响。两个事务不是一个真正的嵌套事务。同时它需要JTA事务理器的支持?
使用PROPAGATION_NESTEDӞ外层事务的回滚可以引起内层事务的回滚。而内层事务的异常q不会导致外层事务的回滚Q它是一个真正的嵌套事务。DataSourceTransactionManager使用savepoint支持PROPAGATION_NESTEDӞ需要JDBC 3.0以上驱动?.4以上的JDK版本支持。其它的JTA TrasactionManager实现可能有不同的支持方式?/p>

PROPAGATION_REQUIRED应该是我们首先的事务传播行ؓ。它能够满我们大多数的事务需求?/p>

hk2000c 2007-11-01 16:13 发表评论
]]>
Spring配置事务在DAO层和业务逻辑?http://m.tkk7.com/hk2000c/archive/2007/11/01/157508.htmlhk2000chk2000cThu, 01 Nov 2007 07:38:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/11/01/157508.htmlhttp://m.tkk7.com/hk2000c/comments/157508.htmlhttp://m.tkk7.com/hk2000c/archive/2007/11/01/157508.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/157508.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/157508.htmlSpring通过AOP实现声明式事务管理。通常通过TransactionProxyFactoryBeanSpring事务代理。我们需要一个目标对象包装在事务代理中。这个目标对象一般是一个普?/span>Java对象?/span>bean。当我们定义TransactionProxyFactoryBeanӞ必须提供一个相关的 PlatformTransactionManager的引用和事务属性?/span> 事务属性含有上面描q的事务定义?/span>

PlatformTransactionManagerQ?/span>

HibernateTransactionManager需要一?/span>SessionFactory的引?/span>

JtaTransactionManager

一Q把事务攄在了DAO层:

<!—hibernateTransactionManager-->

<bean id="transactionManager"

       class="org.springframework.orm.hibernate3.HibernateTransactionManager">

       <property name="sessionFactory">

              <ref local="sessionFactory" />

       </property>

</bean>

<!—DAO层接口实?/span>-->

<bean id="companyDAOTarget"

       class="com.vstsoft.querycompany.dao.impl.CompanyDAOImpl">

       <property name="sessionFactory">

              <ref local="sessionFactory" />

       </property>

</bean>

<!—spring?/span>DAO层的事务代理-->

<bean id="companyDAOProxy"

       class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

       <property name="transactionManager">

              <ref bean="transactionManager" />

       </property>

       <property name="target">

              <ref local="companyDAOTarget" />

       </property>

       <property name="transactionAttributes">

              <props>

              <prop key="insert*">PROPAGATION_REQUIRED</prop>

              <prop key="delete*">PROPAGATION_REQUIRED</prop>

              <prop key="find*">

              PROPAGATION_REQUIRED,readOnly

              </prop>

              </props>

       </property>

</bean>

<!?span style="font-family: 宋体">业务层接口实玎ͼ?/span>DAO注入?/span>Service里面-->

<bean name="companyManageTarget"

       class="com.vstsoft.querycompany.service.impl.CompanyManageTarget">

       <property name="companyDAO">

              <ref bean="companyDAOProxy" />

       </property>

</bean>

<!—spring?/span>Service层的代理-->

<bean id="companyManageProxy"

       class="org.springframework.aop.framework.ProxyFactoryBean">

       <property name="proxyInterfaces">

              <value>com.vstsoft.querycompany.service.CompanyManage</value>

       </property>

       <property name="target">

              <ref bean="companyManageTarget" />

       </property>

</bean>

<!?span style="font-family: 宋体">配置struts讉KQ把service层注入到action里面-->

<bean name="/company"

       class="com.vstsoft.querycompany.web.action.CompanyAction" singleton="false">

       <property name="companyManage">

              <ref local="companyManageProxy" />

       </property>

</bean>

二.把事务放|在?/span>Service层:

<!—jtaTransactionManager-->

<bean id="jtaTransactionManager"

       class="org.springframework.transaction.jta.JtaTransactionManager" />

<!—DAO层接口实?/span>-->

<bean id="companyDAOTarget"

       class="com.vstsoft.querycompany.dao.impl.CompanyDAOImpl">

       <property name="sessionFactory">

              <ref local="sessionFactory" />

       </property>

</bean>

<!—spring?/span>DAO层的代理-->

<bean id="companyDAOProxy"

       class="org.springframework.aop.framework.ProxyFactoryBean">

       <property name="proxyInterfaces">

              <value>com.vstsoft.querycompany.dao.CompanyDAO</value>

       </property>

       <property name="target">

              <ref bean="companyDAOTarget" />

       </property>

</bean>

<!?span style="font-family: 宋体">业务层接口实玎ͼ?/span>DAO注入?/span>Service里面-->

<bean name="companyManageTarget"

       class="com.vstsoft.querycompany.service.impl.CompanyManageTarget">

       <property name="companyDAO">

              <ref bean="companyDAOProxy" />

       </property>

</bean>

<!—spring代理业务层的事务理-->

<bean id="companyManageProxy"

       class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

       <property name="transactionManager">

              <ref local="jtaTransactionManager" />

       </property>

       <property name="transactionAttributes">

              <props>

                     <prop key="set*">PROPAGATION_REQUIRED</prop>

                     <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>

              </props>

       </property>

       <property name="target">

              <ref bean="companyManageTarget" />

       </property>

</bean>

<!?span style="font-family: 宋体">配置struts讉KQ把service层注入到action里面-->

<bean name="/company"

       class="com.vstsoft.querycompany.web.action.CompanyAction" singleton="false">

       <property name="companyManage">

              <ref local="companyManageProxy" />

       </property>

</bean>

?/span>service层的接口实现CompanyManageImpl里面有个setDataҎQ按序执行数据查询Q数据删除,数据插入数据库行为,如果哪一步出异常Q运行时异常Q,事务回滚Q只有所有行为都没成功,事务提交?/span>



hk2000c 2007-11-01 15:38 发表评论
]]>
spring事务探烦 [转]http://m.tkk7.com/hk2000c/archive/2007/11/01/157362.htmlhk2000chk2000cWed, 31 Oct 2007 17:36:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/11/01/157362.htmlhttp://m.tkk7.com/hk2000c/comments/157362.htmlhttp://m.tkk7.com/hk2000c/archive/2007/11/01/157362.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/157362.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/157362.htmlspring自徏事务理模块。而且q个事务理是一个抽象设计,可以应用到很多场合,包括普通的DataSourceQjtaQjms和hibernate上?nbsp;

要正用spring的事务,首先需要了解spring在事务设计上的一些概?nbsp;
l观spring事务Q围l着两个核心PlatformTransactionManager和TransactionStatus

PlatformTransactionManager 直译q来是q_相关事务Q这里的q_指的?#8220;事务?#8221;Q包括刚才我说的DataSourceQjta{等。这些无一不是一个事务源。广义的_凡是可以完成事务性操作的对象Q都可以设计出相对应的PlatformTransactionManagerQ只要这个事务源支持commitQrollback 和getTransaction语意?

查看spring代码Q可以发现这些manager实现事务Q就是调用事务源的事务操作方?

比如

HibernateTransactionManager
java代码:

protected void doCommit(DefaultTransactionStatus status) {
HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();
if (status.isDebug()) {
logger.debug("Committing Hibernate transaction on session [" +
txObject.getSessionHolder().getSession() + "]";
}
try {
txObject.getSessionHolder().getTransaction().commit();
}
...

}

 

jdbc 的DataSourceTransactionManager
java代码:

protected void doCommit(DefaultTransactionStatus status) {
DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
Connection con = txObject.getConnectionHolder().getConnection();
if (status.isDebug()) {
logger.debug("Committing JDBC transaction on connection [" + con + "]";
}
try {
con.commit();
}
...
}

 

那么PlatformTransactionManager以什么依据处理事务呢Q?
是TransactionStatus
查看api发现q个接口有三个方?
isNewTransaction() QisRollbackOnly()QsetRollbackOnly()
PlatformTransactionManager 是Ҏ前两个方法决定是否要创徏一个新事务Q是要递交q是回滚。至于第三个Ҏ是改变事务当前状态的Q很多地斚w要用刎ͼ偏偏 PlatformTransactionManager自n好像不怎么用,毕竟事务状态的改变是由E序员代码决定的Q不需要一个manager多管闲事?

ȝ上面所说的Qspring的事务由PlatformTransactionManager理Qmanager最后调用事务源的方法来实现一个事务过E。而manager通过TransactionStatus 来决定如何实现?

接下去说spring事务中的TransactionTemplate和TransactionInterceptor

TransactionTemplate 其实和spring中其他的template的作用类|起到化简代码的作用,不要被它那么长的名字吓倒了Q事实上q个templateq不是什么非常核心的对象。如果比较学I派的,可以ȝ看template设计模式Q在此就不再Ҏ赘述了?
Z么要有TransactionTemplateQ先来看看如果没有TransactionTemplateQ我们的代码该怎么?

先来看看spring reference中的一D代?
java代码:

DefaultTransactionDefinition def = new DefaultTransactionDefinition()
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

TransactionStatus status = transactionManager.getTransaction(def);

try {
// execute your business logic here
} catch (MyException ex) {
transactionManager.rollback(status);
throw ex;
}
transactionManager.commit(status);

q是直接使用transactionManager的例子,可以看到真正执行business logic 的地Ҏ在try当中那段Q前后的代码都是Z完成事务理的。如果每个business logic都要写上那么一D,我肯定是疯了。我们翻出TransactionTemplate的代码看看他怎么化简了我们的代码

java代码:

public Object execute(TransactionCallback action) throws TransactionException {
TransactionStatus status = this.transactionManager.getTransaction(this);
Object result = null;
try {
result = action.doInTransaction(status);
}
catch (RuntimeException ex) {
// transactional code threw application exception -> rollback
rollbackOnException(status, ex);
throw ex;
}
catch (Error err) {
// transactional code threw error -> rollback
rollbackOnException(status, err);
throw err;
}
this.transactionManager.commit(status);
return result;
}


同上面的代码如出一辙,前后是事务处理代码,当中那段result = action.doInTransaction(status);是我们的应用代码。至于action是什么,全看各位的需要了。但是有一点要主要Q如果利用TransactionTemplateQ那么他不管你扔Z么异帔R会回滚事务,但是回滚的是哪个事务呢?l箋挖代?
java代码:

private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {
if (logger.isDebugEnabled()) {
logger.debug("Initiating transaction rollback on application exception", ex);
}
try {
this.transactionManager.rollback(status);
}
catch (RuntimeException ex2) {
logger.error("Application exception overridden by rollback exception", ex);
throw ex2;
}
catch (Error err) {
logger.error("Application exception overridden by rollback error", ex);
throw err;
}
}

真相大白Q是对template所持有的某个transactionManagerq行回滚。所以如果你的应用代码用的是事务源a的一些资源,比如到服务器 a的一个datasourceQ但是你的transactionManager理的是另一些资源,比如服务器b的一个datasourceQ代码铁定不会正常运?

特别是在一些多事务源的E序里,q点千万不能搞错。如果多个事务源之间要完成全局事务Q还是老老实实用分布式事务管理服务吧QjtaQ?

那么TransactionInterceptor是干什么的Q这个是spring 的声明式事务的支持方式。因为用 TransactionTemplate要硬~码Q而且调整事务{略很麻烦(不是说不能调。D个例子原来程序抛出异常A需要回滚,现在不需要要Q我可以把a catch吃掉。这时候template׃会回滚了。但是每ơ调整都要重写编码。)而用TransactionInterceptor可以将q些调整写在配置中。我们再来挖TransactionInterceptor的代?

java代码:

public Object invoke(MethodInvocation invocation) throws Throwable {
// Work out the target class: may be null.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface
Class targetClass = (invocation.getThis() != null) ? invocation.getThis().getClass() : null;

// Create transaction if necessary
TransactionInfo txInfo = createTransactionIfNecessary(invocation.getMethod(), targetClass);

Object retVal = null;
try {
// This is an around advice.
// Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
retVal = invocation.proceed();
}
catch (Throwable ex) {
// target invocation exception
doCloseTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
doFinally(txInfo);
}
doCommitTransactionAfterReturning(txInfo);

return retVal;
}

万变不离其宗?

所以用spring的事务管理需要作q些?
1Q设|好事务源,比如DataSourceQhibernate的session。如果有多个事务源要考虑他们之间是否有全局事务Q如果有Q老老实实用jtaQ否则就需要自己写一个manager?
2Q设|managerQ根据你的事务源选择对应的PlatformTransactionManager
3Q选择实现事物的方式,用templateq是interceptor。用template代码直观点,但是template所辖的manager和你应用代码所用的事务源要一致。如果用interceptor千万注意Q一定要调用interceptor那个beanQ而不是原始的那个target。在坛子上我已经看到臛_有两个朋友说spring事物不v作用Q从配置和代码上看都正确Q这时要好好查查Q调用的bean是哪一个?
4Q这个是设计问题了,推荐事务处于一个较高层ơ,比如service上的某个函数Q而底层的dao可以不考虑事务Q否则可能会出现事务嵌套Q增加程序复杂度?/p>



hk2000c 2007-11-01 01:36 发表评论
]]>
spring 事务支持http://m.tkk7.com/hk2000c/archive/2007/11/01/157359.htmlhk2000chk2000cWed, 31 Oct 2007 16:41:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/11/01/157359.htmlhttp://m.tkk7.com/hk2000c/comments/157359.htmlhttp://m.tkk7.com/hk2000c/archive/2007/11/01/157359.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/157359.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/157359.html


hk2000c 2007-11-01 00:41 发表评论
]]>
spring bean l承父类propertyҎ http://m.tkk7.com/hk2000c/archive/2007/10/31/157232.htmlhk2000chk2000cWed, 31 Oct 2007 08:32:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/10/31/157232.htmlhttp://m.tkk7.com/hk2000c/comments/157232.htmlhttp://m.tkk7.com/hk2000c/archive/2007/10/31/157232.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/157232.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/157232.htmlxxActionl承BaseAction,BaseAction注入了一个CommonManagerQBaseAction.commonSave()Ҏ调用了commonManager?/p>

本来想xxAction调用父类的commonSaveҎ会DcommonManager为null的错误,因ؓjvmd始化BaseAction时ƈ不会L入CommonManger?
其实解决q个问题只需要在子类xxAction bean配置文g中加上commonManagerq个propertyQ然后把父类BaseAction的commonManager 改ؓprotected?Ok了。这样初始化子类的时候会注入commonManagerQ调用commonSaveҎ也就不会抛出npe了?/p>

配置文g中把xxAction 加上parent的配|也是可以的Q这样会把父cȝ所有property都注?/p>

hk2000c 2007-10-31 16:32 发表评论
]]>
增加CMS static page 预读功能http://m.tkk7.com/hk2000c/archive/2007/10/31/157076.htmlhk2000chk2000cTue, 30 Oct 2007 16:22:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/10/31/157076.htmlhttp://m.tkk7.com/hk2000c/comments/157076.htmlhttp://m.tkk7.com/hk2000c/archive/2007/10/31/157076.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/157076.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/157076.html 增加CMS static page 预读功能



hk2000c 2007-10-31 00:22 发表评论
]]>
用户密码使用动态密钥SHA-512位加?/title><link>http://m.tkk7.com/hk2000c/archive/2007/10/30/156924.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Tue, 30 Oct 2007 06:17:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2007/10/30/156924.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/156924.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2007/10/30/156924.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/156924.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/156924.html</trackback:ping><description><![CDATA[用户密码使用动态密钥SHA-512位加?br /> <br /> <img src ="http://m.tkk7.com/hk2000c/aggbug/156924.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2007-10-30 14:17 <a href="http://m.tkk7.com/hk2000c/archive/2007/10/30/156924.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pȝ会给出step by step 的配|表?/title><link>http://m.tkk7.com/hk2000c/archive/2007/10/30/156912.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Tue, 30 Oct 2007 05:29:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2007/10/30/156912.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/156912.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2007/10/30/156912.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/156912.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/156912.html</trackback:ping><description><![CDATA[pȝ会给出step by step 的配|表?br /> <br /> 配置比如 密码密钥 {?关键数据 <br /> <br /> <br /> <img src ="http://m.tkk7.com/hk2000c/aggbug/156912.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2007-10-30 13:29 <a href="http://m.tkk7.com/hk2000c/archive/2007/10/30/156912.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>增加pȝ配置文ghttp://m.tkk7.com/hk2000c/archive/2007/10/30/156911.htmlhk2000chk2000cTue, 30 Oct 2007 05:23:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/10/30/156911.htmlhttp://m.tkk7.com/hk2000c/comments/156911.htmlhttp://m.tkk7.com/hk2000c/archive/2007/10/30/156911.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/156911.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/156911.html
?StartupListener ?nbsp;
 
每次重启d



hk2000c 2007-10-30 13:23 发表评论
]]>
支持动态读取系l配|Url列表http://m.tkk7.com/hk2000c/archive/2007/10/30/156910.htmlhk2000chk2000cTue, 30 Oct 2007 05:22:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/10/30/156910.htmlhttp://m.tkk7.com/hk2000c/comments/156910.htmlhttp://m.tkk7.com/hk2000c/archive/2007/10/30/156910.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/156910.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/156910.html 支持动态读取系l配|的url列表Q标Cؓ static , 权限可配|?br />  
攑֜ StartupListener 内?br />  
做到每次pȝ重启都自动更斎ͼ有校验匹配的功能?br />


hk2000c 2007-10-30 13:22 发表评论
]]>
增加用户名即时校验机?/title><link>http://m.tkk7.com/hk2000c/archive/2007/10/29/156703.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Mon, 29 Oct 2007 08:00:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2007/10/29/156703.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/156703.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2007/10/29/156703.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/156703.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/156703.html</trackback:ping><description><![CDATA[增加用户名即时校验机Ӟ可以x查询用户名是否被占用?br /> <br /> <img src ="http://m.tkk7.com/hk2000c/aggbug/156703.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2007-10-29 16:00 <a href="http://m.tkk7.com/hk2000c/archive/2007/10/29/156703.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>加紧开发用h?/title><link>http://m.tkk7.com/hk2000c/archive/2007/10/27/156370.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Sat, 27 Oct 2007 09:29:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2007/10/27/156370.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/156370.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2007/10/27/156370.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/156370.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/156370.html</trackback:ping><description><![CDATA[完成了灵z表单开发?br /> <br /> 加紧开发用h?修正用户列表Q用L辑,用户dQ数据库支持?br /> <br /> 开发好以后可以全面开发CMSpȝ了?br /> <br /> <br /> <br /> <br /> <img src ="http://m.tkk7.com/hk2000c/aggbug/156370.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2007-10-27 17:29 <a href="http://m.tkk7.com/hk2000c/archive/2007/10/27/156370.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>改进了spring 的校验机?/title><link>http://m.tkk7.com/hk2000c/archive/2007/10/26/156227.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Fri, 26 Oct 2007 10:35:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2007/10/26/156227.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/156227.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2007/10/26/156227.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/156227.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/156227.html</trackback:ping><description><![CDATA[改进了spring 的校验机?br /> <br /> 重写了几个类Q得应用程序更加自由,可以自定义formName,不用l定pojo名字?br /> <br /> <img src ="http://m.tkk7.com/hk2000c/aggbug/156227.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2007-10-26 18:35 <a href="http://m.tkk7.com/hk2000c/archive/2007/10/26/156227.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>BaseCommandController initApplicationContext() 分析http://m.tkk7.com/hk2000c/archive/2007/10/26/155990.htmlhk2000chk2000cThu, 25 Oct 2007 17:12:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/10/26/155990.htmlhttp://m.tkk7.com/hk2000c/comments/155990.htmlhttp://m.tkk7.com/hk2000c/archive/2007/10/26/155990.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/155990.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/155990.html
/**
  * Subclasses can override this for custom initialization behavior.
  * Gets called by <code>setApplicationContext</code> after setting the context instance.
  * <p>Note: Does </i>not</i> get called on reinitialization of the context
  * but rather just on first initialization of this object's context reference.
  * @throws ApplicationContextException in case of initialization errors
  * @throws BeansException if thrown by ApplicationContext methods
  * @see #setApplicationContext
  */
 protected void initApplicationContext() throws BeansException {
 }

愿意为子cd以把初始化bean 动作攑օ此方法,可以自定义一些动作?br />
我们再来看看调用
public final void setApplicationContext(ApplicationContext context) throws BeansException {
  if (context == null && !isContextRequired()) {
   // Reset internal context state.
   this.applicationContext = null;
   this.messageSourceAccessor = null;
  }
  else if (this.applicationContext == null) {
   // Initialize with passed-in context.
   if (!requiredContextClass().isInstance(context)) {
    throw new ApplicationContextException(
      "Invalid application context: needs to be of type [" + requiredContextClass().getName() + "]");
   }
   this.applicationContext = context;
   this.messageSourceAccessor = new MessageSourceAccessor(context);
   initApplicationContext();
  }
  else {
   // Ignore reinitialization if same context passed in.
   if (this.applicationContext != context) {
    throw new ApplicationContextException(
      "Cannot reinitialize with different application context: current one is [" +
      this.applicationContext + "], passed-in one is [" + context + "]");
   }
  }
 }

可以看到?ApplicationObjectSupport  ?setApplicationContext Ҏ调用
而此Ҏ?ApplicationContextAware 的唯一接口ҎQ?br />

public interface ApplicationContextAware {
 
 /**
  * Set the ApplicationContext that this object runs in.
  * Normally this call will be used to initialize the object.
  * <p>Invoked after population of normal bean properties but before an init callback such
  * as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
  * or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
  * {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
  * {@link MessageSourceAware}, if applicable.
  * @param applicationContext the ApplicationContext object to be used by this object
  * @throws ApplicationContextException in case of context initialization errors
  * @throws BeansException if thrown by application context methods
  * @see org.springframework.beans.factory.BeanInitializationException
  */
 void setApplicationContext(ApplicationContext applicationContext) throws BeansException;

}

此方法被 ApplicationContextAwareProcessor ?postProcessBeforeInitialization  调用
ApplicationContextAwareProcessor implements BeanPostProcessor 
 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  if (bean instanceof ResourceLoaderAware) {
   ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
  }
  if (bean instanceof ApplicationEventPublisherAware) {
   ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
  }
  if (bean instanceof MessageSourceAware) {
   ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
  }
  if (bean instanceof ApplicationContextAware) {
   ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
  }
  return bean;
 }





hk2000c 2007-10-26 01:12 发表评论
]]>
spring validator 分析http://m.tkk7.com/hk2000c/archive/2007/10/26/155989.htmlhk2000chk2000cThu, 25 Oct 2007 16:48:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/10/26/155989.htmlhttp://m.tkk7.com/hk2000c/comments/155989.htmlhttp://m.tkk7.com/hk2000c/archive/2007/10/26/155989.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/155989.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/155989.html?BaseCommandController Z
protected void initApplicationContext() {
  if (this.validators != null) {
   for (int i = 0; i < this.validators.length; i++) {
    if (this.commandClass != null && !this.validators[i].supports(this.commandClass))
     throw new IllegalArgumentException("Validator [" + this.validators[i] +
       "] does not support command class [" +
       this.commandClass.getName() + "]");
   }
  }
 }

子类配置如下

 <bean id="addNewsController" class="AddNewsController" scope="request">
        <property name="formView" value="/management/news/addNews"/>
        <property name="validator" ref="beanValidator"/>
        <property name="successView" value="forward:/management/news/newsList.html"/>
        <property name="commandClass" value="News"/>
        <property name="commandName" value="news"/>
    </bean>

public final void setValidator(Validator validator) {
  this.validators = new Validator[] {validator};
 }

讄Validator数组

在初始化的时候,?是否支持command cd
this.validators[i].supports(this.commandClass)

此support ?org.springframework.validation.Validator 的所?实现cȝ ҎQ检验支持检验类的动作?br />

举例 配置
 <bean id="beanValidator" class="org.springmodules.validation.commons.DefaultBeanValidator">
        <property name="validatorFactory" ref="validatorFactory"/>
    </bean>

DefaultBeanValidator extends AbstractBeanValidator implements Validator

再看实现Ҏ

   /**
     * Checks if the validatorFactory is configured to handle this class.  Will
     * convert the class into a form name, suitable for commons validator.
     *
     * @return <code>true</code> if the validatorFactory supports the class,
     *         or <code>false</code> if not
     * @see #getFormName(Class)
     */
    public boolean supports(Class clazz) {
        boolean canSupport = validatorFactory.hasRulesForBean(getFormName(clazz), getLocale());
        if (log.isDebugEnabled()) {
            log.debug("validatorFactory " + (canSupport ? "does" : "does not")
                + " support class " + clazz + " with form name " + getFormName(clazz));
        }
        return canSupport;
    }

验是否支持输入类

另一个方?br />  /**
     * If <code>useFullyQualifiedClassName</code> is false (default value), this function returns a
     * string containing the uncapitalized, short name for the given class
     * (e.g. myBean for the class com.domain.test.MyBean). Otherwise, it  returns the value
     * returned by <code>Class.getName()</code>.
     *
     * @param cls <code>Class</code> of the bean to be validated.
     * @return the bean name.
     */
    protected String getFormName(Class cls) {
        return (this.useFullyQualifiedClassName) ? cls.getName() : Introspector.decapitalize(ClassUtils.getShortName(cls));
    }
 Introspector.decapitalize(ClassUtils.getShortName(cls) 获得按照西班牙命名法的form ?

q个Ҏ本意是获得以cd为formName 的所有校验配|?br />
实际上有一个重大的设计~陷








hk2000c 2007-10-26 00:48 发表评论
]]>
q要增加command 的记忆功?/title><link>http://m.tkk7.com/hk2000c/archive/2007/10/25/155903.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Thu, 25 Oct 2007 09:01:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2007/10/25/155903.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/155903.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2007/10/25/155903.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/155903.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/155903.html</trackback:ping><description><![CDATA[q要增加command 的记忆功能,主要是ؓ了表单验证失败以后,在服务器端控制表单内容不丢失问题?br /> <br /> <img src ="http://m.tkk7.com/hk2000c/aggbug/155903.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2007-10-25 17:01 <a href="http://m.tkk7.com/hk2000c/archive/2007/10/25/155903.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://m.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://www-554757.com" target="_blank">ŮƵ77777</a>| <a href="http://senimei9.com" target="_blank">˳վþ99ȹ</a>| <a href="http://ddm88888.com" target="_blank">޾ƷóƬAV߲ </a>| <a href="http://815389.com" target="_blank">һŮëƬ</a>| <a href="http://612662.com" target="_blank">޾ƷƷ벻99</a>| <a href="http://xiaojiejieav.com" target="_blank">99þþƷ</a>| <a href="http://htsp777.com" target="_blank">޳aƬӰԺĦ</a>| <a href="http://72c5.com" target="_blank">þþƷҹɫA</a>| <a href="http://19b1.com" target="_blank">ĻƵѹۿƵ</a>| <a href="http://doubaye.com" target="_blank">ٶ˽ȫֱ</a>| <a href="http://wwwp784.com" target="_blank">޾ƷƵѿ</a>| <a href="http://xxxxyz.com" target="_blank">aػƵƬƵ</a>| <a href="http://woaianli.com" target="_blank">պӰ߹ۿ</a>| <a href="http://shulan88.com" target="_blank">޾Ʒһ</a>| <a href="http://www-006688.com" target="_blank">޳AVƬһ</a>| <a href="http://www99383.com" target="_blank">³˿Ƭһ߹ۿ</a>| <a href="http://by6635.com" target="_blank">뾫ƷһƵ </a>| <a href="http://paweax.com" target="_blank">AVƷɫ</a>| <a href="http://cnlawedu.com" target="_blank">˿Ů͵ԲĻ</a>| <a href="http://dstbxg.com" target="_blank">91ɫƷ</a>| <a href="http://35469642.com" target="_blank">һëƬaaѹۿ</a>| <a href="http://3bmmatv.com" target="_blank">ۺľƷ</a>| <a href="http://huahui1866.com" target="_blank">޾ƷƬþ</a>| <a href="http://gujingyuye.com" target="_blank">߳aëƬѲ </a>| <a href="http://18888kj.com" target="_blank">ƵƷ</a>| <a href="http://cc19123.com" target="_blank">91Ƶ</a>| <a href="http://438266.com" target="_blank">ƷרWEB</a>| <a href="http://szqsnt.com" target="_blank">Ƶһվ</a>| <a href="http://50077995.com" target="_blank">ɫþþþۺ</a>| <a href="http://haha02.com" target="_blank">ŮvƬ</a>| <a href="http://8mav950.com" target="_blank">ƷŮͬһվ</a>| <a href="http://tttui.com" target="_blank">պëƬƵ</a>| <a href="http://cc8n.com" target="_blank">ۺɫͼƬ</a>| <a href="http://57gt.com" target="_blank">AVҹӰԺʦӰԺ</a>| <a href="http://xyzch.com" target="_blank">ȫaһëƬ˰</a>| <a href="http://yuyang0752.com" target="_blank">þҹƵ</a>| <a href="http://whspmd.com" target="_blank">պavþþƷ</a>| <a href="http://19520888.com" target="_blank">Ļպר</a>| <a href="http://zjjtejia.com" target="_blank">˳վ</a>| <a href="http://wwwse09.com" target="_blank">ۺһ</a>| <a href="http://class3g.com" target="_blank">һӰԺ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>