spring2.0配置

Spring 2.0的新配置:
如果如果service没有基于接口,使用cgilib来实现AOP,定义proxy-target-class="true"
<aop:config proxy-target-class="true">
<aop:advisor pointcut="execution(* com.cutoff.service..*Manager.*(..))" advice-ref="transactionAdvice"/>
//这里是spring例子自带的,可以实现自定义的advice,在每次save动作完成后。会触发emailAdvice
Java代码 复制代码
  1.     <aop:advisor pointcut="execution(* com.cutoff.service..*Manager.save(..))" advice-ref="emailAdvice"/>        
  2. </aop:config>   
  3.   
  4. <tx:advice id="transactionAdvice" transaction-manager="transactionManager">   
  5.     <tx:attributes>   
  6.         <tx:method name="get*" read-only="true"/>    
  7.         <tx:method name="find*" read-only="true"/>    
  8.         <tx:method name="insert*" />    
  9.         <tx:method name="update*" />    
  10.         <tx:method name="save*" />    
  11.     </tx:attributes>   
  12. </tx:advice>   
  13.   
  14. <bean id="emailAdvice" class="org.springframework.samples.jpetstore.domain.logic.SendOrderConfirmationEmailAdvice">   
  15.     <property name="mailSender" ref="mailSender"/>   
  16. </bean>   
  17.   
  18. <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">   
  19.     <property name="host" value="${mail.host}"/>   
  20. </bean>   
		<aop:advisor pointcut="execution(* com.cutoff.service..*Manager.save(..))" advice-ref="emailAdvice"/>		
	</aop:config>

	<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="get*" read-only="true"/> 
			<tx:method name="find*" read-only="true"/> 
			<tx:method name="insert*" /> 
			<tx:method name="update*" /> 
			<tx:method name="save*" /> 
		</tx:attributes>
	</tx:advice>
	
	<bean id="emailAdvice" class="org.springframework.samples.jpetstore.domain.logic.SendOrderConfirmationEmailAdvice">
		<property name="mailSender" ref="mailSender"/>
	</bean>
	
	<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
		<property name="host" value="${mail.host}"/>
	</bean>
	
唯一有点难懂的是pointcut里的语法,其实也很好学,Spring参考文档6.2.3.4 示例里有完整说明 ,其实一排子过去是

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)其中带问号的modifiers-pattern?(public/protected) 和 declaring-type-pattern? throws-pattern? 可以不填

execution(* *..BookManager.save(..))的解读:
第一颗* 代表ret-type-pattern 返回值可任意,
*..BookManager 代表任意Pacakge里的BookManager类。
如果写成com.xyz.service.* 则代表com.xyz.service下的任意类
com.xyz.service..* com.xyz.service则代表com.xyz.service及其子package下的任意类
save代表save方法,也可以写save* 代表saveBook()等方法
(..) 匹配0个参数或者多个参数的,任意类型
(x,..) 第一个参数的类型必须是X
(x,,,s,..) 匹配至少4个参数,第一个参数必须是x类型,第二个和第三个参数可以任意,第四个必须是s类型。
注意事项:
1. name-pattern千万不要写成*..*Manager ,这样子会把所有第三方类库的Manager比如Spring的PlatformTranstationManager 也加入aop,非常危险。所以最好还是加上项目的package前缀,如"org.springside..*Manager"

2. 因为有*,会修饰所有方法,有些hibernateTemplate的final的方法不能被cglib修改,会抛warning,无害。

4. 事务定义选项
事务定义一般默认的PROPAGATION_REQUIRED即可,另提供的几个选择很少使用。值得注意的是一个PROPAGATION_NESTED,嵌入式事务的意义在于多级事务,如果出错只rollback子事务自己,不rollback主事务的所有操作。比如OrderManager的shipOrder函数 调用 save函数,如果save()被定义为嵌入式事务,当进入save()时,会存储save point。如果在save 中出错,会rollback 到刚才的save point,但不影响其他的操作。这需要JDBC3.0 SavePoint功能的支持。 而一般service间互相嵌入调用时,如果都定义为PROPAGATION_REQUIRED,有其中一个操作出错,rollback全部操作。

你可能感兴趣的:(spring,AOP,bean,嵌入式)