Spring 注释 @Autowired 和@Resource 的区别

转载:https://blog.csdn.net/mccand1234/article/details/52472970

https://www.cnblogs.com/leiOOlei/p/3713779.html

一、

@Autowired和@Resource都可以用来装配bean,都可以写在字段上,或者方法上。

 

二、

@Autowired属于Spring的;@Resource为JSR-250标准的注释,属于J2EE的。

 

三、

@Autowired默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,例如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:

@Autowired() 
@Qualifier("baseDao")
private BaseDao baseDao;

 

四、

@Resource,默认安装名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

 例如:

@Resource(name="baseDao")
private BaseDao baseDao;

 

五、

推荐使用:@Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与spring的耦合。这样代码看起就比较优雅。

 

遇到的问题

@Autowired
@Qualifier("cipShopOwnerServiceImpl")   bean name
ShopOwnerService cipShopOwnerServiceImpl;
ShopOwnerService 需要是接口 cipShopOwnerServiceImpl bean的名字

ShopOwnerService是接口,两个实现类
@Component("cipShopOwnerServiceImpl")   bean name
public class CIPShopOwnerServiceImpl implements ShopOwnerService {}

@Component("shopOwnerServiceImpl")       bean name
public class ShopOwnerServiceImpl implements ShopOwnerService {}

直接
@Autowired
CipShopOwnerServiceImpl cipShopOwnerServiceImpl;
报错

  @Autowired
//    @Qualifier("cipShopOwnerServiceImpl")
    ShopOwnerService cipShopOwnerServiceImpl;
    可以

 @Autowired
//    @Qualifier("cipShopOwnerServiceImpl")
    ShopOwnerService pShopOwnerServiceImpl;
    报错 确定cipShopOwnerServiceImpl 最好是bean name
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
配置文件的方法

我们编写spring框架的代码时候。一直遵循是这样一个规则:所有在spring中注入的bean都建议定义成私有的域变量。并且要配套写上get和set方法。 
Boss拥有Office和Car类型的两个属性:

public class Boss
{   
    private Car car;   
    private Office office;   
    //省略 get/setter   
    @Override  
    public String toString()
    {   
        return "car:" + car + "/n" + "office:" + office;   
    }   
}   
1
2
3
4
5
6
7
8
9
10
11
我们在Spring容器中将Office和Car声明为Bean,并注入到Boss Bean中,下面是使用传统XML完成这个工作的配置文件beans.xml:

<?xml version="1.0" encoding="UTF-8" ?>   
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">   
    <bean id="boss" class="Boss">   
        <property name="car" ref="car"/>   
        <property name="office" ref="office" />   
    </bean>   
    <bean id="office" class="Office">   
        <property name="officeNo" value="002"/>   
    </bean>   
    <bean id="car" class="Car" scope="singleton">   
        <property name="brand" value="红旗CA72"/>   
        <property name="price" value="2000"/>   
    </bean>   
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
当我们运行以下代码时,控制台将正确打出boss的信息:

import org.springframework.context.ApplicationContext;   
import org.springframework.context.support.ClassPathXmlApplicationContext;   
public class Test
{   

    public static void main(String[] args)
    {   
        String[] locations = {"beans.xml"};   
        ApplicationContext ctx = new ClassPathXmlApplicationContext(locations);   
        Boss boss = (Boss) ctx.getBean("boss");   
        System.out.println(boss);   
    }   

1
2
3
4
5
6
7
8
9
10
11
12
13
@Autowired的使用

Spring 2.5引入了@Autowired注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。通过@Autowired的使用来消除set,get方法。 
下面是@Autowired的定义:

@Retention(RetentionPolicy.RUNTIME)  
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD})
public @interface Autowired
{
//是否必须满足依赖性检查,默认时,凡是应用了@Autowired注解的属性和方法都必须找到合适的协作者,否则Spring容器会抛出异常,
//通过调整required属性取值能够改变这一行为。
boolean required() default true;

1
2
3
4
5
6
7
8
注意:@Autowired注解能够作用于构建器、属性、方法。这里的方法不局限于设值方法,即setter方法,常见的各种方法都可以应用这一注解。 
要使用@Autowired实现我们要精简程序的目的,需要这样来处理: 
在applicationContext.xml中加入:

<!-- 该 BeanPostProcessor 将自动对标注 @Autowired 的 Bean 进行注入 -->   
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
1
2
Spring通过一个BeanPostProcessor对@Autowired进行解析,所以要让@Autowired起作用必须事先在Spring容器中声明AutowiredAnnotationBeanPostProcessor Bean。 
修改在原来注入Spirng容器中的bean的方法,在域变量上加上标签@Autowired,并且去掉相应的get和set方法。 
使用 @Autowired 注释的 Boss.java

import org.springframework.beans.factory.annotation.Autowired;   
public class Boss
{   
    @Autowired  
    private Car car;   
    @Autowired  
    private Office office;   
}  
1
2
3
4
5
6
7
8
在applicatonContext.xml中把原来引用的标签也去掉。

<?xml version="1.0" encoding="UTF-8" ?>   
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">   

    <!-- 该 BeanPostProcessor 将自动起作用,对标注 @Autowired 的 Bean 进行自动注入 -->   
    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>   

    <!-- 移除 boss Bean 的属性注入配置的信息 -->   
    <bean id="boss" class="Boss"/>   

    <bean id="office" class="Office">   
        <property name="officeNo" value="001"/>   
    </bean>   
    <bean id="car" class="Car" scope="singleton">   
        <property name="brand" value="红旗 CA72"/>   
        <property name="price" value="2000"/>   
    </bean>   
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
这样,当 Spring容器启动时,AutowiredAnnotationBeanPostProcessor将扫描Spring容器中所有Bean,当发现Bean中拥有@Autowired 注释时就找到和其匹配(默认按类型匹配)的Bean,并注入到对应的地方中去。

@Autowired注入规则

@Autowired默认是按照byType进行注入的,但是当byType方式找到了多个符合的bean,又是怎么处理的?Autowired默认先按byType,如果发现找到多个bean,则又按照byName方式比对,如果还有多个,则报出异常。 
例子:

@Autowired
private Car redCar;
1
2
spring先找类型为Car的bean
如果存在且唯一,则OK;
如果不唯一,在结果集里,寻找name为redCar的bean。因为bean的name有唯一性,所以,到这里应该能确定是否存在满足要求的bean了 
@Autowired也可以手动指定按照byName方式注入,使用@Qualifier标签,例如: 
@Autowired() 
@Qualifier(“baseDao” ) 
因为bean的name具有唯一性,理论上是byName会快一点,但spring默认使用byType的方式注入。另外补充一点:@Resource(这个注解属于J2EE的)的标签,默认是按照byName方式注入的。
--------------------- 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值