Spring2.5注释驱动与基于注释的MVC
2010-07-13 20:15
369 查看
转载: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;
}
Set和get方法
}
代码清单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;
}
Set和get方法
}
代码清单3 Main.java Main对象有两个属性分别是Foo和Bar
package com.tony.test;
public class Main {
private Foo foo;
private Bar bar;
public String toString(){
return "Main : [" + this.foo.toStirng() +" "+ this.bar.toStirng() + "]";
}
Set和get方法
}
代码清单4 配置文件spring-config-beans.xml
代码清单 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类中的set和get方法删除
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 修改配置文件
当 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 在配置文件中增加id为foo2 Bean定义
运行Test.java控制台输出如下信息:
Main : [Foo Name is :Foo1 Bar Add is :Bar]
证明Spring容器成功将foo1注入进main类中
3)使用 简化配置
Spring 2.1 添加了一个新的 context 的 Schema 命名空间,该命名空间对注释驱动、属性文件引入、加载期织入等功能提供了便捷的配置。我们知道注释本身是不会做任何事情的,它仅提供元数据信息。要使元数据信息真正起作用,必须让负责处理这些元数据的处理器工作起来。而我们前面所介绍的 AutowiredAnnotationBeanPostProcessor 就是处理这些注释元数据的处理器。但是直接在 Spring 配置文件中定义这些 Bean 显得比较笨拙。Spring 为我们提供了一种方便的注册这些 BeanPostProcessor 的方式,这就是 。请看下面的代码清单:
代码清单10
代码清单中将
替换成为
将隐式地向 Spring 容器注册 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 以及 equiredAnnotationBeanPostProcessor 这 4 个 BeanPostProcessor。
4) 使用 @Component
虽然我们可以通过 @Autowired在 Bean 类中使用自动注入功能,但是 Bean 还是在 XML 文件中通过 进行定义,也就是说,在 XML 配置文件中定义 Bean,通过 @Autowired 为 Bean 的成员变量、方法入参或构造函数入参提供自动注入的功能。能否也通过注释定义 Bean,从 XML 配置文件中完全移除 Bean 定义的配置呢?答案是肯定的,我们通过 Spring 2.5 提供的 @Component 注释就可以达到这个目标。请看下面的代码清单:
代码清单11 Foo.java
@Component
public class Foo {
private String name = "Foo's name.";
public String toStirng(){
return "Foo Name is :" + this.name;
}
}
在类的开始位置使用@Component注释,标明此类是一个Bean
代码清单12 Main.java
@Component("main")
public class Main {
@Autowired
private Foo foo;
@Autowired
private Bar bar;
……
@Component 有一个可选的入参,用于指定 Bean 的名称,在 Main 中,我们就将 Bean 名称定义为“main”。在使用 @Component 注释后,Spring 容器必须启用类扫描机制以启用注释驱动 Bean 定义和注释驱动 Bean 的自动注入的策略。Spring 2.5 对 context 命名空间进行了扩展,提供了这一功能。
代码清单13 Spring配置文件中只保留以下配置信息
这里,所有通过 元素定义 Bean 的配置内容已经被移除,仅需要添加一行 配置就解决所有问题了——Spring XML 配置文件得到了极致的简化(当然配置元数据还是需要的,只不过以注释形式存在罢了)。 的 base-package 属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。
8.4.2 Spring2.5基于注解驱动的MVC
Spring 2.5 也为 Spring MVC 引入了注释驱动功能。现在我们无须让 Controller 继承任何接口,无需在 XML 配置文件中定义请求和 Controller 的映射关系,仅仅使用注释就可以让一个 POJO 具有 Controller 的绝大部分功能 —— Spring MVC 框架的易用性得到了进一步的增强。
1) 基于注解的 Controller
由于 Spring MVC 的 Controller 必须事先是一个 Bean,所以 @Controller 注解是不可缺少的。请看下面的代码清单
代码清单1
@Controller //将这个类标注为Controller
public class FooController {
@Autowired
private FooService fooService;
@RequestMapping("/list.do") //URL请求映射
public String[] list() {
String[] list = fooService.getAll();
System.out.println(list);
return list;
}
@RequestMapping("/del.do") //URL请求映射
public void del(HttpServletRequest request, HttpServletResponse response) {
fooService.doDel(request.getParameter("id"));
}
}
在代码清单1中我们通过@Controller注释将FooController.java 标注为一个控制器,而不需继承或者实现任何类和接口,就使FooController.java拥有了控制器的功能。代码清单1中使用了两个链接分别访问了不同的方法,在实际应用中我们也许有另外一种需求一个控制器只接受一个URL请求,而控制器中不同的方法来处理URL请求中携带的不同的参数,请看下面的代码清单。
2) 一个 Controller 对应一个 URL,由请求参数决定请求处理方法
代码清单2
@Controller
@RequestMapping("/doFoo.do")// 指定控制器对应URL请求
public class FooController {
@Autowired
private FooService fooService;
//list方法对应URL /doFoo.do?mode=list
@RequestMapping(params = "mode=list")
public String[] list() {
String[] list = fooService.getAll();
System.out.println(list);
return list;
}
//del方法对应URL /doFoo.do?mode=del
@RequestMapping(params = "mode=del")
public void del(HttpServletRequest request,
HttpServletResponse response) {
fooService.doDel(request.getParameter("id"));
}
}
代码清单2中满足了针对不同粒度程序设计的需要。我们还可以让请求处理方法处理特定的 HTTP 请求如POST类型的,请看下面的代码清单。
3) 让请求处理方法处理特定的 HTTP 请求方法
代码清单3
@Controller
@RequestMapping("/doFoo.do")// 指定控制器对应URL请求
public class FooController {
//只针对POST请求
@RequestMapping(params = "mode=submit",
method = RequestMethod.POST)
public String submit(HttpServletRequest request,
HttpServletResponse response){
System.out.println("调用 submit 方法.");
return "success";
}
}
方法submit只处理类型为POST的URL请求
4) 处理方法入参绑定 URL 参数
代码清单4
@Controller
@RequestMapping("/doFoo.do")// 指定控制器对应URL请求
public class FooController {
@Autowired
private FooService fooService;
//del方法对应URL /doFoo.do?mode=del&id=10
@RequestMapping(params = "mode=del")
public String del(int id) {
fooService.doDel(id);
return "success";
}
}
当我们发送 /doFoo.do?mode=del&id=10 的 URL 请求时,
Spring 不但让 del() 方法处理这个请求,而且还将 id 请求参数在类型转换后绑定到 del() 方法的 id 入参上。而 del() 方法的返回类型是 String,它将被解析为逻辑视图的名称。也就是说 Spring 在如何给处理方法入参自动赋值以及如何将处理方法返回值转化为 ModelAndView 中的过程中存在一套潜在的规则,不熟悉这个规则就不可能很好地开发基于注解的请求处理方法,因此了解这个潜在规则无疑成为理解 Spring MVC 框架基于注解功能的核心问题。代码清单4还可以写成下面这种形式
代码清单5
@Controller
@RequestMapping("/doFoo.do")// 指定控制器对应URL请求
public class FooController {
@Autowired
private FooService fooService;
//del方法对应URL /doFoo.do?mode=del&id=10
@RequestMapping(params = "mode=del")
public String del(@RequestParam("id")int id) {
fooService.doDel(id);
return "success";
}
}
代码清单5中对 del() 请求处理方法的 id 入参标注了 @RequestParam("id") 注释,所以它将和 id 的 URL 参数绑定。
我的其它Spring文章,也许会对您有帮助
Spring的任务调度和邮件发送
Spring应用的单元测试
Spring的数据库支持
Spring的MVC框架
Spring的IoC容器
Spring对AOP的支持
Spring2.5注释驱动与基于注释的MVC
本文出自 “绝缘材料” 博客,请务必保留此出处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;
}
Set和get方法
}
代码清单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;
}
Set和get方法
}
代码清单3 Main.java Main对象有两个属性分别是Foo和Bar
package com.tony.test;
public class Main {
private Foo foo;
private Bar bar;
public String toString(){
return "Main : [" + this.foo.toStirng() +" "+ this.bar.toStirng() + "]";
}
Set和get方法
}
代码清单4 配置文件spring-config-beans.xml
代码清单 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类中的set和get方法删除
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 修改配置文件
当 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 在配置文件中增加id为foo2 Bean定义
运行Test.java控制台输出如下信息:
Main : [Foo Name is :Foo1 Bar Add is :Bar]
证明Spring容器成功将foo1注入进main类中
3)使用 简化配置
Spring 2.1 添加了一个新的 context 的 Schema 命名空间,该命名空间对注释驱动、属性文件引入、加载期织入等功能提供了便捷的配置。我们知道注释本身是不会做任何事情的,它仅提供元数据信息。要使元数据信息真正起作用,必须让负责处理这些元数据的处理器工作起来。而我们前面所介绍的 AutowiredAnnotationBeanPostProcessor 就是处理这些注释元数据的处理器。但是直接在 Spring 配置文件中定义这些 Bean 显得比较笨拙。Spring 为我们提供了一种方便的注册这些 BeanPostProcessor 的方式,这就是 。请看下面的代码清单:
代码清单10
代码清单中将
替换成为
将隐式地向 Spring 容器注册 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 以及 equiredAnnotationBeanPostProcessor 这 4 个 BeanPostProcessor。
4) 使用 @Component
虽然我们可以通过 @Autowired在 Bean 类中使用自动注入功能,但是 Bean 还是在 XML 文件中通过 进行定义,也就是说,在 XML 配置文件中定义 Bean,通过 @Autowired 为 Bean 的成员变量、方法入参或构造函数入参提供自动注入的功能。能否也通过注释定义 Bean,从 XML 配置文件中完全移除 Bean 定义的配置呢?答案是肯定的,我们通过 Spring 2.5 提供的 @Component 注释就可以达到这个目标。请看下面的代码清单:
代码清单11 Foo.java
@Component
public class Foo {
private String name = "Foo's name.";
public String toStirng(){
return "Foo Name is :" + this.name;
}
}
在类的开始位置使用@Component注释,标明此类是一个Bean
代码清单12 Main.java
@Component("main")
public class Main {
@Autowired
private Foo foo;
@Autowired
private Bar bar;
……
@Component 有一个可选的入参,用于指定 Bean 的名称,在 Main 中,我们就将 Bean 名称定义为“main”。在使用 @Component 注释后,Spring 容器必须启用类扫描机制以启用注释驱动 Bean 定义和注释驱动 Bean 的自动注入的策略。Spring 2.5 对 context 命名空间进行了扩展,提供了这一功能。
代码清单13 Spring配置文件中只保留以下配置信息
这里,所有通过 元素定义 Bean 的配置内容已经被移除,仅需要添加一行 配置就解决所有问题了——Spring XML 配置文件得到了极致的简化(当然配置元数据还是需要的,只不过以注释形式存在罢了)。 的 base-package 属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。
8.4.2 Spring2.5基于注解驱动的MVC
Spring 2.5 也为 Spring MVC 引入了注释驱动功能。现在我们无须让 Controller 继承任何接口,无需在 XML 配置文件中定义请求和 Controller 的映射关系,仅仅使用注释就可以让一个 POJO 具有 Controller 的绝大部分功能 —— Spring MVC 框架的易用性得到了进一步的增强。
1) 基于注解的 Controller
由于 Spring MVC 的 Controller 必须事先是一个 Bean,所以 @Controller 注解是不可缺少的。请看下面的代码清单
代码清单1
@Controller //将这个类标注为Controller
public class FooController {
@Autowired
private FooService fooService;
@RequestMapping("/list.do") //URL请求映射
public String[] list() {
String[] list = fooService.getAll();
System.out.println(list);
return list;
}
@RequestMapping("/del.do") //URL请求映射
public void del(HttpServletRequest request, HttpServletResponse response) {
fooService.doDel(request.getParameter("id"));
}
}
在代码清单1中我们通过@Controller注释将FooController.java 标注为一个控制器,而不需继承或者实现任何类和接口,就使FooController.java拥有了控制器的功能。代码清单1中使用了两个链接分别访问了不同的方法,在实际应用中我们也许有另外一种需求一个控制器只接受一个URL请求,而控制器中不同的方法来处理URL请求中携带的不同的参数,请看下面的代码清单。
2) 一个 Controller 对应一个 URL,由请求参数决定请求处理方法
代码清单2
@Controller
@RequestMapping("/doFoo.do")// 指定控制器对应URL请求
public class FooController {
@Autowired
private FooService fooService;
//list方法对应URL /doFoo.do?mode=list
@RequestMapping(params = "mode=list")
public String[] list() {
String[] list = fooService.getAll();
System.out.println(list);
return list;
}
//del方法对应URL /doFoo.do?mode=del
@RequestMapping(params = "mode=del")
public void del(HttpServletRequest request,
HttpServletResponse response) {
fooService.doDel(request.getParameter("id"));
}
}
代码清单2中满足了针对不同粒度程序设计的需要。我们还可以让请求处理方法处理特定的 HTTP 请求如POST类型的,请看下面的代码清单。
3) 让请求处理方法处理特定的 HTTP 请求方法
代码清单3
@Controller
@RequestMapping("/doFoo.do")// 指定控制器对应URL请求
public class FooController {
//只针对POST请求
@RequestMapping(params = "mode=submit",
method = RequestMethod.POST)
public String submit(HttpServletRequest request,
HttpServletResponse response){
System.out.println("调用 submit 方法.");
return "success";
}
}
方法submit只处理类型为POST的URL请求
4) 处理方法入参绑定 URL 参数
代码清单4
@Controller
@RequestMapping("/doFoo.do")// 指定控制器对应URL请求
public class FooController {
@Autowired
private FooService fooService;
//del方法对应URL /doFoo.do?mode=del&id=10
@RequestMapping(params = "mode=del")
public String del(int id) {
fooService.doDel(id);
return "success";
}
}
当我们发送 /doFoo.do?mode=del&id=10 的 URL 请求时,
Spring 不但让 del() 方法处理这个请求,而且还将 id 请求参数在类型转换后绑定到 del() 方法的 id 入参上。而 del() 方法的返回类型是 String,它将被解析为逻辑视图的名称。也就是说 Spring 在如何给处理方法入参自动赋值以及如何将处理方法返回值转化为 ModelAndView 中的过程中存在一套潜在的规则,不熟悉这个规则就不可能很好地开发基于注解的请求处理方法,因此了解这个潜在规则无疑成为理解 Spring MVC 框架基于注解功能的核心问题。代码清单4还可以写成下面这种形式
代码清单5
@Controller
@RequestMapping("/doFoo.do")// 指定控制器对应URL请求
public class FooController {
@Autowired
private FooService fooService;
//del方法对应URL /doFoo.do?mode=del&id=10
@RequestMapping(params = "mode=del")
public String del(@RequestParam("id")int id) {
fooService.doDel(id);
return "success";
}
}
代码清单5中对 del() 请求处理方法的 id 入参标注了 @RequestParam("id") 注释,所以它将和 id 的 URL 参数绑定。
我的其它Spring文章,也许会对您有帮助
Spring的任务调度和邮件发送
Spring应用的单元测试
Spring的数据库支持
Spring的MVC框架
Spring的IoC容器
Spring对AOP的支持
Spring2.5注释驱动与基于注释的MVC
本文出自 “绝缘材料” 博客,请务必保留此出处http://tonyaction.blog.51cto.com/227462/83874
相关文章推荐
- Spring2.5注释驱动与基于注释的MVC
- Spring2.5注释驱动与基于注释的MVC
- Spring2.5注释驱动与基于注释的MVC 推荐
- Spring2.5注释驱动与基于注释的MVC
- Spring2.5基于驱动的MVC
- 使用 Spring 2.5 基于注解驱动的 Spring MVC
- 使用 Spring 2.5 注释驱动的 IoC 功能
- 使用 Spring 2.5 注释驱动的 IoC 功能
- 使用 Spring 2.5 注释驱动的 IoC 功能
- 使用 Spring 2.5 注释驱动的 IoC 功能
- 使用 Spring 2.5 基于注解驱动的 Spring MVC
- 使用 Spring 2.5 基于注解驱动的 Spring MVC
- Spring2.5中基于注释的IoC
- 使用 Spring 2.5 基于注解驱动的 Spring MVC
- 使用 Spring 2.5 注释驱动的 IoC 功能
- 使用 Spring 2.5 基于注解驱动的 Spring MVC
- Spring2.5中基于注释的IoC
- 使用 Spring 2.5 注释驱动的 IoC 功能
- Spring 2.5 JPA 基于注解驱动的 Spring MVC教程
- 使用 Spring 2.5 基于注解驱动的 Spring MVC