Spring注解注入

转自:http://blog.csdn.net/cpf2016/article/details/45582399

1.xml中配置bean

        假如我们现在有3个类,Boss、Office、Car,这3个类需要在Spring容器中配置为bean

[java]  view plain copy
  1. public class Office {  
  2.     private String officeNo =”001”;  
  3.   
  4.     //省略 get/setter  
  5.   
  6.     @Override  
  7.     public String toString() {  
  8.         return "officeNo:" + officeNo;  
  9.     }  
  10. }  
[java]  view plain copy
  1. public class Car {  
  2.     private String brand;  
  3.     private double price;  
  4.   
  5.     // 省略 get/setter  
  6.   
  7.     @Override  
  8.     public String toString() {  
  9.         return "brand:" + brand + "," + "price:" + price;  
  10.     }  
  11. }  
[java]  view plain copy
  1. public class Boss {  
  2.     private Car car;  
  3.     private Office office;  
  4.   
  5.     // 省略 get/setter  
  6.   
  7.     @Override  
  8.     public String toString() {  
  9.         return "car:" + car + "\n" + "office:" + office;  
  10.     }  
  11. }  
           现在在beans.xml中将以上3个类配置成bean

[html]  view plain copy
  1.                   
  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.     <bean id="boss" class="com.baobaotao.Boss">  
  8.         <property name="car" ref="car"/>  
  9.         <property name="office" ref="office" />  
  10.     </bean>  
  11.     <bean id="office" class="com.baobaotao.Office">  
  12.         <property name="officeNo" value="002"/>  
  13.     </bean>  
  14.     <bean id="car" class="com.baobaotao.Car" scope="singleton">  
  15.         <property name="brand" value=" 红旗 CA72"/>  
  16.         <property name="price" value="2000"/>  
  17.     </bean>  
  18. </beans>  
             这样的话就完成了依赖注入。

             测试代码如下:

[java]  view plain copy
  1. import org.springframework.context.ApplicationContext;  
  2. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  3. public class AnnoIoCTest {  
  4.   
  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. }  
               控制台正确打出了Boss的信息,说明Spring已经正确完成了实例的注入

2.@Autowired

        (1)要求

               Spring通过一个BeanPostProcessor对@Autowired进行解析,要使@Autowired起作用,则必须在Spring容器中声明AutowiredAnnotationBeanPostProcessor的Bean

[html]  view plain copy
  1. <!-- 该 BeanPostProcessor 将自动起作用,对标注 @Autowired 的 Bean 进行自动注入 -->      
  2. <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>  
               这样,当Spring容器启动时,AutowiredAnnotationBeanPostProcessor将扫描Spring中的所有bean,如果发现bean中拥有@Autowired注解时,就找到何其匹配( 默认按类型匹配 )的bean,并注入到对应的地方中去。

          如果是在成员变量上使用的话:因为是直接使用反射对bean中的私有成员变量进行注入的,所以使用了@Autowired注解之后,可以直接删除setter方法

        (2)成员变量上使用

[java]  view plain copy
  1. public class Boss {  
  2.     @Autowired  
  3.     private Car car;  
  4.     @Autowired  
  5.     private Office office;  
  6.   
  7.     @Override  
  8.     public String toString() {  
  9.         return "car:" + car + "\n" + "office:" + office;  
  10.     }  
  11. }  
               beans.xml改为

[html]  view plain copy
  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.    
  7.     <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>  
  8.    
  9.     <bean id="boss" class="com.mycompany.app.Boss">  
  10.     </bean>  
  11.     <bean id="office" class="com.mycompany.app.Office">  
  12.         <property name="officeNo" value="002"/>  
  13.     </bean>  
  14.     <bean id="car" class="com.mycompany.app.Car" scope="singleton">  
  15.         <property name="brand" value=" 红旗 CA72"/>  
  16.         <property name="price" value="2000"/>  
  17.     </bean>  
  18. </beans>  
                结果为:

car:brand: 红旗 CA72,price:2000.0
office:officeNo:002

        (3)set方法上使用

[java]  view plain copy
  1. package com.mycompany.app;  
  2.   
  3. import org.springframework.beans.factory.annotation.Autowired;  
  4.   
  5. public class Boss {  
  6.     private Car car;  
  7.     private Office office;  
  8.   
  9.     @Autowired  
  10.     public void setCar(Car car) {  
  11.         this.car = car;  
  12.     }  
  13.   
  14.     @Autowired  
  15.     public void setOffice(Office office) {  
  16.         this.office = office;  
  17.     }  
  18.   
  19.     @Override  
  20.     public String toString() {  
  21.         return "car:" + car + "\n" + "office:" + office;  
  22.     }  
  23. }  

        这时,@Autowired将查找被标注的方法的传入参数类型的bean,并调用方法自动注入这些bean 

       (4)构造方法上使用

[java]  view plain copy
  1. package com.mycompany.app;  
  2.   
  3. import org.springframework.beans.factory.annotation.Autowired;  
  4.   
  5. public class Boss {  
  6.     private Car car;  
  7.     private Office office;  
  8.   
  9.      
  10.     @Autowired  
  11.     public Boss(Car car, Office office) {  
  12.         super();  
  13.         this.car = car;  
  14.         this.office = office;  
  15.     }  
  16.   
  17.     @Override  
  18.     public String toString() {  
  19.         return "car:" + car + "\n" + "office:" + office;  
  20.     }  
  21. }  
          由于Boss构造方法有两个入参,分别是car和office,@Autowired将分别寻找和他们类型匹配的bean,将他们作为入参来创建Boss bean

3.@Qualifier

        (1)引入及作用

                  当我们在Spring容器中配置了2个类型为Office类型的bean,当对Boss的office成员变量进行自动注入时,Spring容器将无法确定到底使用哪一个bean,就会发生异常。

[html]  view plain copy
  1. <bean id="boss" class="com.mycompany.app.Boss">  
  2. </bean>  
  3. <bean id="office1" class="com.mycompany.app.Office">  
  4.     <property name="officeNo" value="002"/>  
  5. </bean>  
  6.  <bean id="office2" class="com.mycompany.app.Office">  
  7.     <property name="officeNo" value="004"/>  
  8. </bean>  
              运行后抛出异常

[html]  view plain copy
  1. Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.mycompany.app.Office] is defined: expected single matching bean but found 2: [office1, office2]  

                 Spring中允许我们通过@Qualifier注释指定注入bean的名称,这样歧义就消除了,可以通过如下方法解决异常

[java]  view plain copy
  1. package com.mycompany.app;  
  2.   
  3. import org.springframework.beans.factory.annotation.Autowired;  
  4. import org.springframework.beans.factory.annotation.Qualifier;  
  5.   
  6. public class Boss {  
  7.     @Autowired  
  8.     private Car car;  
  9.     @Autowired  
  10.     @Qualifier("office1")  
  11.     private Office office;  
  12.   
  13.     @Override  
  14.     public String toString() {  
  15.         return "car:" + car + "\n" + "office:" + office;  
  16.     }  
  17. }  
             

4.@Resource

        (1)作用

                   @Resource作用相当于@Autowired,只不过 @Autowired按byType自动注入,@Resource按byName自动注入

                   @Resource有两个比较重要的属性:name和type,Spring将@Resource注释的name属性解析为bean的名字,而type属性解析为bean的类型。

                   所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果不指定name和type,则将通过反射来使用byName自动注入

        (2)使用要求

                   1)@Resource位于common-annotation.jar中,因此在使用之前必须要导包

                   2)在配置文件中加入:

[html]  view plain copy
  1. <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>  

        (3)例子     

[java]  view plain copy
  1. public class Boss {  
  2.     @Resource  
  3.     private Car car;  
  4.     @Resource  
  5.     private Office office;  
  6.   
  7.     @Override  
  8.     public String toString() {  
  9.         return "car:" + car + "\n" + "office:" + office;  
  10.     }  
  11. }  

5.spring中隐式注册注解

        使用这些注解时需要在配置文件中导入很多配置,这样会导致配置文件混乱,所以spring提供了一个方法,可以隐式注册这些annotation

[html]  view plain copy
  1. <context:annotation-config/>  
        但是需要导入context命名空间,所以,需要再加入context明明空间。整体配置如下:

[html]  view plain copy
  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.    
  10.     <context:annotation-config/>   
  11.     <bean id="boss" class="com.mycompany.app.Boss">  
  12.     </bean>  
  13.     <bean id="office" class="com.mycompany.app.Office">  
  14.         <property name="officeNo" value="002"/>  
  15.     </bean>  
  16.      <bean id="office2" class="com.mycompany.app.Office">  
  17.         <property name="officeNo" value="004"/>  
  18.     </bean>  
  19.     <bean id="car" class="com.mycompany.app.Car" scope="singleton">  
  20.         <property name="brand" value=" 红旗 CA72"/>  
  21.         <property name="price" value="2000"/>  
  22.     </bean>  
  23. </beans>  
          这个隐式配置实际上注册了4个类:

AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 以及equiredAnnotationBeanPostProcessor 


6.@Component

        (1)引入

                   虽然我们可以通过@Autowired或者@Resource在bean类中使用自动注入功能,但是bean还是在xml文件中通过<bean>进行了定义——也就是说,在xml配置文件中定义bean,通过@Autowired或者@Resource为bean的成员变量、方法、构造方法入参提供自动注入的功能。

                  那么能否也通过注释定义bean,从xml配置中完全移除bean定义的配置呢?答案是肯定的。我们通过@Component注解就可以达到这个目标了。

                  实际上共有四种注解实现了这种功能@Component、@Repository、@Controller、@Service,功能完全相同,只是应用于不同的层次

                        @Component:是一个泛化的概念,仅仅表示是一个bean,可以用在任何层次

                        @Service:通常用在业务层,功能与@Component相同

                        @Controller:通常用在控制层,功能与@Component相同

                        @Repository:通常用在dao层,功能与@Component相同

        (2)配置
                  1)需要指定扫描的包,这样的话spring就可以自动扫描指定包下带@Component(或其他三个)注解的类,并生成bean

[html]  view plain copy
  1. <context:component-scan base-package="com.mycompany.app"/>  

                  2)需要添加命名空间

[html]  view plain copy
  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">  
        (3)实例

[java]  view plain copy
  1. package com.mycompany.app;  
  2.   
  3. import javax.annotation.Resource;  
  4.   
  5. import org.springframework.stereotype.Component;  
  6.   
  7. @Component  
  8. public class Boss {  
  9.     @Resource  
  10.     private Car car;  
  11.     @Resource  
  12.     private Office office;  
  13.   
  14.     @Override  
  15.     public String toString() {  
  16.         return "car:" + car + "\n" + "office:" + office;  
  17.     }  
  18. }  
         car类

[java]  view plain copy
  1. package com.mycompany.app;  
  2.   
  3. import org.springframework.stereotype.Component;  
  4.   
  5. @Component  
  6. public class Car {  
  7.     private String brand = "红旗 CA72";  
  8.     private double price = 2000;  
  9.   
  10.     @Override  
  11.     public String toString() {  
  12.         return "brand:" + brand + "," + "price:" + price;  
  13.     }  
  14.   
  15.     public String getBrand() {  
  16.         return brand;  
  17.     }  
  18.   
  19.     public void setBrand(String brand) {  
  20.         this.brand = brand;  
  21.     }  
  22.   
  23.     public double getPrice() {  
  24.         return price;  
  25.     }  
  26.   
  27.     public void setPrice(double price) {  
  28.         this.price = price;  
  29.     }  
  30. }  
             注意:这里因为不能再在bean中指定car属性的值了,所以直接给成员变量赋值
[java]  view plain copy
  1. package com.mycompany.app;  
  2.   
  3. import org.springframework.stereotype.Component;  
  4.   
  5. @Component  
  6. public class Office {  
  7.     private String officeNo ="001";  
  8.   
  9.   
  10.     public String getOfficeNo() {  
  11.         return officeNo;  
  12.     }  
  13.   
  14.   
  15.     public void setOfficeNo(String officeNo) {  
  16.         this.officeNo = officeNo;  
  17.     }  
  18.   
  19.   
  20.     @Override  
  21.     public String toString() {  
  22.         return "officeNo:" + officeNo;  
  23.     }  
  24. }  

        (4)@Scope
                  @Scope注解可以和@Component注解配合使用,用来指定bean的scope。

                  默认是singleton,也就是整个应用使用同一个实例;如果使用prototype,则spring每次getBean都会拿到新的bean



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值