Spring常用注解的用法和作用理解1

目录

一、实例

@Controller

@RequestMaping

@Service

@Resource

@Autowired

@Repository

@Component


在使用spring的时候这些标注都是必不可少的会用到。今天就总结一下它们各自的作用以及用法。

一、实例

  • 控制层
@Controller
@RequestMapping(value="/car")
public class Action{
    @Autowired
    private IocCarSrivice iocCarSrivice ;

    @RequestMapping(value="/carRun")
    public void carRun(){
        iocCarSrivice.run();
    }
}
  • service层
@Service
public class IocCarService{
    @Resource
    private IIocCarDao iIocCarDaoImpl;

    public void carRun(){
        iIocCarDaoImpl.run();
    }
}
  • Dao层
public interface IIocCarDao{
    void run();
}
  • Dao层实现类
@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)。

 

@Controller

   用法:标记于一个类上面 
   作用:用来注解这个bean(类)是MVC模型中的一个控制层,使分发处理器识别到该类,该类会被spring的auto-scan扫到纳入管理。通俗来,被这个标注类里面的方法加上@RequestMaping(“…”),就可以直接被浏览器调用然后做一些数据逻辑处理。 
   实例解释:如果要在浏览器访问Action类中的carRun方法(本地)127.0.0.1:8080/car/carRun

@RequestMaping

   用法:1.标记于一个被@Controller标注的类上 
      2.标记于被@Controller标注类里面的方法上面 
   作用:用法1,表示该被标注类下面所有方法的父类标注(可以理解为所有用法2“继承”用法1)@RequestMaping有六个属性value、method、consumes、produces、params、headers 
   value:指定浏览器请求的地址; 
   method:指定请求的method类型, GET、POST、PUT、DELETE等; 

@Controller
@RequestMapping("/appointments")
public class AppointmentsController {

    private AppointmentBook appointmentBook;
    
    @Autowired
    public AppointmentsController(AppointmentBook appointmentBook) {
        this.appointmentBook = appointmentBook;
    }

    @RequestMapping(method = RequestMethod.GET)
    public Map<String, Appointment> get() {
        return appointmentBook.getAppointmentsForToday();
    }

    @RequestMapping(value="/{day}", method = RequestMethod.GET)
    public Map<String, Appointment> getForDay(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date day, Model model) {
        return appointmentBook.getAppointmentsForDay(day);
    }

    @RequestMapping(value="/new", method = RequestMethod.GET)
    public AppointmentForm getNewForm() {
        return new AppointmentForm();
    }

    @RequestMapping(method = RequestMethod.POST)
    public String add(@Valid AppointmentForm appointment, BindingResult result) {
        if (result.hasErrors()) {
            return "appointments/new";
        }
        appointmentBook.addAppointment(appointment);
        return "redirect:/appointments";
    }
}

value的uri值为以下三类:

A) 可以指定为普通的具体值;

B)  可以指定为含有某变量的一类值(URI Template Patterns with Path Variables);

C) 可以指定为含正则表达式的一类值( URI Template Patterns with Regular Expressions);

example B)

@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable String ownerId, Model model) {
  Owner owner = ownerService.findOwner(ownerId);  
  model.addAttribute("owner", owner);  
  return "displayOwner"; 
}

example C)

@RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\d\.\d\.\d}.{extension:\.[a-z]}")
  public void handle(@PathVariable String version, @PathVariable String extension) {    
    // ...
  }
}


consumes:指定处理请求的提交内容类型(Content-Type),例如application/json, text/html; 

@Controller
@RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json")
public void addPet(@RequestBody Pet pet, Model model) {    
    // implementation omitted
}

方法仅处理request Content-Type为“application/json”类型的请求。

 

produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回; 

@Controller
@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json")
@ResponseBody
public Pet getPet(@PathVariable String petId, Model model) {    
    // implementation omitted
}

方法仅处理request请求中Accept头中包含了"application/json"的请求,同时暗示了返回的内容类型为application/json;

params:指定request中必须包含某些参数值是,才让该方法处理; 

@Controller
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController {

  @RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, params="myParam=myValue")
  public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {    
    // implementation omitted
  }
}

仅处理请求中包含了名为“myParam”,值为“myValue”的请求; 

headers:指定request中必须包含某些指定的header值,才能让该方法处理请求; 

@Controller
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController {

@RequestMapping(value = "/pets", method = RequestMethod.GET, headers="Referer=http://www.ifeng.com/")
  public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {    
    // implementation omitted
  }
}


   实例解释:如果要在浏览器访问Action类中的carRun方法,只需要本地域名+端口号+该标注所定义的value值即可(127.0.0.1:8080/car/carRun)   
   @RequestMaping常用的记住value和method,更详细的介绍——》链接

@Service

   用法:用于标注业务层组件(Service层)上 
   作用:标注于业务层组件上表示定义一个bean,自动根据所标注的组件名称实例化一个首字母为小写的bean。 
   实例解释:IocCarService类被标注为一个bean,bean名称为iocCarService,此时该类已经被spring纳入管理中,待使用

@Resource

   用法:标注于字段上或者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();
    }
}

此时将会输出:不是老司机也可以学开车。

@Autowired

   该注解和@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();
    }
}

@Repository

   用法:用户标注数据访问层组件(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("不是老司机也可以学开车。");
    }
}

@Component

   用法:泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。 
   作用:和前面@Service、@Repository、@Controller一样,只是它们比@Component更巨细化。

总结: 

@Repository、@Service、@Controller注解是使被标注的组件成为Bean被Spring纳入管理,而Bean的名称可以通过他们的属性自定义@Repository为数据访问层使用,@Service为Service层使用 

@Resource、@Autowired注解是使用已经被Spirng纳入管理的Bean。@Resource使用方式为ByName。@Autowired使用方式为ByType,结合@Qualifier使用可以变更为ByName。它们同样可以自定义调用的Bean名称

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值