在使用spring的时候这些标注都是必不可少的会用到。今天就总结一下它们各自的作用以及用法。
@Controller
@RequestMapping(value="/car")
public class Action{
@Autowired
private IocCarSrivice iocCarSrivice ;
@RequestMapping(value="/carRun")
public void carRun(){
iocCarSrivice.run();
}
}
@Service
public class IocCarService{
@Resource
private IIocCarDao iIocCarDaoImpl;
public void carRun(){
iIocCarDaoImpl.run();
}
}
public interface IIocCarDao{
void run();
}
@Repository
public class IIocCarDaoImpl implements IIocCarDao{
@Override
public void run(){
System.out.println("老司机才可以开车。");
}
}
package CarTest;
import java.util.Date;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.kq.domain.TransPayLog;
import com.kq.service.TransPayLogService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class CarTest{
@Autowired
private IocCarService iocCarService;
@Test
public void Test3_7(){
iocCarService.carRun();
}
}
输入:老司机才可以开车。
注:以上就是一个最简单的三层架构,如果是发布到Tomcat下面,服务器会按照@Controller标注让Spring Bean工厂自动注入控制层实例,然后浏览@RequestMapping上面的路径,就可以通过一系列标注访问Dao层。此处测试因为没有发布,所以直接使用手动注入(关于怎么手动注入可以参考CarTest类上面的注解,或者直接使用BeanFactory)。
下面以上为例解释注解(在所有配置文件都齐全的情况下)
用法:标记于一个类上面
作用:用来注解这个bean(类)是MVC模型中的一个控制层,使分发处理器识别到该类,该类会被spring的auto-scan扫到纳入管理。通俗来,被这个标注类里面的方法加上@RequestMaping(“…”),就可以直接被浏览器调用然后做一些数据逻辑处理。
实例解释:如果要在浏览器访问Action类中的carRun方法(本地)127.0.0.1:8080/car/carRun
用法:1.标记于一个被@Controller标注的类上
2.标记于被@Controller标注类里面的方法上面
作用:用法1,表示该被标注类下面所有方法的父类标注(可以理解为所有用法2“继承”用法1)@RequestMaping有六个属性value、method、consumes、produces、params、headers
value:指定浏览器请求的地址;
method:指定请求的method类型, GET、POST、PUT、DELETE等;
consumes:指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
params:指定request中必须包含某些参数值是,才让该方法处理;
headers:指定request中必须包含某些指定的header值,才能让该方法处理请求;
实例解释:如果要在浏览器访问Action类中的carRun方法,只需要本地域名+端口号+该标注所定义的value值即可(127.0.0.1:8080/car/carRun)
@RequestMaping常用的记住value和method,更详细的介绍——》链接
用法:用于标注业务层组件(Service层)上
作用:标注于业务层组件上表示定义一个bean,自动根据所标注的组件名称实例化一个首字母为小写的bean。
实例解释:IocCarService类被标注为一个bean,bean名称为iocCarService,此时该类已经被spring纳入管理中,待使用
用法:标注于字段上或者setter方法上,@Resource默认按ByName进行自动装配
作用:用来自动装配Bean,激活一个命名资源的依赖注入。@Resource属性name可以定义被自动装配Bean的名称
实例解释:在IocCarService类中IIocCarDao 的实现类已经被@Repository标注为一个被Spring管理的Bean,此时需要用到它的时候只需要在属性名称上标注@Resource用户自动装配就可以了。
情况1: 如果加上如下代码,打印输出的还是:只有老司机才可以开车。
@Repository
public class IIocCarDaoImplXXX implements IIocCarDao{
@Override
public void run(){
System.out.println("不是老司机也可以学开车。");
}
}
这就很奇怪了,两个实现类。程序怎么知道我要调用哪一个呢。
因为在CarService类中我们的属性名(private IIocCarDao iIocCarDaoImpl;)是iIocCarDaoImpl而不是刚刚加入的iIocCarDaoImplXXX 所以打印出来的也就是只有老司机才可以开车。
情况2:如果CarServicer类中我们将属性名改变(private IIocCarDao iIocCarDaoImplYYY;)
那么此时会报错(org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.ulewo.ioc.IIocCarDaoImplYYY] is defined: expected single matching bean but found 2: iIocCarDaoImpl,iIocCarDaoImplXXX),意思是程序找到两个Bean,名称为iIocCarDaoImpl和iIocCarDaoImplXXX,但是没有我们的iIocCarDaoImplYYY,所以报错了。
此时解决方案可以使改变属性名称,还可以在@Resource注解上面给其定义正确的名称,如这样:
@Service
public class IocCarService{
@Resource(name="iIocCarDaoImplYYY")
private IIocCarDao iIocCarDaoImpl;
public void carRun(){
iIocCarDaoImpl.run();
}
}
此时将会输出:不是老司机也可以学开车。
该注解和@Resource的用法和作用基本一致。
不同点:1. @Resource属于J2EE,@Autowired属于Spring
2.@Autowired是根据类型(ByType)进行自动装配的
3.@Autowired没有name属性,如果要按名称进行装配,需要配合@Qualifier使用
@Service
public class IocCarService{
@Resource(name="iIocCarDaoImplYYY")
private IIocCarDao iIocCarDaoImpl;
public void carRun(){
iIocCarDaoImpl.run();
}
}
//等价于
@Service
public class IocCarService{
@Autowired
@Qualifie("iIocCarDaoImplYYY")
private IIocCarDao iIocCarDaoImpl;
public void carRun(){
iIocCarDaoImpl.run();
}
}
用法:用户标注数据访问层组件(Dao层)
作用:实现Dao访问;将类识别为Bean,同时它将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型。
实例解释:Dao层实现类IIocCarDaoImpl 被Spring装载为bean纳入管理中,bean名称为iIocCarDaoImpl。 同时它将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型。
如果需要自定义Bean名称只需要改变该注解的value属性值
@Repository(value="IIocCarDaoImplZZZ")
public class IIocCarDaoImpl implements IIocCarDao{
@Override
public void run(){
System.out.println("不是老司机也可以学开车。");
}
}
此时如果按ByName使用这个bean,在@Resource或者@Autowired下面的属性名称将变为iIocCarDaoImplZZZ或者@Resource(name=”iIocCarDaoImplZZZ”)或者@Autowired+@Qualifie(“iIocCarDaoImplZZZ”)
用法:泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
作用:和前面@Service、@Repository、@Controller一样,只是它们比@Component更巨细化。
总结下:
@Repository、@Service注解是使被标注的组件成为Bean被Spring纳入管理,而Bean的名称可以通过他们的属性自定义@Repository为数据访问层使用,@Service为Service层使用
@Resource、@Autowired注解是使用已经被Spirng纳入管理的Bean。@Resource使用方式为ByName。@Autowired使用方式为ByType,结合@Qualifier使用可以变更为ByName。它们同样可以自定义调用的Bean名称