SSM框架实战系列之八_注解
使用注解进行开发是非常便利的。以前在使用Spring框架进行开发时,需要在Spring框架的配置文件中定义所有的bean,并设置依赖注入。而现在,在代码中使用注解便可替代这一做法。
一、基本的注解
以编写三层结构的应用程序为例,我们的程序分为控制器层、业务逻辑层和数据处理层。用户请求首先到达控制器层,控制器层再调用业务逻辑层,业务逻辑层调用数据处理层。
使用注解进行三层结构的应用程序开发,需要在控制器类加上注解@Controller,业务逻辑类加上注解@Service,数据处理类加上注解@Repository(仓库)。
只要加上这些注解,由于上一节我们已经设置了Spring框架的组件扫描,因此Spring框架加载时,会查找到带注解的类,并创建它们的实例。
Spring框架很贴心地为三层结构应用程序分别规定了不同的注解,以凸显各层的作用。
二、依赖注入的实现
当一个类中使用另一个类作为属性时,只需在属性定义上加@Resource(资源)注解,即可实现依赖注入。
例如SchoolServiceImpl中使用了SchoolDao作为其属性,这时可以这样写:
@Service
public class SchoolServiceImpl implements SchoolService {
@Resource
private SchoolDao schoolDao; // 属性名应规范为接口名的小写形式
// 省略部分代码
}
三、实际案例
下面,以学校管理模块为例,展示各部分的代码,注意观察注解的使用。
1、项目的目录结构:
2、bean包中的实体类:
(实体类不需要任何注解,因为它不需要自动实例化,也没有依赖注入的要求)
package com.hanhf.ssm.bean;
public class School {
private int id;
private String name;
private Province province;
private String inCharge;
private String city;
private String schoolLevel;
private String remark;
private boolean del;
// 省略getter和setter
}
3、dao包中的数据处理接口(MyBatis不需要编写实现类,只需编写接口):
(数据处理类前使用@Repository注解,该类会被自动实例化)
package com.hanhf.ssm.dao;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.hanhf.ssm.bean.School;
@Repository
public interface SchoolDao {
void add(School school);
void del(int id);
void update(School school);
School getById(int id);
List<School> list(@Param("name") String name, @Param("provinceId") int provinceId, @Param("city") String city,
@Param("start") int start, @Param("length") int length);
int count(@Param("name") String name, @Param("provinceId") int provinceId, @Param("city") String city);
List<School> listByName(@Param("name") String name);
}
4、service包中的业务处理接口:
(接口中不使用注解,因为接口不能实例化,所以也就没有自动实例化和依赖注入的要求)
package com.hanhf.ssm.service;
import java.util.List;
import com.hanhf.ssm.bean.School;
public interface SchoolService {
void add(School school);
void del(int id);
void update(School school);
School get(int id);
List<School> list(String name, int provinceId, String city, int start, int length);
int count(String name, int provinceId, String city);
List<School> listByName(String name);
}
5、service.impl包中的业务处理类:
(业务逻辑类中使用@Service注解,同时注入对DAO的依赖)
package com.hanhf.ssm.service.impl;
import java.util.List;
import javax.annotation.Resource;
import javax.transaction.Transactional;
import org.springframework.stereotype.Service;
import com.hanhf.ssm.bean.School;
import com.hanhf.ssm.dao.SchoolDao;
import com.hanhf.ssm.service.SchoolService;
@Service
@Transactional
public class SchoolServiceImpl implements SchoolService {
@Resource
private SchoolDao schoolDao;
@Override
public void add(School school) {
schoolDao.add(school);
}
@Override
public void del(int id) {
schoolDao.del(id);
}
@Override
public void update(School school) {
schoolDao.update(school);
}
@Override
public School get(int id) {
return schoolDao.getById(id);
}
@Override
public List<School> list(String name, int provinceId, String city, int start, int length) {
return schoolDao.list(name, provinceId, city, start, length);
}
@Override
public int count(String name, int provinceId, String city) {
return schoolDao.count(name, provinceId, city);
}
@Override
public List<School> listByName(String name) {
return schoolDao.listByName(name);
}
}
6、controller包中的控制器类:
(控制器类使用@Controller注解,同时注入对Service的依赖)
package com.hanhf.ssm.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.hanhf.ssm.bean.DatatableData;
import com.hanhf.ssm.bean.Province;
import com.hanhf.ssm.bean.School;
import com.hanhf.ssm.service.ProvinceService;
import com.hanhf.ssm.service.SchoolService;
@Controller
@RequestMapping("/school")
public class SchoolController {
@Resource
private SchoolService schoolService;
@Resource
private ProvinceService provinceService;
@RequestMapping("/toList")
public String toList() {
return "school/list";
}
// 省略部分代码
}
注意:
注解通常都是加在实现类上的,因为只有实现类才能创建实例,接口是不能创建实例的。
然而MyBatis的DAO接口是一个特例,可以在DAO接口上加上注解,因为MyBatis不需要编写实现类,它会根据DAO接口自动生成代理类,所以可以这样用。