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