@Component-@Resource-@Repository-@Service-@Controller的区别和理解-------springMVC

1.作用:@Component------------------------泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。(Component-------成分; 组分; 零件)@Resource------------------------(资源)@Autowired-----------------------(自动绑定)@Repository-----------------------于标注数据访问组件,即DAO组件(repository-------仓库; 贮藏室,容器。)@Service----------------------------用于标注业务层组件(我们通常定义的service层就用这个)  @Controller-------------------------用于标注控制层组件(如struts中的action)这几个注解的作用相同:都是为实现所在类(即组件)的bean的转化,然后可以在容器中调用。然后从名字上的作用就是可以明确各个层次和层次的作用首先还是先了解为什么要bean转化。 虽然下面内容超多,但是看完真的有不少帮助,若是你不是很了解的话。 spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository、@Service 和 @Controller。在目前的 Spring 版本中,这 3 个注释和 @Component 是等效的,但是从注释类的命名上,很容易看出这 3 个注释分别和持久层、业务层和控制层(Web 层)相对应。虽然目前这 3 个注释和 @Component 相比没有什么新意,但 Spring 将在以后的版本中为它们添加特殊的功能。所以,如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释,而用 @Component 对那些比较中立的类进行注释。 

在一个稍大的项目中,通常会有上百个组件,如果这些组件采用xml的bean定义来配置,显然会增加配置文件的体积,查找以及维护起来也不太方便。 Spring2.5为我们引入了组件自动扫描机制,他可以在类路径底下寻找标注了@Component,@Service,@Controller,@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件时一样的。要使用自动扫描机制,我们需要打开以下配置信息: Java代码  
  1. xml version="1.0" encoding="UTF-8" ?> <beansxmlnsbeansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-2.5.xsd"   
  2. >   
  3.     
  4. <context:component-scan base-package=”com.eric.spring”>     
  5. beans>    
 其中base-package为需要扫描的包(含所有子包) @Service用于标注业务层组件,@Controller用于标注控制层组件(如struts中的action),@Repository用于标注数据访问组件,即DAO组件,而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。    @Service public class VentorServiceImpl implements iVentorService{ } @Repository public class VentorDaoImpl implements iVentorDao {} getBean的默认名称是类名(头字母小写),如果想自定义,可以@Service(“aaaaa”)这样来指定,这种bean默认是单例的,如果想改变,可以使用@Service(“beanName”)@Scope(“prototype”)来改变。可以使用以下方式指定初始化方法和销毁方法(方法名任意): @PostConstruct public void init() { } 
@PreDestroy public void destory() { } 

注入方式: 
把DAO实现类注入到service实现类中,把service的接口(注意不要是service的实现类)注入到action中,注入时不要new 这个注入的类,因为spring会自动注入,如果手动再new的话会出现错误,然后属性加上@Autowired后不需要getter()和setter()方法,Spring也会自动注入。至于更具体的内容,等对注入的方式更加熟练后会做个完整的例子上来。 

注解在spring的配置文件里面只需要加上,可以使用base-package="*"表示全部的类。
< context:component-scan base-package=”com.eric.spring”> 
其中base-package为需要扫描的包(含所有子包) 

在接口前面标上@Autowired和@Qualifier注释使得接口可以被容器注入,当接口存在两个实现类的时候必须指定其中一个来注入,使用实现类首字母小写的字符串来注入,如: 
    @Autowired      
    @Qualifier("chinese")      
     private Man man;    
否则可以省略,只写@Autowired  。 

Spring中@Autowired注解、@Resource注解的区别

Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource@PostConstruct以及@PreDestroy
@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
@Resource装配顺序
1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配; @Autowired 与@Resource的区别:

1、 @Autowired与@Resource都可以用来装配bean.都可以写在字段上,或写在setter方法上。
2、@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false),如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:
a.@Autowired() @Qualifier("baseDao")
b.private BaseDao baseDao;
3、@Resource(这个注解属于J2EE的),默认安装名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
a.@Resource(name="baseDao")
b.private BaseDao baseDao;

推荐使用:@Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与spring的耦合。这样代码看起就比较优雅。使用Spring2.5的新特性——Autowired可以实现快速的自动注入,而无需在xml文档里面添加bean的声明,大大减少了xml文档的维护(我想到安卓日博投注规则_皇冠日博怎么了_日博官方网址是不是有一个xml里面每个页面都要在这声明,类似的原理,原来web日博投注规则_皇冠日博怎么了_日博官方网址也是这么滴,注解出现后,就不用一个个声明啦)。(偶喜欢这个功能,因为偶对xml不感冒以下是一个例子:
  1.  先编写接口Man:    
  2.         public interface Man {    
  3.             public String sayHello();    
  4.  }    
  5. 然后写Man的实现类Chinese和American:    
  6.        @Service    
  7. public class Chinese implements Man{    
  8.     public String sayHello() {    
  9.         return "I am Chinese!";    
  10.     }    
  11. }    
  12.     
  13.        @Service    
  14. public class American implements Man{    
  15.     public String sayHello() {    
  16.         return "I am American!";    
  17.     }    
  18. }   
@Service注释表示定义一个bean,自动根据bean的类名实例化一个首写字母为小写的bean,例如Chinese实例化为chinese,American实例化为american,如果需要自己改名字则:@Service("你自己改的bean名")。 beans.xml  
  1. xml version="1.0" encoding="UTF-8"?>    
  2. <beans xmlns="http://www.springframework.org/schema/beans"    
  3.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
  4.         xmlns:context="http://www.springframework.org/schema/context"    
  5.         xsi:schemaLocation="http://www.springframework.org/schema/beans     
  6.            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd    
  7.            http://www.springframework.org/schema/context    
  8.            http://www.springframework.org/schema/context/spring-context-2.5.xsd">    
  9.       <context:annotation-config/>    
  10.       <context:component-scan base-package="testspring.main"/>    
  11. beans>  
在spring的配置文件里面只需要加上,可以使用base-package="*"表示全部的类。 
  1. 编写主类测试:    
  2. @Service    
  3. public class Main {    
  4.     @Autowired    
  5.     @Qualifier("chinese")    
  6.     private Man man;    
  7.     public static void main(String[] args) {    
  8.         // TODO code application logic here    
  9.         ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");    
  10.         Main main = (Main) ctx.getBean("main");    
  11.         System.out.println(main.getMan().sayHello());    
  12.     }    
  13.     public Man getMan() {    
  14.         return man;    
  15.     }    
  16. }  
在Man接口前面标上@Autowired和@Qualifier注释使得Man接口可以被容器注入,当Man接口存在两个实现类的时候必须指定其中一个来注入,使用实现类首字母小写的字符串来注入。否则可以省略,只写@Autowired  注释配置相对于 XML 配置具有很多的优势:  
    它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作。如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO 的属性名、类型等信息,如果关系表字段和 PO 属性名、类型都一致,您甚至无需编写任务属性映射信息——因为这些信息都可以通过 Java 反射机制获取。   
注释和 Java 代码位于一个文件中,而 XML 配置采用独立的配置文件,大多数配置信息在程序日博投注规则_皇冠日博怎么了_日博官方网址完成后都不会调整,如果配置信息和 Java 代码放在一起,有助于增强程序的内聚性。而采用独立的 XML 配置文件,程序员在编写一个功能时,往往需要在程序文件和配置文件中不停切换,这种思维上的不连贯会降低日博投注规则_皇冠日博怎么了_日博官方网址效率。   
因此在很多情况下,注释配置比 XML 配置更受欢迎,注释配置有进一步流行的趋势。Spring 2.5 的一大增强就是引入了很多注释类,现在您已经可以使用注释配置完成大部分 XML 配置的功能。在这篇文章里,我们将向您讲述使用注释进行 Bean 定义和依赖注入的内容。原来我们是怎么做的在使用注释配置之前,先来回顾一下传统上是如何配置 Bean 并完成 Bean 之间依赖关系的建立。下面是 3 个类,它们分别是 Office、Car 和 Boss,这 3 个类需要在 Spring 容器中配置为 Bean:
  1.  Office 仅有一个属性:    
  2.  1. Office.java    
  3.  package com.baobaotao;    
  4.  public class Office {    
  5.      private String officeNo =”001”;     
  6.     //省略 get/setter    
  7.      @Override    
  8.      public String toString() {    
  9.          return "officeNo:" + officeNo;    
  10.      }    
  11.  }    
  12.  Car 拥有两个属性:    
  13. 2. Car.java    
  14.   package com.baobaotao;    
  15.   public class Car {    
  16.       private String brand;    
  17.       private double price;    
  18.       // 省略 get/setter    
  19.       @Override    
  20.       public String toString() {    
  21.           return "brand:" + brand + "," + "price:" + price;    
  22.       }    
  23.   }    
  24.   Boss 拥有 Office 和 Car 类型的两个属性:    
  25.  3. Boss.java    
  26.   package com.baobaotao;    
  27.   public class Boss {    
  28.       private Car car;    
  29.      private Office office;    
  30.        // 省略 get/setter    
  31.        @Override    
  32.       public String toString() {    
  33.          return "car:" + car + "n" + "office:" + office;    
  34.      }    
  35.   }   
我们在 Spring 容器中将 Office 和 Car 声明为 Bean,并注入到 Boss Bean 中:下面是使用传统 XML 完成这个工作的配置文件 beans.xml: 4. beans.xml 将以上三个类配置成 Bean
  1.  xml version="1.0" encoding="UTF-8" ?>    
  2.  <beans xmlns="http://www.springframework.org/schema/beans"    
  3.      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans     
  5.   http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">    
  6.      <bean id="boss" class="com.baobaotao.Boss">    
  7.          <property name="car" ref="car"/>    
  8.         <property name="office" ref="office" />    
  9.     bean>    
  10.     <bean id="office" class="com.baobaotao.Office">    
  11.         <property name="officeNo" value="002"/>    
  12.      bean>    
  13.      <bean id="car" class="com.baobaotao.Car" scope="singleton">    
  14.          <property name="brand" value=" 红旗 CA72"/>    
  15.         <property name="price" value="2000"/>    
  16.     bean>    
  17. beans>    
  18.  当我们运行以下代码时,控制台将正确打出 boss 的信息:  
  1. 5. 测试类:AnnoIoCTest.java    
  2.   import org.springframework.context.ApplicationContext;    
  3.   import org.springframework.context.support.ClassPathXmlApplicationContext;    
  4.   public class AnnoIoCTest {    
  5.      public static void main(String[] args) {    
  6.           String[] locations = {"beans.xml"};    
  7.           ApplicationContext ctx =     
  8.              new ClassPathXmlApplicationContext(locations);    
  9.          Boss boss = (Boss) ctx.getBean("boss");    
  10.          System.out.println(boss);    
  11.       }    
  12.   }  
使用 @Autowired 注释 
Spring 2.5 引入了 @Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。来看一下使用 @Autowired 进行成员变量自动注入的代码:
  1. 6. 使用 @Autowired 注释的 Boss.java    
  2.  package com.baobaotao;    
  3.  import org.springframework.beans.factory.annotation.Autowired;    
  4.  public class Boss {    
  5.     @Autowired    
  6.      private Car car;    
  7.          @Autowired    
  8.      private Office office;    
  9.      …    
  10.  }    
  11.  Spring 通过一个 BeanPostProcessor 对 @Autowired 进行解析,所以要让 @Autowired 起作用必须事先在 Spring 容器中声  明 AutowiredAnnotationBeanPostProcessor Bean。    
  12. 7. 让 @Autowired 注释工作起来    
  13.  "1.0" encoding="UTF-8" ?>    
  14.  <>"http://www.springframework.org/schema/beans"    
  15.      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
  16.      xsi:schemaLocation="http://www.springframework.org/schema/beans     
  17.   http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">    
  18.          
  19.      <>class="org.springframework.beans.factory.annotation.    
  20.          AutowiredAnnotationBeanPostProcessor"/>    
  21.     
  22.         
  23.     <>"boss" class="com.baobaotao.Boss"/>    
  24.        <>"office" class="com.baobaotao.Office">    
  25.          <>"officeNo" value="001"/>    
  26.          
  27.      <>"car" class="com.baobaotao.Car" scope="singleton">    
  28.          <>"brand" value=" 红旗 CA72"/>    
  29.        <>"price" value="2000"/>    
  30.         
  31.      
这样,当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired
注释时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。 按照上面的配置,Spring 将直接采用 Java 反射机制对 Boss 中的 car 和 office 这两个私有成员变量进行自动注入。所以对成员变量使用 @Autowired 后,您大可将它们的 setter 方法(setCar() 和 setOffice())从 Boss 中删除。当然,您也可以通过 @Autowired 对方法或构造函数进行标注,来看下面的代码:
  1. 8. 将 @Autowired 注释标注在 Setter 方法上    
  2.  package com.baobaotao;    
  3.  public class Boss {    
  4.      private Car car;    
  5.      private Office office;    
  6.      
  7.       @Autowired    
  8.     public void setCar(Car car) {    
  9.         this.car = car;    
  10.     }    
  11.   
  12.     @Autowired    
  13.      public void setOffice(Office office) {    
  14.          this.office = office;    
  15.     }    
  16.      …    
  17.  }    
  18.  这时,@Autowired 将查找被标注的方法的入参类型的 Bean,并调用方法自动注入这些 Bean。而下面的使用方法则对构造函数进行标注:    
  19. 9. 将 @Autowired 注释标注在构造函数上    
  20.  package com.baobaotao;    
  21.  public class Boss {    
  22.      private Car car;    
  23.      private Office office;    
  24.   
  25.      @Autowired    
  26.      public Boss(Car car ,Office office){    
  27.          this.car = car;    
  28.         this.office = office ;    
  29.     }    
  30.     …    
  31. }    
  32.  由于 Boss() 构造函数有两个入参,分别是 car 和 office,@Autowired 将分别寻找和它们类型匹配的 Bean,将它们作为 Boss(Car car ,Office office) 的入参来创  建 Boss Bean。  
当候选 Bean 数目不为 1 时的应对方法在默认情况下使用 @Autowired 注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。当找不到一个匹配的 Bean 时,Spring 容器将抛出 BeanCreationException 异常,并指出必须至少拥有一个匹配的 Bean。我们可以来做一个实验:
  1. 10. 候选 Bean 数目为 0 时    
  2.  xml version="1.0" encoding="UTF-8" ?>    
  3.  <beans xmlns="http://www.springframework.org/schema/beans"    
  4.      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
  5.       xsi:schemaLocation="http://www.springframework.org/schema/beans     
  6.   http://www.springframework.org/schema/beans/spring-beans-2.5.xsd ">    
  7.       
  8.     <bean class="org.springframework.beans.factory.annotation.    
  9.          AutowiredAnnotationBeanPostProcessor"/>     
  10.        <bean id="boss" class="com.baobaotao.Boss"/>    
  11.      
  12.         
  13.     

相关内容推荐