SSM框架中註解含義及應用場景小結
先說一下什麼是元件掃描:
指定一個包路徑,Spring會自動掃描該包及其子包所有元件類,當發現元件類定義前有特定的註解標記時,就將該元件納入到Spring容器。等價於原有XML配置中的<bean>定義功能。
元件掃描可以替代大量XML配置的<bean>定義。
使用元件掃描,首先需要在XML配置中指定掃描類路徑
<context:component-scan
base-package = "org.example"/>
上面配置官網:www.fhadmin.org,容器例項化時會自動掃描org.example包及其子包下所有元件類。
指定掃描類路徑後,並不是該路徑下所有元件類都掃描到Spring容器的,只有在元件類定義前面有以下註解標記時,才會掃描到Spring容器。
@Component:通用註解;@Name:通用註解;@Repository:持久化層元件註解
@Service:業務層元件註解;@Controller:控制層元件註解
當一個元件在掃描過程中被檢測到時,會生成一個預設id值,預設id為小寫開頭的類名。也可以在註解標記中自定義id。下面兩個元件id名字分別是oracleUserDao和loginService
@Repository
public class OracleUserDao implements UserDao{
//.....
}
@Service("loginService")
public class UserService{
//....
}
官網:www.fhadmin.org通常受Spring管理的元件,預設的作用域是“singleton”。如果需要其他作用域可以使用@Scope註解,只要在註解中提供作用域的名稱即可。
@Scope("prototype")
@Repository
public class OracleUserDao implements EmpDao{
//...
}
@PostConstruct和@PreDestroy註解標記分別用於指定初始化和銷燬回撥方法,使用示例:
public class ExampleBean{
@PostConstruct
public void init(){
//初始化回撥方法
}
@PreDestroy
public void destroy(){
//銷燬回撥方法
}
}
具有依賴關係的Bean物件,利用下面任何一種註解都可以實現關係注入:
@Resource
@Autowired/@Qualifier
@Inject/@Named
@Resource註解標記可以用在欄位定義或setter方法定義前面,預設首先按名稱匹配注入,然後型別匹配注入:
public class UserService{
//@Resource
private UserDao userDao;
@Resource
public void setUserDao(UserDao dao){
this.userDao = dao;
}
}
當遇到多個匹配Bean時注入會發生錯誤,官網:www.fhadmin.org 可以顯示指定名稱,例如@Resource(name = "empDao1")
@Autowired註解標記也可以用在欄位定義或setter方法定義前面,預設按型別匹配注入:
public class UserService{
//@Autowired
private UserDao userDao;
@Autowired
public void setUserDao(UserDao dao){
this.userDao = dao;
}
}
@Autowired當遇到多個匹配Bean時注入會發生錯誤,可以使用下面方法指定名稱:
public class UserService{
//@Autowired
//@Qualifiter("mysqlUserDao")
private UserDao userDao;
@Autowired
public void setUserDao(@Qualifiter("mysqlUserDao") userDao dao){
this.userDao = dao;
}
}
@Inject註解標記是Spring3.0開始增添的對JSR-330標準的支援,使用前需要新增JSR-330的jar包,使用方法與@Autowired相似,具體如:
public class UserService{
//@Inject
private UserDao userDao;
@Inject
public void setUserDao(UserDao dao){
this.userDao = dao;
}
}
@Inject當遇到多個匹配Bean時注入會發生錯誤,可以使用@Named指定名稱限定,使用方法為:
public class UserService{
private UserDao userDao;
@Inject
public void setUserDao(@Named("mysqlUserDao") UserDao dao){
this.userDao = dao;
}
}
@Value註解可以注入Spring表示式值,使用方法:
首先在XML配置中指定要注入的properties檔案
<util:properties id = "jdbcProps" location = "classpath:db.properties"/>
然後在setter方法前使用@Value註解
public class JDBCDataSource{
@Value("#{jdbcProps.url}")
private String url;
@Value("#{jdbcProps.driver}")
public void setUrl(String driver){
try{Class.forName(driver)}catch(.....)...
}
}
RequestMapping註解應用
@RequestMapping可以用在類定義和方法定義上
@RequestMapping標明這個類或者方法與哪一個客戶請求對應
@RequestMapping可以定義在Controller類前和處理方法前,主要用於指定Controller的方法處理哪些請求
@Controller
@RequestMapping("/demo01")
public class Controller{
@RequestMapping("/hello")
public String execute()throws Exception{
return "hello";
}
}
開啟@RequestMapping註解對映,官網:www.fhadmin.org需要在Spring的XML配置檔案中定義RequestMappingHandlerMapping(類定義前)和RequestMappingHandlerAdapter(方法定義前)兩個bean元件
示例:
<bean
class ="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean
class = "org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
從Spring3.2版本開始可以使用下面XML配置簡化RequestMappingHandlerMapping和RequestMappingHandlerAdapter定義:
<mvc:annotation-driven/>
Controller註解應用
推薦使用@Controller註解宣告Controller元件,這樣可以使得Controller定義更加靈活,可以不用實現Controller介面,請求處理的方法也可以靈活定義
@Controller
@RequestMapping("/demo01")
public classs Controller{
@RequestMapping("/hello")
public String execute()throws Exception{
return "hello";
}
}
為了使@Controller註解生效,需要在Spring的XML配置檔案中開啟元件掃描定義,並指定Controller元件所在包
<context:component-scan base-package = "com.controller"/>
接受請求引數值
Spring MVC Web請求提交資料到控制器有下面幾種方法:
使用 HttpServletRequest獲取
使用@RequestParam註解
使用自動機制封裝成Bean物件
使用@RequestParam註解:
Spring會自動將表單引數注入到方法引數(名稱一致)
使用@RequestParam註解,對映不一致的名稱
優點引數型別會自動轉換,但可能出現型別轉換異常
@RequestMapping("/login-action.form")
public String checkLogin(String name,@RequestParam("pwd")String password,HttpServletRequest req){
System.out.println(name);
System.out.println(password);
User user = userService.login(name,password);
//處理過程
return "success";
使用@ModelAttribute註解是當Controller元件處理後,需要向JSP傳值用此方法。
(引出:向JSP頁面傳值也可以直接使用HttpServletRequest和Session;ModeAndView物件;ModelMap引數物件等)
示例:
在Controller方法的引數部分或Bean屬性方法上使用。
@RequestMapping("login-action.from")
public String checkLogin(@ModelAttribute("user")User user){
//處理過程
return "success";
}
@ModelAttribute("name")
public String getName(){
return name;
}
(@ModelAttribute資料會利用HttpServletRequest的Attribute傳遞到JSP頁面中)
@ExceptionHandler註解
@ExceptionHandler註解提供了Spring MVC處理異常的方法
(引出:Spring MVC處理異常的方法有三種:使用Spring MVC提供的簡單異常處理器(SimpleMappingExceptionResolver);實現HandlerExceptionResolver介面自定義異常處理器;使用 @ExceptionHandler註解實現異常處理)
@ExceptionHandler註解使用方法:
public class BaseController{
@ExceptionHandler
public String execute(HttpServletRequest req,Exception e){
req.setAttribute("e",e);
//可根據異常型別不同返回不同檢視名
return "error";
}
}
(適合區域性處理有“處理過程”的異常)
然後其他的Controller繼承BaseController類即可
@ResponseBody註解(在Spring MVC中,此註解與JSON響應相關)
在控制器方法上使用 @ResponseBody 註解, 就可以自動的將控制器的返回值(JavaBean)轉換為JSON傳送到客戶端.
@ResponseBody註解主要用於Controller元件的處理方法前,使用方法為:
引入jackson開發包,後面示例用的是jackson-annotations-2.4.1.jar,jackson-core-2.4.1.jar,jackson-databind-2.4.1.jar
在Spring配置檔案中定義<mvc:annotation-driven/>,開啟對@ResponseBody應用的支援
在Controller處理方法前定義@ResponseBody註解
示例:
使用@ResponseBody,返回單個值:
@RequestMapping("/test1")
@ResponseBody
public boolean f1(){
//業務處理程式碼
return true;
}
使用@ResponseBody返回多個值:
@RequestMapping("/test2")
@ResponseBody
public Map<String,Object>f2(){
Map<String,Object> m = new HashMap<String,Object>)();
m.put("id",1);
m.put("name","Tom");
return m;
}
使用@ResponseBody返回List結果:
@RequestMapping("/test3")
@ResponseBody
public List<String>f3(){
List<String> list = new ArrayList<String>();
list.add("java");
list.add("php");
list.add("ui");
return list;
}
使用@ResponseBody返回物件結果:
@RequestMapping("/test4")
@ResponseBody
public Object f4(){
Object obj = new Object();
return obj;
}
使用@ResponseBody返回物件集合結果:
@RequestMapping("/test5")
@ResponseBody
public Object f5(){
Emp e1 = new Emp();
e1.setId(1);
e1.setName("張三");
Emp e2 = new Emp();
e2.setId(2);
e2.setName("李四");
List<Emp> list = new ArrayList<Emp>();
list.add(e1);
;ist.add(e2);
return list;
}
註解實現AOP
開發步驟:
建立方面元件:
建立一個類,充當方面元件,實現通用業務邏輯。
宣告方面元件官網:www.fhadmin.org:
在applicationContext.xml中開啟AOP註解掃描:
<aop:aspectj-autoproxy proxy-target-class = "true"/>;
使用@Component註解標識這個類,將其宣告為元件。
使用@Aspect註解標識這個類,將其宣告為方面元件。
使用方面元件:
在元件的方法上,使用註解將方面元件作用到目標元件的方法上,並設定通知型別以確認方面元件呼叫的時機。
使用前置通知,在方面元件方法上增加註解:
@Before("within(controller..*)")
public void log(){
}
後置通知、最終通知使用方法與前置通知一致,只需要將註解改為@AfterReturning、@After即可。
環繞通知,在方面元件方法上增加註解:
@Around("within(controller..*)")
public Object log(ProceedingJoinPoint p) throws Throwable{
//此處程式碼在目標元件前執行
Object obj = p.proceed();//執行目標元件方法
//此處程式碼在目標元件後執行
return obj;
}
使用異常通知,在方面元件方法上增加註解:
@AfterThrowing(pointcut = "within(controller..*)",throwing = "e")
public void log(Exception e){
}
@Transactional註解
此註解實現宣告式事務,步驟如下:
在applicationContext.xml中宣告事務元件官網:www.fhadmin.org,開始事務註解掃描,示例為:
<!-- 宣告事務管理元件 -->
<bean id = "txManager"
class = "org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name = "dataSource" ref = "ds"/>
</bean>
<!-- 開啟事務註解掃描 -->
<tx:annotation-driven transaction-manager = "txManager" proxy-target-class = "true"/>
transaction-manager指定的事務管理器txManager,需要根據資料庫訪問技術不同選擇不同的實現。例如JDBC、Mybatis技術選用DataSourceTransactionManager,而Hibernate技術則選用HibernateTransactionManager.
使用 @Transactional註解宣告事務,使用方法為:
@Transactional
public class DefaultFooService implements FooService{
// @Transactional
public void insertFoo(Foo foo){...}
public void updateFoo(Foo foo){...}
@Transactional註解標記可以用在類定義和方法定義前,方法的事務設定將優先於類級別註解的事務設定。
@Transactional註解標記有以下屬性,在使用時可以根據需要做特殊設定:
- propagation:設定事務傳播
- isolation:設定事務隔離級別
- readOnly:設定為只讀,還是可讀寫
- rollbackFor:設定遇到哪些異常必須回滾
- noRollbackFor:設定遇到哪些異常不回滾
@Transactional註解屬性預設設定如下:
事務傳播設定是:PROPAGATION_REQUIRED
事務隔離級別是:ISOLATION_DEFAULT
事務是讀/寫
事務超時預設是依賴於事務系統的,或者事務超時沒有被支援
任何RuntimeException將觸發事務回滾,但是任何Checked Exception將不觸發事務回滾
@PathVariable應用
@PathVariable作用是將URI請求模板中的變數解析出來,對映到處理方法的引數上,示例為:
@RequestMapping(value = "/emp/{id}",method = requestMethod.GET)
public String execute(@PathVariable("id") int id){
//查詢操作處理
return " ";
}
上述URI請求模板匹配/emp/1、emp/2等格式請求