|
本文参考《精通Spring:JavaWeb开发技术详解》,作者:孙卫琴,清华大学出版社出版
当一个Web应用中的多个控制器类要完成一些共同的操作,传统的做法是定义一个控制器父类(例如BaseController),它包含了执行共同操作的方法,其他的控制器类(例如ControllerA和ControllerB)继承这个控制器父类。图1显示了控制器父类和控制器子类的关系。
图1 控制器父类和控制器子类的关系
继承是提高控制器类的代码可重用性的有效手段,但是它有一个缺陷,那就是由于Java语言不支持多继承,当控制器类继承了一个控制器父类后,就不能再继承其他的类。
Spring MVC框架提供了另一种方式来为多个控制器类提供共同的方法:利用@ControllerAdvice注解来定义一个控制器增强类。
控制器增强类并不是控制器类的父类。在程序运行时,Spring MVC框架会把控制器增强类的方法代码块动态注入到其他控制器类中,通过这种方式来增强控制器类的功能。图2显示了控制器增强类(例如MyControllerAdvice)和控制器类的关系。
图2 控制器增强类和控制器类的关系
以下例程1的MyControllerAdvice类的setColors()方法向Model中加入一个colors属性。
例程1 MyControllerAdvice.javapackage mypack;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
import java.util.*;
@ControllerAdvice
public class MyControllerAdvice {
@ModelAttribute(name = "colors")
public Map<String,String> setColors() {
HashMap<String, String> colors = new HashMap<String,String>();
colors.put("RED", "红色");
colors.put("BLUE", "蓝色");
colors.put("GREEN", "绿色");
return colors;
}
} |
当程序运行时,Spring MVC框架会把MyControllerAdvice类的setColors()方法动态注入到其他控制器类中,因此其他控制器类自动拥有了该方法。例如在TestAttributeController类中可以直接访问Model中的colors属性:
@RequestMapping(value="/testColor")
public String testColor(
@ModelAttribute("colors") Map<String,String> colors,
@ModelAttribute("userName") String name){
System.out.println(name+"'s favourite color:"+colors.get("RED"));
return "result";
} |
通过浏览器访问以下URL:
http://localhost:8080/helloapp/testColor?name=Tom
testColor()方法会在服务器端打印“TOM's favourite color:红色”。
默认情况下,@ControllerAdvice注解用来增强当前Web应用中所有控制器类的功能。此外,它的assignableTypes属性和basePackages属性用来指定需要增强功能的控制器类:
//增强PersonController和TestAttributeController的功能
@ControllerAdvice(assignableTypes={PersonController.class,
TestAttributeController.class})
public class MyControllerAdvice1{……}
//增强mypack包和net.javathinker包中的控制器类的功能
@ControllerAdvice(basePackages ={"mypack","net.javathinker"})
public class MyControllerAdvice2{……} |
程序猿的技术大观园:www.javathinker.net
|
|