Spring自动装配相关注解1

Spring的自动装配即:使用DI(Dependency Injection)机制来完成容器中各个组件之间的相互依赖赋值,将原本属于程序中自己创建对象的工作交给了Spring来完成,给项目的开发提供了极大的便捷,下面将结合具体的示例介绍Spring自动装配中经常使用的注解。

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

Autowired注解使用介绍

Autowired注解是用来根据容器中bean的类型完成依赖组件自动装配的工作,通常有如下的几种用法。

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

当容器中只有一个指定类型的Bean,会直接按照类型进行Bean的装配,如下:

a.AutowiredConfig配置类:

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

b.UserService类:

/**
 * Created by wangbin on 2020/3/3.
 */
@Service
public class UserService {
   @Autowired
   private UserDao userDao;
   public void printUserDao() {
      System.out.println(userDao);
   }
}

c.UserDao类:

/**
 * Created by wangbin33 on 2020/3/3.
 */
@Repository
public class UserDao {
}

d.Test测试类:

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

      UserDao userDao = acx.getBean(UserDao.class);
      System.out.println(userDao);

      UserService userService = acx.getBean(UserService.class);
      userService.printUserDao();
   }
}
// 输出结果:
com.wb.spring.autowired.dao.UserDao@6cd8737
com.wb.spring.autowired.dao.UserDao@6cd8737

可以看出,容器中的UserDao为同一个单例的Bean。

(2)示例2

容器中存在着多个类型相同的Bean,则匹配到多个类型相同的Bean之后,然后默认找属性名称相同的Bean,如下:

a.UserDao类:

/**
 * Created by wangbin33 on 2020/3/3.
 */
@Repository
public class UserDao {
   // 用来对bean做标记
   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 + '\'' +
            '}';
   }
}

b.AutowiredConfig配置类:

/**
 * Created by wangbin33 on 2020/3/3.
 */
@Configuration
@ComponentScan({"com.wb.spring.autowired"})
public class AutowiredConfig {
   /**
    * 使用@Bean向容器中注入一个名称为userDao2,类型为UserDao的Bean
    */
   @Bean("userDao2")
   public UserDao userDao() {
      UserDao userDao = new UserDao();
      userDao.setFlag("2");
      return userDao;
   }
}

c.UserService类:

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

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'}

从该示例中可以看出,使用@Autowired注解装配的时候,当容器中存在着多个类型相同的Bean时,会优先使用属性名相同的Bean进行装配,因为UserService中的引入的属性名为userDao,所以会优先装配名称为userDao的Bean。

注意:@Repository,@Service,@Component注解标注的类,如果没有指定名称,在创建Bean的时候,Bean的名称默认为类名小写。

(3)示例3

当容器中有多个类型相同的Bean,而且使用@Autowired注解进行装配,可以配合使用@Qualifier注解来指定装配某一个指定名称的Bean,如下:

a.UserDao类:

同上,此处略。

b.AutowriedConfig配置类:

同上,此处略。

c.UserService类:

/**
 * Created by wangbin33 on 2020/3/3.
 */
@Service
public class UserService {
   /**
    * 使用@Qualifier+@Autowired注解,标注注入名称为userDao,
    * 类型为UserDao的Bean
    */
   @Qualifier("userDao")
   @Autowired
   private UserDao userDao2;
   public void printUserDao() {
      System.out.println(userDao2);
   }
}

d.TestMain测试类:

同上,此处略。

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

可以看出,此时打印的是flag为1的bean,这是因为Qualifier中指定的Bean为flag为1的Bean。

(4)示例4

当容器中没有指定类型的Bean时,在自动装配的时候默认会抛出异常:异常信息大概是NosuchBeanDefinitionException异常。表示没有找到对应的Bean定义。此时,如果需要忽略,可以结合@Autowired注解中的required属性完成,如下:

// 使用required注解标识当没有找到bean时,忽略该Bean的自动装配.
@Autowired(required=false)
@Qualifier("userDao")
private UserDao userDao;
(5)示例5

当容器中存在着多个类型相同的Bean时,如果需要指定优先装配某一个指定的组件,则可以通过@Primary组件来完成,如下:

a.UserDao类:

同上,此处略。

b.AutowiredConfig配置类:

/**
 * Created by wangbin33 on 2020/3/3.
 */
@Configuration
@ComponentScan({"com.wb.spring.autowired"})
public class AutowiredConfig {
   // 使用@Primary指定如果类型容器中有多个类型为UserDao的Bean,
   //  优先装配改Bean
   @Primary
   @Bean("userDao2")
   public UserDao userDao() {
      UserDao userDao = new UserDao();
      userDao.setFlag("2");
      return userDao;
   }
}

c.UserService类:

/**
 * Created by wangbin33 on 2020/3/3.
 */
@Service
public class UserService {
   @Autowired
   private UserDao userDao2;
   public void printUserDao() {
      System.out.println(userDao2);
   }
}

c.测试类:

同上,此处略。

运行结果:

UserDao{flag='2'}

从上述结果中可以看出,被标注了@Primary注解的Bean被优先装配。

2、@Autowired用法总结

@Autowired注解的装配顺序如下:

(1)首先默认按照类型去容器中查找类型相同的bean,然后装配;

 

(2)如果容器中存在着多个类型相同的Bean,则再按照属性的名称去优先装配名称相同的Bean;

 

(3)如果容器中存在着多个类型相同,名称不同的Bean,可以结合@Qualifier注解来指定需要装配哪一个Bean,即:@Autowired + @Qualifier注解可以根据类型加名称指定要装配的Bean;

 

(4)默认情况下,如果容器中找不到类型匹配的Bean,则会抛出NoSuchBeanDefinitionException异常,可以通过指定@Autowired注解中的required属性值为false,在找不到相同类型的bean时忽略Bean的装配;

 

(5)如果容器中存在着多个类型相同的Bean,则可以通过@Primary注解来指定默认优先装配的Bean。但是如果同时使用了@Primary指定了优先装配的Bean,然后还使用了@Qualifier注解指定了指定名称的Bean,则会使用@Qualifier注解指定的名称对应的Bean进行装配,即:@Qualifier的优先级比@Primary的高。

至此,Spring自动装配中的@Autowired,@Qualifier,@Primary注解使用方法介绍完毕!下篇文章将继续介绍Spring自动装配中的其他注解的使用方法,包括@Inject,@Resource,@Profile等。欢迎转发文章!

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

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

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