Spring自动装配相关注解2

上篇文章介绍了Spring提供的自动装配时常用的注解@Autowired,@Qualifier,@Primary,但是在Java的JSR中也对自动装配做了支持,本篇文章将介绍Java的JSR中提供的用于Spring完成Bean自动装配的常用注解。

温馨提示:本博客已经发布小程序,可在微信小程序中搜索”百变码农”,手机上也能看!

@Resource和@Inject注解使用介绍

@Resource注解是Java的JSR250中提供的一个默认按照组件名称进行Bean装配的注解,通常用如下的几种用法。

1、@Resource使用示例
(1)示例1

如果不指定要装配的Bean的名称,默认按照Bean的名称去进行Bean的装配。

a.AuwiredConfig配置类:

/**
 * Created by wangbin33 on 2020/3/3.
 */
@Configuration
@ComponentScan({"com.wb.spring.autowired"})
public class AutowiredConfig {

   @Primary
   @Bean("userDao2")
   public UserDao userDao() {
      UserDao userDao = new UserDao();
      userDao.setFlag("2");
      return userDao;
   }
}

b.UserService类:

/**
 * Created by wangbin33 on 2020/3/3.
 */
@Service
public class UserService {
   // 使用@Resource进行Bean的装配
   @Resource
   private UserDao userDao;
   public void printUserDao() {
      System.out.println(userDao);
   }
}

c.UserDao类:

/**
 * Created by wangbin33 on 2020/3/3.
 */
@Repository
public class UserDao {
   private String flag = "1";
   public String getFlag() {
      return flag;
   }
   public void setFlag(String flag) {
      this.flag = flag;
   }
   @Override
   public String toString() {
      return "UserDao{" +
            "flag='" + flag + '\'' +
            '}';
   }
}

d.TestMain测试类:

/**
 * Created by wangbin33 on 2020/3/3.
 */
public class TestMain {
   public static void main(String[] args) {
      ApplicationContext acx = 
     new AnnotationConfigApplicationContext(AutowiredConfig.class);

      UserService userService = acx.getBean(UserService.class);
      userService.printUserDao();
   }
}
// 输出结果:
UserDao{flag='1'}

可以看出,就算是使用了@Primary标注了优先使用的Bean,也不会被自动装配,因为@Resource不支持使用@Primary标注优先注入Bean的功能。还是优先按照bean的名称进行装配。

(2)示例2

如果使用@Resource,还需要指定装配某一个特定的Bean,则可以结合@Resource的属性name来指定需要装配的Bean,如下:

a.AutowiredConfig配置类:

同上,此处略。

b.UserService类:

/**
 * Created by wangbin33 on 2020/3/3.
 */
@Service
public class UserService {
   // 使用@Resource并使用name指定需要装配name为userDao2的Bean
   @Resource(name = "userDao2")
   private UserDao userDao;
   public void printUserDao() {
      System.out.println(userDao);
   }
}

c.UserDao类:

同上,此处略。

d.测试类TestMain:

同上,此处略。

输出结果:

UserDao{flag='2'}

可以看出,输出的结果表示userDao2被装配了,因为Resource注解中的name指定的为名称为userDao2的Bean。

(3)示例3

如果使用了@Resource进行Bean的自动装配,而且指定了装配某一个名称的Bean,当这个名称的Bean在Spring容器中不存在的时候,将会抛出异常,如下:

修改UserService类,其他类不变:

/**
 * Created by wangbin33 on 2020/3/3.
 */
@Service
public class UserService {
   @Resource(name = "userDao111222")
   private UserDao userDao;
   public void printUserDao() {
      System.out.println(userDao);
   }
}

运行结果:

Exception in thread “main” org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘userService’: Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ‘userDao111222’ available

提示没有名称为userDao111222的Bean。

2、@Inject使用示例

@Inject默认也是按照bean的名称完成Bean的自动装配。

注意:在使用@Inject之前,首先需要导入@Inject的依赖包,maven依赖如下:

<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>
(1)示例1

使用@Inject自动装配UserDao,代码如下:

a.AutowiredConfig配置类:

同上,此处略。

b.UserService类:

/**
 * Created by wangbin33 on 2020/3/3.
 */
@Service
public class UserService {
   // 使用@Inject进行Bean的自动装配.
   @Inject
   private UserDao userDao;
   public void printUserDao() {
      System.out.println(userDao);
   }
}

c.UserDao类:

同上,此处略。

d.测试类TestMain:

同上,此处略。

// 运行结果:
UserDao{flag='2'}

可以看到,@Inject注解可以结合@Primary注解一块使用。优先装配@Primary标注的Bean。

(2)示例2

删除掉AutowiredConfig类中的@Primary,则输出的结果为:UserDao{flag=’1′},因为@Inject默认也是按照名称进行装配的,如果没有指定优先装配的Bean,则会装配属性名对应的Bean。

3、用法总结

(1)@Resource和@Inject属于Java的JSR规范中的注解,默认都是按照名称进行装配;

 

(2)使用@Inject之前,需要先导入@Inject的依赖包;

 

(3)@Resource不支持@Primary注解的功能;

 

(4)@Inject类似@Autowired,支持@Primary的功能,但是不支持required属性;

4、和@Autowired注解的对比

(1)@Resource和@Inject是Java中JSR提供的规范,在脱离了Spring框架之后,如果其他框架对该注解提供了支持,也可以使用;

 

(2)@Resource默认和@Inject默认都是按照名称进行装配的,而@Autowired默认按照类型进行装配的,如果需要指定名称,则需要结合@Qualifier注解;

 

(3)@Resource默认按照类型进行装配时,如果需要指定装配特定的bean,则可以使用name属性进行指定,但是@Inject注解不可以指定装配某一个名称的Bean;

 

(4)@Resource不支持@Primary的功能,如果容器中存在着多个类型相同的Bean,使用@Primary标注优先注入某一个Bean也不会生效,而@Autowired和@Inject支持@Primary注解的功能,可以优先注入某一个特定的Bean;

 

(5)@Inject可以结合@Primary完成Bean的优先装配,但是需要注入的Bean必须存在,如果不存在,则会抛出NoSuchBeanDefinitionException异常。不支持像@Autowired中使用required属性忽略Bean装配的功能;

 

(6)如果需要使用@Inject注解,则需要导入@Inject的依赖jar包。

至此,Spring中自动装配Bean的另外几个常用注解介绍完毕。这几个注解在用法上有很多不同点,在使用中应该根据需要合理选择,例如可以根据项目中是否支持Spring来灵活选用装配方式!欢迎转发!

温馨提示:如果小程序端代码显示混乱,是因为移动端兼容性导致,可移步至PC端站点查看!

文章属于原创,如果转发请标注文章来源:个人小站【www.jinnianshizhunian.vip

另外提供一些优秀的Java架构师及IT开发视频,书籍资料。无需注册,无需登录即可下载,免费下载地址:https://www.592xuexi.com