草样年华--跑掉的青春

博客园 首页 新随笔 联系 订阅 管理

1   配置文件的方法

一般编写spring 框架的代码时候。一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量。并且要配套写上 get 和 set方法。 
Boss 拥有 Office 和 Car 类型的两个属性

 1 public class Boss {      
 2     private Car car;      
 3     private Office office;      
 4      
 5     // 省略 get/setter  没写    
 6      
 7     @Override     
 8     public String toString() {      
 9         return "car:" + car + "\n" + "office:" + office;      
10     }      
11 }     

我们在 Spring 容器中将 Office 和 Car 声明为 Bean,并注入到 Boss Bean 中:下面是使用传统 XML 完成这个工作的配置文件 beans.xml和测试类代码

<?xml version="1.0" encoding="UTF-8" ?>      
<beans xmlns="http://www.springframework.org/schema/beans"     
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     
    xsi:schemaLocation="http://www.springframework.org/schema/beans       
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">      
    <bean id="boss" class="com.baobaotao.Boss">      
        <property name="car" ref="car"/>      
        <property name="office" ref="office" />      
    </bean>      
    <bean id="office" class="com.baobaotao.Office">      
        <property name="officeNo" value="002"/>      
    </bean>      
    <bean id="car" class="com.baobaotao.Car" scope="singleton">      
        <property name="brand" value=" 红旗 CA72"/>      
        <property name="price" value="2000"/>      
    </bean>      
</beans>     
 1 import org.springframework.context.ApplicationContext;      
 2 import org.springframework.context.support.ClassPathXmlApplicationContext;      
 3 public class AnnoIoCTest {      
 4      
 5     public static void main(String[] args) {      
 6         String[] locations = {"beans.xml"};      
 7         ApplicationContext ctx =       
 8             new ClassPathXmlApplicationContext(locations);      
 9         Boss boss = (Boss) ctx.getBean("boss");      
10         System.out.println(boss);      
11     }      
12 }      

2、通过注解方式实现注入

  Spring 2.5 引入了 @Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Autowired的使用来消除 set ,get方法。 
要实现我们要精简程序的目的。需要这样来处理: 

* 在applicationContext.xml中加入: 
 
  <!-- 该 BeanPostProcessor 将自动对标注 @Autowired 的 Bean 进行注入 -->   

  <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> 

Spring 通过一个 BeanPostProcessor 对 @Autowired 进行解析,所以要让 @Autowired 起作用必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。   

  * 修改在原来注入spirng容器中的bean的方法,在域变量上加上标签@Autowired,并且去掉 相应的get 和set方法。

public class Boss {      
     
    @Autowired     
    private Car car;      
     
    @Autowired     
    private Office office;      
     
    //省略toString没写     
}     

在applicatonContext.xml中 把原来boss引用的<porpery >标签也去掉。

<?xml version="1.0" encoding="UTF-8" ?>      
<beans xmlns="http://www.springframework.org/schema/beans"     
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     
    xsi:schemaLocation="http://www.springframework.org/schema/beans       
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">      
     
    <!-- 该 BeanPostProcessor 将自动起作用,对标注 @Autowired 的 Bean 进行自动注入 -->      
    <bean class="org.springframework.beans.factory.annotation.      
        AutowiredAnnotationBeanPostProcessor"/>      
     
    <!-- 移除 boss Bean 的属性注入配置的信息 -->      
    <bean id="boss" class="com.baobaotao.Boss"/>      
       
    <bean id="office" class="com.baobaotao.Office">      
        <property name="officeNo" value="001"/>      
    </bean>      
    <bean id="car" class="com.baobaotao.Car" scope="singleton">      
        <property name="brand" value=" 红旗 CA72"/>      
        <property name="price" value="2000"/>      
    </bean>      
</beans>    

这样,当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired 注释时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。

按照上面的配置,Spring 将直接采用 Java 反射机制对 Boss 中的 car 和 office 这两个私有成员变量进行自动注入。所以对成员变量使用 @Autowired 后,大可将它们的 setter 方法(setCar() 和 setOffice())从 Boss 中删除

 

在使用Autowired注解和Resource注解以及xml中的default-autowire注解时,需要详细地了解每个注解的工作方式和工作范围,在大多数情况下。这几种方式都差不多,但在细节方面有差异。从笔者对于代码的严谨角度,我并不推荐在xml中配置default-autowire,因为这会导致所有的bean,不管需不需要注入,spring都会帮你注入。从一方面是好事,从另一方面就管得太多。如果确实要配置default-autowire,请再配置另一个属性default-autowire-candidates,这个属性可以固定default-autowire的范围,比如*Service,可以只针对Service结尾的bean进行autowire包装。

最后,@Autowire注解不是xml配置中的default-autowire-byType,而@Resource也不是@Autowire,更不是xml配置中的default-autowire-byName。不能够简单地混为一谈。

注意
1) ,如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。推荐使用:@Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与spring的耦合。
2) , Hibernate JPA注解一般加在属性或者属性getter方法上,Spring注解一般加在属性或者属性setter方法上。

 
0

参考:http://wangqiaowqo.iteye.com/blog/1088397


 

posted on 2016-07-31 12:27  草样年华--跑掉的青春  阅读(547)  评论(0)    收藏  举报