zoukankan      html  css  js  c++  java
  • Spring中@Autowired、@Resource和@Inject注解的使用和区别

    在使用Spring进行项目开发的时候,会大量使用到自动装配,那自动装配是什么呢?简单来说:Spring 利用依赖注入(DI)功能,完成SpringIOC容器中各个组件之间的依赖关系赋值管理。

    下面介绍和总结可以在在Spring使用的三种自动注入的注解。首先回顾一下最初使用xml进行是如何进行注入的。

    零、回顾:XML方式注入

    使用 property 或者 constructor-arg 属性。

    <!-- 配置需要被Spring管理的Bean(创建,创建后放在了Spring IOC容器里面)-->
    <bean id="superMan" class="org.annotation.autowried.SuperMan">
     <property name="car" ref="car"></property>
     <!--<constructor-arg ref="car"/>--> 
    </bean>
    <bean id="car" class="org.annotation.autowried.Car"/>
    public class SuperMan {
     private Car car;
     /* private SuperMan(Car car){
     this.car = car;
     }*/
     public void setCar(Car car) {
     this.car = car;
     }
    }
    public class Car {
     private String brand = "喇嘛杀敌";
    }

    这样就能够将需要的组件注入到Spring中,并且进行组件中的依赖关系管理。回顾结束,通过这种方式来,配置比较繁琐,下面正式进入使用注解注入的主题。

    @Autowired介绍

    在Spring 2.5 引入了 @Autowired 注解!

    @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Autowired {
     boolean required() default true;
    }

    从Autowired注解源码上看,可以使用在下面这些地方:

    @Target(ElementType.CONSTRUCTOR) #构造函数
    @Target(ElementType.METHOD) #方法
    @Target(ElementType.PARAMETER) #方法参数
    @Target(ElementType.FIELD) #字段、枚举的常量
    @Target(ElementType.ANNOTATION_TYPE) #注解

    还有一个value属性,默认是true。

    简单总结:

    1、@Autowired是Spring自带的注解,通过AutowiredAnnotationBeanPostProcessor 类实现的依赖注入

    2、@Autowired可以作用在CONSTRUCTOR、METHOD、PARAMETER、FIELD、ANNOTATION_TYPE

    3、@Autowired默认是根据类型(byType )进行自动装配的

    4、如果有多个类型一样的Bean候选者,需要指定按照名称(byName )进行装配,则需要配合@Qualifier。

    指定名称后,如果Spring IOC容器中没有对应的组件bean抛出NoSuchBeanDefinitionException。也可以将@Autowired中required配置为false,如果配置为false之后,当没有找到相应bean的时候,系统不会抛异常

    简单使用代码:

    在字段属性上。

    @Autowired
    private HelloDao helloDao;

    或者

    private HelloDao helloDao;
    public HelloDao getHelloDao() {
     return helloDao;
    }
    @Autowired
    public void setHelloDao(HelloDao helloDao) {
     this.helloDao = helloDao;
    }

    或者

    private HelloDao helloDao;
    //@Autowired
    public HelloServiceImpl(@Autowired HelloDao helloDao) {
     this.helloDao = helloDao;
    }
    // 构造器注入也可不写@Autowired,也可以注入成功。

    将@Autowired写在被注入的成员变量上,setter或者构造器上,就不用再xml文件中配置了。

    如果有多个类型一样的Bean候选者,则默认根据设定的属性名称进行获取。如 HelloDao 在Spring中有 helloWorldDao 和 helloDao 两个Bean候选者。

    @Autowired
    private HelloDao helloDao;

    首先根据类型获取,发现多个HelloDao,然后根据helloDao进行获取,如果要获取限定的其中一个候选者,结合@Qualifier进行注入。

    @Autowired
    @Qualifier("helloWorldDao")
    private HelloDao helloDao;

    注入名称为helloWorldDao 的Bean组件。@Qualifier("XXX") 中的 XX是 Bean 的名称,所以 @Autowired 和 @Qualifier 结合使用时,自动注入的策略就从 byType 转变成 byName 了。

    多个类型一样的Bean候选者,也可以@Primary进行使用,设置首选的组件,也就是默认优先使用哪一个。

    注意:使用@Qualifier 时候,如何设置的指定名称的Bean不存在,则会抛出异常,如果防止抛出异常,可以使用:

    @Qualifier("xxxxyyyy")
    @Autowired(required = false)
    private HelloDao helloDao;

    在SpringBoot中也可以使用@Bean+@Autowired进行组件注入,将@Autowired加到参数上,其实也可以省略。

    @Bean
    public Person getPerson(@Autowired Car car){
     return new Person();
    }
    // @Autowired 其实也可以省略

    @Resource介绍

    @Target({TYPE, FIELD, METHOD})
    @Retention(RUNTIME)
    public @interface Resource {
     String name() default "";
     // 其他省略
    }

    从Resource注解源码上看,可以使用在下面这些地方:

    @Target(ElementType.TYPE) #接口、类、枚举、注解
    @Target(ElementType.FIELD) #字段、枚举的常量
    @Target(ElementType.METHOD) #方法

    name 指定注入指定名称的组件。

    简单总结:

    1、@Resource是JSR250规范的实现,在javax.annotation包下

    2、@Resource可以作用TYPE、FIELD、METHOD上

    3、@Resource是默认根据属性名称进行自动装配的,如果有多个类型一样的Bean候选者,则可以通过name进行指定进行注入

    简单使用代码:

    @Component
    public class SuperMan {
     @Resource
     private Car car;
    }

    按照属性名称 car 注入容器中的组件。如果容器中BMW还有BYD两种类型组件。指定加入BMW。如下代码:

    @Component
    public class SuperMan {
     @Resource(name = "BMW")
     private Car car;
    }

    name 的作用类似 @Qualifier!

    @Inject介绍

    @Target({ METHOD, CONSTRUCTOR, FIELD })
    @Retention(RUNTIME)
    @Documented
    public @interface Inject {}

    从Inject注解源码上看,可以使用在下面这些地方:

    @Target(ElementType.CONSTRUCTOR) #构造函数
    @Target(ElementType.METHOD) #方法
    @Target(ElementType.FIELD) #字段、枚举的常量

    简单总结:

    1、@Inject是JSR330 (Dependency Injection for Java)中的规范,需要导入javax.inject.Inject jar包 ,才能实现注入

    2、@Inject可以作用CONSTRUCTOR、METHOD、FIELD上

    3、@Inject是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Named;

    简单使用代码:

    @Inject
    private Car car;

    指定加入BMW组件。

    @Inject
    @Named("BMW")
    private Car car;

    @Named 的作用类似 @Qualifier!

    总结

    1、@Autowired是Spring自带的,@Resource是JSR250规范实现的,@Inject是JSR330规范实现的

    2、@Autowired、@Inject用法基本一样,不同的是@Inject没有一个request属性

    3、@Autowired、@Inject是默认按照类型匹配的,@Resource是按照名称匹配的

    4、@Autowired如果需要按照名称匹配需要和@Qualifier一起使用,@Inject和@Name一起使用,@Resource则通过name进行指定

    转自:https://www.toutiao.com/i6725012978053153291/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&timestamp=1568424622&app=news_article&utm_source=weixin&utm_medium=toutiao_android&req_id=2019091409302201002607602300CDF3ED&group_id=6725012978053153291

  • 相关阅读:
    利用 runtime,解决多次点击相同 button,导致重复跳转的问题-b
    dbcp数据库连接池管理
    dbutil组件的常见用法
    事务的概念及常用方法
    jdbc链接基础
    MySQL数据约束和关联查询
    mysql基本操作语句
    jsp常用标签和标签库及javaBean规范
    EL表达式
    会话过程保存数据对象cookie和session
  • 原文地址:https://www.cnblogs.com/diandianquanquan/p/11518365.html
Copyright © 2011-2022 走看看