Spring中@Autowire、@Resource和@Inject的使用和区别

@Resource

@Resource并不是Spring中自带的注解,而是JSR-250中的注解,属于Java EE的范畴,它具有三种注入的模式

  • Match by Name(按变量名注入)
  • Match by Type(按类型注入)
  • Match by Qualifier(使用Qualifier显式注入)
    这些注入方式都支持通过setter方法注入或者是通过属性的方式注入。

通过属性注入

首先建立一个名为MyClass的测试类,类代码如下

public class MyClass {
    String s;
    
    public MyClass() {
        
    }
    
    public MyClass(String s) {
        this.s = s;
    }
}

Match by Name

首先声明一个bean,并设置其name

@Configuration
public class ApplicationContextTestResourceNameType {
 
    @Bean(name="namedBean")
    public MyClass namedBean() {
        return new MyClass();
    }
}

接着对另外一个bean中的String属性使用@Resource进行注入

    @Resource(name="namedBean")
    private MyClass defaultBean;

这样defaultBean在进行bean的初始化时就会被注入为一个MyClass的值。

Match by Type

接上面的测试样例,bean的配置相同,将注入的部分改为下面的形式,删去括号中的部分

    @Resource
    private MyClass defaultBean;

经过bean的初始化,会发现defaultBean仍然是有值的,因为当删去括号中的name属性后,Spring框架在初始化的过程中发现无法使用Match by Name,就会转而使用Match by Type,在bean容器中寻找类型为MyClass的bean来进行注入。

Match by Qualifier

为了测试显示注入,我们首先将上面的配置类改为如下形式,在bean容器中添加两个同样类型的bean

@Configuration
public class ApplicationContextTestResourceNameType {
 
    @Bean(name="firstNamedBean")
    public MyClass namedBean() {
        return new MyClass("firstNamedBean");
    }
    
    @Bean(name="SecondNamedBean")
    public MyClass namedBean() {
        return new MyClass("SecondNamedBean");
    }
}

接着对另一个bean的属性进行显示注入

    @Resource
    @Qualifier("firstNamedBean")
    private MyClass firstNamedBean;
    
    @Resource
    @Qualifier("SecondNamedBean")
    private MyClass SecondNamedBean;

当我们对这两个属性进行访问的时候就会发现firstNamedBean中的s属性值为"firstNamedBean",而SecondNamedBean中的s属性的值为"SecondNamedBean"。而如果我们不使用@Qualifier注解,则在Spring初始化的时候会报出org.springframework.beans.factory.NoUniqueBeanDefinitionException的异常,因为在Spring容器中有两个类型为MyClass的bean,无法使用Match by Type自动注入。

通过setter方法注入

通过setter方法注入的形式和通过属性注入是相同的,只是注入的位置不一样。

扫描二维码关注公众号,回复: 4137117 查看本文章
    @Resource(name="namedBean")
    public void setMyClass(MyClass myClass) {
        this.myClass = myClass;
    }
    @Resource
    public void setMyClass(MyClass myClass) {
        this.myClass = myClass;
    }
    @Resource
    @Qualifier(name="namedBean")
    public void setMyClass(MyClass myClass) {
        this.myClass = myClass;
    }

@Inject

@Inject同样不是Spring自带的注解,它是属于JSP-330的,同样有三种注入方式

  • Match by Name
  • Match by Type
  • Match by Qualifier
    同样,也可以使用属性注入或者是setter方法注入
    想要使用@Inject注解,需要在maven中引入相关依赖
<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>

对于@Inject注解,在Match by Type和Match by Qualifier的使用上和@Resource是完全一致的,只需要把@Resource注解替换为@Inject即可,下面主要说明以下Match by Name的情况

Match by Name

首先在配置类中定义相应的bean

@Configuration
public class ApplicationContextTestResourceNameType {
 
    @Bean(name="namedBean")
    public MyClass namedBean() {
        return new MyClass();
    }
}

接着对属性进行注入

    @Inject
    @Named("namedBean")
    private MyClass MyClass;

可以看到这里和@Resource有很大的区别,@Inject这个注解自身是不带有name属性的,需要另外使用一个@Named注解来告诉Spring框架使用什么名字对属性进行注入。

@Autowired

@Autowired注解和@Inject的表现很相似,只是@Autowired是由Spring框架自身提供的,同样是支持以下三种注入方式

  • Match by Type
  • Match by Qualifier
  • Match by Name
    注入的方式也是支持属性注入和setter方法注入两种形式。

用属性方式注入

Match by Type

首先在配置类中声明一个用于注入的bean

@Configuration
public class ApplicationContextTestAutowiredQualifier {
 
    @Bean
    public MyClass autowiredMyClass() {
        return new MyClass();
    }
}

接着使用这个bean对另一个bean的属性进行注入

    @Autowired
    private MyClass MyClazz;

Spring容器在初始化的过程中遇到@Autowired就会从容器中寻找相应类型的bean来对属性进行注入,前提是容器中只有一个类型为MyClass的bean,否则在不进行任何其他指定的情况下会抛出NoUniqueBeanDefinitionException。

Match by Qualifier

@Autowired中使用@Qualifier的方式与其他两种注解相同

@Autowired
@Qualifier("autowiredFieldDependency")
private FieldDependency fieldDependency1;

Match by Name

首先声明一个bean,并为其指定它在bean容器中的名字

@Component(value="autowiredMyClass")
public class MyClass {
 
}

接着使用这个类型为MyClass的bean对另一个bean的属性进行注入

    @Autowired
    private MyClass autowiredMyClass;

这里是@Autowired与另外两种注入方式不同的地方,其他两种方式通过变量名进行注入的时候无论是声明bean的地方还是注入属性的地方都需要显示写出bean的name以此来进行匹配,但是对于@Autowired来说,只需要在声明bean的地方写上bean的名字即可,在进行注入的时候容器会自动将要注入的属性的变量名与容器中bean的名字进行匹配。

使用setter方式注入

使用setter方式注入与使用属性方式注入大体相同,只是注入的位置是在setter方法上,可以参见上文@Resource的注入形式

猜你喜欢

转载自blog.csdn.net/turbo_zone/article/details/84204815