继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

@Autowired 与@Resource之争

HUX布斯
关注TA
已关注
手记 301
粉丝 84
获赞 378

1、@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。

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

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

3、@Resource 是JDK1.6支持的注解默认按照名称进行装配
名称可以通过name属性进行指定,
如果没有指定name属性

  • 当注解写在字段上时,默认取字段名,按照名称查找

  • 如果注解写在setter方法上默认取属性名进行装配

  • 当找不到与名称匹配的bean时才按照类型进行装配

但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。


5bd467f90001df7905710540.jpg


只不过注解处理器我们使用的是Spring提供的,是一样的,无所谓解耦不解耦的说法,两个在便利程度上是等同的。

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

byName 通过参数名 自动装配,如果一个bean的name 和另外一个bean的 property 相同,就自动装配。
byType 通过参数的数据类型自动自动装配,如果一个bean的数据类型和另外一个bean的property属性的数据类型兼容,就自动装配


我们可以通过 @Autowired / @Resource 在 Bean 类中使用自动注入功能,但是 Bean 还是在 XML 文件中通过 <bean> 进行定义 —— 也就是说,在 XML 配置文件中定义 Bean,通过@Autowired 或 @Resource 为 Bean 的成员变量、方法入参或构造函数入参提供自动注入的功能。
比如下面的beans.xml

public class Boss {    private Car car;    private Office office;    
   @Override
    public String toString() {        return "car:" + car + "\n" + "office:" + office;
    }
}
<?xml version="1.0" encoding="UTF-8" ?><beans xmlns="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">

    <context:annotation-config/> 

    <bean id="boss" class="com.sss.Boss"/>
    <bean id="office" class="com.sss.Office">
        <property name="officeNo" value="001"/>
    </bean>
    <bean id="car" class="com.sss.Car" scope="singleton">
        <property name="brand" value=" 红旗 CA72"/>
        <property name="price" value="2000"/>
    </bean></beans>

定义了三个bean对象,但是没有了我们书序的ref指向的内容
比如

<?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="com.sss.Boss">
        <property name="car" ref="car"/>
        <property name="office" ref="office" />
    </bean>
    <bean id="office" class="com.sss.Office">
        <property name="officeNo" value="002"/>
    </bean>
    <bean id="car" class="com.sss.Car" scope="singleton">
        <property name="brand" value=" 红旗 CA72"/>
        <property name="price" value="2000"/>
    </bean></beans>

spring2.5提供了基于注解(Annotation-based)的配置,我们可以通过注解的方式来完成注入依赖。在Java代码中可以使用 @Resource或者@Autowired注解方式来经行注入。虽然@Resource和@Autowired都可以来完成注入依赖,但它们之间是有区 别的。首先来看一下:

a.@Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入;
b.@Autowired默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualifier一起使用;
c.@Resource注解是由JDK提供,而@Autowired是由Spring提供@Resource的方式;
d. @Resource和@Autowired都可以书写标注在字段或者该字段的setter方法之上

2、使用注解的方式,我们需要修改spring配置文件的头信息

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

----------------------PS开始-------------------------------

在基于注解方式配置Spring的配置文件中,你可能会见到

<context:annotation-config/>

这样一条配置,他的作用是式地向 Spring 容器注册

AutowiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
PersistenceAnnotationBeanPostProcessor
RequiredAnnotationBeanPostProcessor

这 4 个BeanPostProcessor。

注册这4个BeanPostProcessor的作用,就是为了你的系统能够识别相应的注解。

例如:

如果你想使用@Autowired注解,那么就必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。传统声明方式如下

<bean class="org.springframework.beans.factory.annotation. AutowiredAnnotationBeanPostProcessor "/>

如果想使用@ Resource 、@ PostConstruct、@ PreDestroy等注解就必须声明CommonAnnotationBeanPostProcessor

<bean class="org.springframework.beans.factory.annotation. CommonAnnotationBeanPostProcessor"/>

如果想使用@PersistenceContext注解,就必须声明PersistenceAnnotationBeanPostProcessor的Bean。

<bean class="org.springframework.beans.factory.annotation.PersistenceAnnotationBeanPostProcessor"/>

如果想使用 @Required的注解,就必须声明RequiredAnnotationBeanPostProcessor的Bean。

同样,传统的声明方式如下:

<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>

一般来说,这些注解我们还是比较常用,尤其是Antowired,在自动注入的时候更是经常使用,所以如果总是需要按照传统的方式一条一条配置显得有些繁琐和没有必要,于是spring给我们提供<context:annotation-config/>的简化配置方式,自动帮你完成声明。

不过,呵呵,我们使用注解一般都会配置扫描包路径选项

<context:component-scan base-package=”XX.XX”/>

该配置项其实也包含了自动注入上述processor的功能,因此当使用 <context:component-scan/> 后,就可以将 <context:annotation-config/> 移除

比如:

<context:component-scan base-package="carPoolingController, carPoolingService, carPoolingDao" />

就把controller包下 service包下 dao包下的注解全部扫描了

----------------------------------------------PS结束------------------------------

3、修改以上配置文件的头信息后,我们就可以在Java代码通过注解方式来注入bean,看下面代码

(1)@Resource

public class StudentService3 implements IStudentService {    //@Resource(name="studentDao")放在此处也是可行的
    private IStudentDao studentDao;    private String id;    public void setId(String id) {    this.id = id;
    }

@Resource(name="studentDao") // 通过此注解完成从spring配置文件中查找名称为studentDao的bean来装配字段studentDao,如果spring配置文件中不存在 studentDao名称的bean则转向按照bean类型进行查找

public void setStudentDao(IStudentDao studentDao) {        this.studentDao = studentDao;
}public void saveStudent() {
        studentDao.saveStudent();
        System.out.print(",ID 为:"+id);
}

配置文件添加如下信息

<bean id="studentDao" class="com.sss.dao.impl.StudentDao"></bean><bean id="studentService3" class="com.sss.service.impl.StudentService3"></bean>

(2)@Autowired

public class StudentService3 implements IStudentService {  //@Autowired放在此处也是可行的
  private IStudentDao studentDao;  private String id;  public void setId(String id) {       this.id = id;
   }

@Autowired

//通过此注解完成从spring配置文件中 查找满足studentDao类型的bean
//@Qualifier("studentDao")则按照名称经行来查找转配的

 public void setStudentDao(IStudentDao studentDao) {       this.studentDao = studentDao;
  }  public void saveStudent() {
       studentDao.saveStudent();
       System.out.print(",ID 为:"+id);
  }
}

配置文件添加如下信息

<bean id="studentDao" class="com.wch.dao.impl.StudentDao"></bean><bean id="studentService3" class="com.wch.service.impl.StudentService3" />

当我们在xml里面为类配置注入对象时,会发现xml文件会越来越臃肿,维护起来很麻烦。这时候我们可以使用注解这种机制来为类配置注入对象。

原生java为我们提供了 javax.annotation.Resource这个注解。

spring框架提供了org.springframework.beans.factory.annotation.Autowired。

一般情况下我们使用 javax.annotation.Resource这个注解,因为这样我们就能实现和spring框架的解藕(难以认同,因为注解处理器还是Spring提供的)。

@Resource可以作用于字段和函数上。当作用于字段上的时候,如果我们只是简单的这样写

@ResourcePersonDao  p;

这时候spring注入p的过程是
1:查找xml中是否有id为p的元素
2:如果没有找到,则看是否有name属性(@Resource name=“”),有则查找name
3:否则查找PersonDao类型的元素

@Resource可作用于set函数上。
例如:

@Resourcepublic void setP(PersonDao p) {  this.p = p;
}

@Autowired注解是根据类型进行查找,比如PersonDao p,他会去xml文件里查找类型为PersonDao的元素



作者:芥末无疆sss
链接:https://www.jianshu.com/p/405680195250
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP