注册 | 登录 忘记密码? 51cto首页 | 博客 | 论坛 | 招聘
热点文章 我很郁闷,19岁的工程师找..
 帮助

Spring2.5注释驱动与基于注释的MVC


2008-06-25 09:29:24
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://tonyaction.blog.51cto.com/227462/83874
写在前面:
好长时间没有写博客了,主要是最近一直忙于工作上面的事情没有研究什么新的东西,也没有什么写的,最近应一个朋友的邀请一起开发一套教材,我才有开始对Spring研究起来,今天把写的其中一部分贴出来与大家共享.如有不足之处请多多指教.
Spring2.5注释驱动
       8.4.1 Spring2.5注释驱动
       注释语法越来越多的被业界所使用,并且注释配置相对于 XML 配置具有很多的优势:它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作。注释和 Java 代码位于一个文件中,而 XML 配置采用独立的配置文件,大多数配置信息在程序开发完成后都不会调整,如果配置信息和 Java 代码放在一起,有助于增强程序的内聚性。而采用独立的 XML 配置文件,程序员在编写一个功能时,往往需要在程序文件和配置文件中不停切换,这种思维上的不连贯会降低开发效率。因此在很多情况下,注释配置比 XML 配置更受欢迎,注释配置有进一步流行的趋势。Spring 2.5 的一大增强就是引入了很多注释类,现在您已经可以使用注释配置完成大部分 XML 配置的功能。
       在使用注释配置之前,先来回顾一下传统上是如何配置 Bean 并完成 Bean 之间依赖关系的建立。
代码清单1  Foo.java Foo对象有一个String类型的name属性.
              package com.tony.test;
public class Foo {
        private String name;
            public String toStirng(){
               return "Foo Name is :" + this.name;
            }
Setget方法
}
代码清单2  Bar.java Bar对象有一个String类型的add属性.
package com.tony.test;
public class Bar {
        private String add;
            public String toStirng(){
               return "Bar Add is :" + this.add;
            }
Setget方法
}
代码清单3 Main.java Main对象有两个属性分别是FooBar
package com.tony.test;
public class Main {
        private Foo foo;
        private Bar bar;
            public String toString(){
return "Main : [" + this.foo.toStirng() +" "+ this.bar.toStirng() + "]";
            }
Setget方法
}
代码清单4 配置文件spring-config-beans.xml
        <bean id="main" class="com.tony.test.Main">
           <property name="foo" ref="foo"></property>
           <property name="bar" ref="bar"></property>
        </bean>
   
        <bean id="foo" class="com.tony.test.Foo">
           <property name="name" value="Foo"></property>
        </bean>
        <bean id="bar" class="com.tony.test.Bar">
           <property name="add" value="Bar"></property>
</bean>
代码清单 5 Test.java Test类用于初始化Spring容器并获得main对象
package com.tony.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.
ClassPathXmlApplicationContext;
public class Test {
            public static void main(String[] args) {   
                 String[] locations = {"spring-config-beans.xml"};   
ApplicationContext ctx = new ClassPathXmlApplicationContext(locations);   
                 Main main = (Main) ctx.getBean("main");   
                 System.out.println(main);   
            }  
}
运行Test类控制台输出以下信息:
Main : [Foo Name is :Foo Bar Add is :Bar]
这说明Spring已经完成了Bean的创建和装配工作。
1)使用 @Autowired 注释
Spring 2.5 引入了 @Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。下面我们来看一下使用 @Autowired 进行成员变量自动注入的代码:
代码清单6使用 @Autowired 注释的 Main.java,此时可以将Main.java类中的setget方法删除
package com.tony.test;
 
import org.springframework.beans.factory.annotation.Autowired;
 
public class Main {
           @Autowired
           private Foo foo;
           @Autowired
           private Bar bar;
   
           public String toString(){
return "Main : [" + this.foo.toStirng() +" "+ this.bar.toStirng() + "]";
           }
}
Spring 通过一个 BeanPostProcessor @Autowired 进行解析,所以要让 @Autowired 起作用必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean
代码清单 7 修改配置文件
<!--  BeanPostProcessor 将自动对标注 @Autowired  Bean 进行注入 -->   
<bean class="org.springframework.beans.factory.annotation.
AutowiredAnnotationBeanPostProcessor"/>
        <!—此时移除 main Bean 的属性注入信息 -->  
        <bean id="main" class="com.tony.test.Main"></bean>
   
        <bean id="foo" class="com.tony.test.Foo">
           <property name="name" value="Foo"></property>
        </bean>
        <bean id="bar" class="com.tony.test.Bar">
           <property name="add" value="Bar"></property>
</bean>
Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired 注释时就找到和其匹配(默认按类型匹配)的 Bean,并将其注入。
2)使用@Qualifier 注释
Spring 允许我们通过 @Qualifier 注释指定注入 Bean 的名称,这样就不会产生注入错误了,请看下面代码清单:
       代码清单8 修改Main.java类中的foo属性注释增加注释@Qualifier("foo1")
public class Main {
           @Autowired
           @Qualifier("foo1")
           private Foo foo;
   
           @Autowired
           private Bar bar;
   
           public String toString(){
return "Main : [" + this.foo.toStirng() +" "+ this.bar.toStirng() + "]";
           }
}
代码清单9 在配置文件中增加idfoo2 Bean定义
<bean class="org.springframework.beans.factory.annotation.
AutowiredAnnotationBeanPostProcessor"/>
   
        <bean id="main" class="com.tony.test.Main"></bean>
   
        <bean id="foo1" class="com.tony.test.Foo">
           <property name="name" value="Foo1"></property>
        </bean>
        <bean id="foo2" class="com.tony.test.Foo">
           <property name="name" value="Foo2"></property>
        </bean>
        <bean id="bar" class="com.tony.test.Bar">
           <property name="add" value="Bar"></property>
</bean>
运行Test.java控制台输出如下信息:
Main : [Foo Name is :Foo1 Bar Add is :Bar]
证明Spring容器成功将foo1注入进main类中
3)使用 <context:annotation-config/> 简化配置
Spring 2.1 添加了一个新的 context Schema 命名空间,该命名空间对注释驱动、属性文件引入、加载期织入等功能提供了便捷的配置。我们知道注释本身是不会做任何事情的,它仅提供元数据信息。要使元数据信息真正起作用,必须让负责处理这些元数据的处理器工作起来。而我们前面所介绍的 AutowiredAnnotationBeanPostProcessor 就是处理这些注释元数据的处理器。但是直接在 Spring 配置文件中定义这些 Bean 显得比较笨拙。Spring 为我们提供了一种方便的注册这些 BeanPostProcessor 的方式,这就是 <context:annotation-config/>。请看下面的代码清单:
代码清单10
<context:annotation-config/>