谈谈Spring 2.x中简化配置的问题

谈谈Spring 2.x中简化配置的问题

关键字: 简化配置

谈谈Spring 2.x中简化配置的问题

Spring 2.x在配置文件的简化的方面做了很多工作,原来1.x中比较麻烦的配置都已经拥有了比较完美的解决方案。最近刚看完《精通Spring 2.x --企业应用开发精解》的书,结合自己的经验整理一下简化配置的内容。

一、关于集合的配置
1.List
>1.x版本的
Java代码 复制代码
  1. <bean id="parentBoss" abstract="true"class="com.baobaotao.attr.Boss"> <--父<bean>   
  2.     <property name="favorites">   
  3.         <set>   
  4.             <value>看报</value>   
  5.             <value>赛车</value>   
  6.             <value>高尔夫</value>   
  7.         </set>   
  8.     </property>   
  9. </bean>  
<bean id="parentBoss" abstract="true"class="com.baobaotao.attr.Boss"> <--父<bean>
	<property name="favorites">
		<set>
			<value>看报</value>
			<value>赛车</value>
			<value>高尔夫</value>
		</set>
	</property>
</bean>


>2.x版本的
Java代码 复制代码
  1. <util:list id="favoriteList1" list-class="java.util.LinkedList">   
  2.     <value>看报</value>   
  3.     <value>赛车</value>   
  4.     <value>高尔夫</value>   
  5. </util:list>  
<util:list id="favoriteList1" list-class="java.util.LinkedList">
	<value>看报</value>
	<value>赛车</value>
	<value>高尔夫</value>
</util:list>


2.Set
> 1.x
Java代码 复制代码
  1. <bean id="boss1" class="com.baobaotao.attr.Boss">   
  2.     <property name="favorites">   
  3.        <set>    
  4.           <value>看报</value>   
  5.           <value>赛车</value>   
  6.           <value>高尔夫</value>   
  7.        </set>   
  8.     </property>   
  9. </bean>  
<bean id="boss1" class="com.baobaotao.attr.Boss">
	<property name="favorites">
	   <set> 
	      <value>看报</value>
	      <value>赛车</value>
	      <value>高尔夫</value>
	   </set>
	</property>
</bean>

> 2.x
Java代码 复制代码
  1.     
  2. <util:set id="favoriteSet1">   
  3.  <value>看报</value>   
  4.  <value>赛车</value>   
  5.   <value>高尔夫</value>   
  6. </util:set>  
    
   <util:set id="favoriteSet1">
	   <value>看报</value>
	   <value>赛车</value>
	    <value>高尔夫</value>
   </util:set>

   3.Map
> 1.x
Java代码 复制代码
  1. <bean id="boss1" class="com.baobaotao.attr.Boss">   
  2.     <property name="jobs">   
  3.     <map>   
  4.           <!--Map第一个元素-->   
  5.                <entry>    
  6.               <key><value>AM</value></key>   
  7.               <value>会见客户</value>   
  8.            </entry>   
  9.           <!--Map第二个元素-->   
  10.                <entry>    
  11.               <key><value>PM</value></key>   
  12.               <value>公司内部会议</value>   
  13.           </entry>                 
  14.     </map>   
  15.     </property>   
  16. </bean>  
<bean id="boss1" class="com.baobaotao.attr.Boss">
    <property name="jobs">
	<map>
	      <!--Map第一个元素-->
               <entry> 
	          <key><value>AM</value></key>
	          <value>会见客户</value>
	       </entry>
	      <!--Map第二个元素-->
               <entry> 
	          <key><value>PM</value></key>
	          <value>公司内部会议</value>
	      </entry>		      
	</map>
    </property>
</bean>

> 2.x
Java代码 复制代码
  1. <util:map id="emails1">   
  2.     <entry key="AM" value="会见客户" />   
  3.     <entry key="PM" value="公司内部会议" />   
  4. </util:map>  
<util:map id="emails1">
	<entry key="AM" value="会见客户" />
	<entry key="PM" value="公司内部会议" />
</util:map>


   4. Properties

> 1.x
Java代码 复制代码
  1. <bean id="boss1" class="com.baobaotao.attr.Boss">   
  2.     <property name="mails">   
  3.         <props>   
  4.            <prop key="jobMail">john-office@baobaotao.com</prop>   
  5.            <prop key="lifeMail">john-life@baobaotao.com</prop>   
  6.         </props>   
  7.     </property>   
  8. </bean>  
<bean id="boss1" class="com.baobaotao.attr.Boss">
	<property name="mails">
	    <props>
	       <prop key="jobMail">john-office@baobaotao.com</prop>
	       <prop key="lifeMail">john-life@baobaotao.com</prop>
	    </props>
	</property>
</bean>


> 2.x
Java代码 复制代码
  1. <util:properties id="emailProps1" location="classpath:com/baobaotao/fb/mails.properties"/>  
  <util:properties id="emailProps1" location="classpath:com/baobaotao/fb/mails.properties"/>

可以在一个属性文件中直接配置属性,这比较符合一般的项目习惯。

二、 关于事务配置


1.1.x
Java代码 复制代码
  1.  <bean id="bbtForum"    
  2. class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">   
  3. <property name="transactionManager" ref="txManager" />    
  4. <property name="target" ref="bbtForumTarget"/>   
  5. <property name="transactionAttributes">    
  6.     <props>   
  7.         <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>    
  8.         <prop key="*">PROPAGATION_REQUIRED</prop>    
  9.     </props>   
  10. </property>   
  11.  </bean>  
  <bean id="bbtForum" 
	class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
	<property name="transactionManager" ref="txManager" /> 
	<property name="target" ref="bbtForumTarget"/>
	<property name="transactionAttributes"> 
		<props>
			<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> 
			<prop key="*">PROPAGATION_REQUIRED</prop> 
		</props>
	</property>
  </bean>


2.2.x

有两种新方法
a)使用@Transactional注解
在需要的服务类或服务方法处直接打上@Transactional注解,然后在Spring配置文件中启用注解事务驱动就可以了:

Java代码 复制代码
  1. @Transactional    
  2. public class BbtForumImpl implements BbtForum {   
  3.     @Transactional(readOnly=true)    
  4.     public Forum getForum(int forumId) {   
  5.         return forumDao.getForum(forumId);   
  6.     }   
  7.        。。。。   
  8. }  
@Transactional 
public class BbtForumImpl implements BbtForum {
	@Transactional(readOnly=true) 
	public Forum getForum(int forumId) {
		return forumDao.getForum(forumId);
	}
       。。。。
}

在Spring配置文件中相应添加上:
Java代码 复制代码
  1. <bean id="txManager"  
  2.         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">   
  3.         <property name="dataSource" ref="dataSource" />   
  4. </bean>   
  5. <tx:annotation-driven transaction-manager="txManager"/>  
<bean id="txManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="txManager"/>

这样就OK了,简单吧:)

b)使用aop/tx

如果你的Service服务类都很规范,我觉得使用aop/tx更方面,因为不用到处打注解,在一处集中配置就OK了,可谓运筹帷幄之中,决胜于千里之外:)
Java代码 复制代码
  1. <aop:config>    
  2. t;aop:pointcut id="serviceMethod"    
  3.    expression="execution(* com.baobaotao.service.*Forum.*(..))" />   
  4. t;aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />    
  5.  </aop:config>   
  6. <tx:advice id="txAdvice" transaction-manager="txManager">    
  7.    <tx:attributes>    
  8.        <tx:method name="get*" read-only="false"/>   
  9.        <tx:method name="add*" rollback-for="Exception" />   
  10.        <tx:method name="update*"/>            
  11.    </tx:attributes>   
  12. lt;/tx:advice>   
 
     <aop:config> 
	  <aop:pointcut id="serviceMethod" 
		      expression="execution(* com.baobaotao.service.*Forum.*(..))" />
	  <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" /> 
      </aop:config>
     <tx:advice id="txAdvice" transaction-manager="txManager"> 
        <tx:attributes> 
            <tx:method name="get*" read-only="false"/>
            <tx:method name="add*" rollback-for="Exception" />
            <tx:method name="update*"/>         
        </tx:attributes>
    </tx:advice>
  


三、关于AOP配置

  原来1.x的AOP太麻烦了,提都不想提,直接说一下2.x的AOP。
Spring 2.x使用@AspectJ来描述切面,由于@AspectJ的语法描述能力超强,因此在Spring 2.x中使用AOP真的非常方便。

    在使用@AspectJ之前,首先你得保证你所使用的JDK的版本是5.0及以上版本,否则无法使用注解技术。
Spring在处理@Aspect注解表达式时,需要使用位于spring/lib/asm下asm关联类库,将该类库的三个类包加入到类路径中:asm-2.2.2.jar、asm-commons-2.2.2.jar和asm-util-2.2.2.jar。我们在第一章中了解了asm类库的用途,它是轻量级的字节码处理框架,因为Java的反射机制无法获取入参名,Spring就利用asm处理@AspectJ中所描述的方法入参名。

    此外,Spring采用AspectJ提供的@AspectJ注解类库及相应的解析类库,它位于spring/lib/aspectj目录下,将目录下的aspectjrt.jar和aspectjweaver.jar类包加入类路径中。
在做好上节中所提到的前置工作后,我们就可以开始编写一个基于@AspectJ的切面了,首先来看一个简单的例子,以便对@AspectJ有一个切身的认识。

   @AspectJ采用不同的方式对AOP进行描述, 我们使用NaiveWaiter的例子来说明,这是一个希望引入切面的目标类:
Java代码 复制代码
  1. package com.baobaotao;   
  2. public class NaiveWaiter implements Waiter {   
  3.     public void greetTo(String clientName) {   
  4.         System.out.println("NaiveWaiter:greet to "+clientName+"...");   
  5.     }   
  6.     public void serveTo(String clientName){   
  7.         System.out.println("NaiveWaiter:serving "+clientName+"...");   
  8.     }      
  9. }  
package com.baobaotao;
public class NaiveWaiter implements Waiter {
	public void greetTo(String clientName) {
		System.out.println("NaiveWaiter:greet to "+clientName+"...");
	}
	public void serveTo(String clientName){
		System.out.println("NaiveWaiter:serving "+clientName+"...");
	}	
}


下面使用@AspectJ来定义一下切面:
Java代码 复制代码
  1. package com.baobaotao.aspectj.aspectj;   
  2. import org.aspectj.lang.annotation.Aspect;   
  3. import org.aspectj.lang.annotation.Before;   
  4. //通过该注解将PreGreetingAspect标识为一个切面   
  5. @Aspect    
  6. public class PreGreetingAspect{   
  7.     @Before("execution(* greetTo(..))"//<---定义切点和增强类型   
  8.     public void beforeGreeting(){ //<----增强的横切逻辑   
  9.         System.out.println("How are you");   
  10.     }   
  11. }  
package com.baobaotao.aspectj.aspectj;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
//通过该注解将PreGreetingAspect标识为一个切面
@Aspect 
public class PreGreetingAspect{
	@Before("execution(* greetTo(..))") //<---定义切点和增强类型
	public void beforeGreeting(){ //<----增强的横切逻辑
		System.out.println("How are you");
	}
}


然后启动@AspectJ的注解切面驱动就可以了!
Java代码 复制代码
  1. <?xml version="1.0" encoding="UTF-8" ?>   
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:aop="http://www.springframework.org/schema/aop"    
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  6. http://www.springframework.org/schema/beans/spring-beans-2.0.xsd   
  7.                         http://www.springframework.org/schema/aop    
  8. http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">   
  9.     <!--基于@AspectJ切面的驱动器-->   
  10.         <aop:aspectj-autoproxy />    
  11.     <bean id="waiter" class="com.baobaotao.NaiveWaiter" />   
  12.     <bean class="com.baobaotao.aspectj.example.PreGreetingAspect" />   
  13. </beans>  
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                        http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
	<!--基于@AspectJ切面的驱动器-->
        <aop:aspectj-autoproxy /> 
	<bean id="waiter" class="com.baobaotao.NaiveWaiter" />
	<bean class="com.baobaotao.aspectj.example.PreGreetingAspect" />
</beans>


四、关于Spring 2.1添加的新功能

1.原来引入一个外面属性配置文件需要使用以下的方式:
Java代码 复制代码
  1. <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">   
  2.     <property name="locations">   
  3.        <list>   
  4.            <!--指定属性文件地址,可以在这里定义多个属性文件-->   
  5.           <value>classpath:com/baobaotao/place/car.properties</value>    
  6.        </list>   
  7.     </property>   
  8.     <property name="fileEncoding" value="utf-8"/>   
  9. </bean>   
  10.   
  11. <!--引用外部属性的值,对car属性进行配置-->   
  12. <bean id="car" class="com.baobaotao.place.Car">   
  13.     <property name="brand" value="${brand}" />   
  14.     <property name="maxSpeed" value="${maxSpeed}" />   
  15.     <property name="price" value="${price}" />   
  16. </bean>  
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<property name="locations">
	   <list>
           <!--指定属性文件地址,可以在这里定义多个属性文件-->
		  <value>classpath:com/baobaotao/place/car.properties</value> 
	   </list>
	</property>
    <property name="fileEncoding" value="utf-8"/>
</bean>

<!--引用外部属性的值,对car属性进行配置-->
<bean id="car" class="com.baobaotao.place.Car">
	<property name="brand" value="${brand}" />
	<property name="maxSpeed" value="${maxSpeed}" />
	<property name="price" value="${price}" />
</bean>


使用Spring 2.1后,你只需要象下面这样配置就可以了:
Java代码 复制代码
  1. <context:property-placeholder location=" classpath:com/baobaotao/place/car.properties "/>  
<context:property-placeholder location=" classpath:com/baobaotao/place/car.properties "/>


3.注解驱动的Bean注入

大家看看这段E文就OK了,
<context:component-scan>: scans classpath using one or more "include"/"exclude" filters, and automatically registers beans
In essence, this is a third way to define beans (1: classic xml, 2:javaconfig (code), 3:<context:component-scan>, matching on annotations or types)
Default naming strategy is based on short classname of discovered bean
@Component and @Repository annotations, when used, can optionally specify a bean name to use
For filter type "annotation", the value of "expression" attribute should resolve to a Java annotation type
For filter type "assignable", the value of "expression" attribute should resolve to a Java type
For filter type "aspectj", the value of "expression" should be an "type expression" (in Pointcut language, perhaps it could be injected?)
Relevant documentation can be found in preliminary spring 2.1 manual, sections 3.10 and 3.11
In addition, this last JIRA comment for http://www.jetbrains.net/jira/browse/IDEADEV-16886#action_163502 contains two links to articles showing example usage of <context:component-scan>
<context:annotation-config> (described in 3.10 in spring 2.1 manual linked above): allows autowiring to be defined using @Resource or @Autowired annotations.


五、关于Spring 2.5添加的新功能
  Spring 2.5继续对context命名空间进行了扩充,添加了好用而强大的context:load-time-weaver,可以让我们更方便地应用AspectJ。大家可以看TSS上的这篇文章,它全面讲解了Spring 2.5的新特性。
http://www.theserverside.com/tt/articles/article.tss?l=IntrotoSpring25

注:以上大部分代码来直接引用自 《精通Spring 2.x--企业应用开发精解》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值