Spring-04 Bean的自动装配

Bean的自动装配

1.自动装配说明

  • 自动装配是使用spring满足bean依赖的一种方法。
  • spring会在应用上下文中为某个bean寻找其依赖的bean。

Spring中bean有三种装配机制,分别是:

  1. 在xml中显式配置;
  2. 在java中显式配置;
  3. 隐式的bean发现机制和自动装配。

这里我们主要讲第三种:自动化的装配bean。

Spring的自动装配需要从两个角度来实现,或者说是两个操作:

  1. 组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean;
  2. 自动装配(autowiring):spring自动满足bean之间的依赖,也就是我们说的IoC/DI;

组件扫描和自动装配组合发挥巨大威力,使得显示的配置降低到最少。

推荐不使用自动装配xml配置 , 而使用注解 。

2.案例

2.1 创建实体类

  1. public class Cat {
  2. public void shout() {
  3. System.out.println("miao~");
  4. }
  5. }
  1. public class Dog {
  2. public void shout() {
  3. System.out.println("wang~");
  4. }
  5. }
  1. public class User {
  2. private Cat cat;
  3. private Dog dog;
  4. private String str;
  5. public Cat getCat() {
  6. return cat;
  7. }
  8. public Dog getDog() {
  9. return dog;
  10. }
  11. public String getStr() {
  12. return str;
  13. }
  14. public void setCat(Cat cat) {
  15. this.cat = cat;
  16. }
  17. public void setDog(Dog dog) {
  18. this.dog = dog;
  19. }
  20. public void setStr(String str) {
  21. this.str = str;
  22. }
  23. }

2.2 创建配置文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5. <bean id="dog" class="pojo.Dog"/>
  6. <bean id="cat" class="pojo.Cat"/>
  7. <bean id="user" class="pojo.User">
  8. <property name="cat" ref="cat"/>
  9. <property name="dog" ref="dog"/>
  10. <property name="str" value="zc"/>
  11. </bean>
  12. </beans>

2.3 测试

  1. @Test
  2. public void Test(){
  3. ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
  4. User user = (User) context.getBean("user");
  5. user.getCat().shout();
  6. user.getDog().shout();
  7. }

3.按名称自动装配

由于在手动配置xml过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低。

采用自动装配将避免这些错误,并且使配置简单化。

修改bean配置:autowire="byName"

  1. <bean id="user" class="pojo.User" autowire="byName">
  2. <property name="str" value="zc"/>
  3. </bean>

再次测试,一切正常。

但是如果将 cat 的bean id修改为 catXXX,就会出现java.lang.NullPointerException

因为按byName规则找不对应set方法,真正的setCat就没执行,对象就没有初始化,所以调用时就会报空指针错误。

当一个bean节点带有 autowire byName的属性时。

  1. 将查找其类中所有的set方法名,例如setCat,获得将set去掉并且首字母小写的字符串,即cat。
  2. 去spring容器中寻找是否有此字符串名称id的对象。
  3. 如果有,就取出注入;如果没有,就报空指针异常。

4.按类型自动装配

使用autowire byType首先需要保证:同一类型的对象,在spring容器中唯一。

修改bean配置:autowire="byType"

  1. <bean id="user" class="pojo.User" autowire="byType">
  2. <property name="str" value="zc"/>
  3. </bean>

再次测试,一切正常。

但是如果添加一个Cat的bean:

  1. <bean id="cat1" class="pojo.Cat"/>

会报错:NoUniqueBeanDefinitionException,所以同一类型的对象,在spring容器中必须唯一。

综上:

  • byName: 需要保证所有的bean的id唯一,并且这个bean需要和自动注入的属性的set的方法的值一致!
  • byType: 需要保证所有的bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!

5.注解实现自动装配

5.1 引入context文件头

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. https://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. https://www.springframework.org/schema/context/spring-context.xsd">
  9. </beans>

5.2 开启属性注解支持!

  1. <context:annotation-config/>

5.3 @Autowired

5.3.1 导入依赖

  1. <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-aop</artifactId>
  5. <version>5.3.3</version>
  6. </dependency>

5.3.2 修改案例

将User类中的set方法去掉,使用@Autowired注解

  1. public class User {
  2. @Autowired
  3. private Cat cat;
  4. @Autowired
  5. private Dog dog;
  6. private String str;
  7. public Cat getCat() {
  8. return cat;
  9. }
  10. public Dog getDog() {
  11. return dog;
  12. }
  13. public String getStr() {
  14. return str;
  15. }
  16. }

5.3.3 修改配置文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. https://www.springframework.org/schema/context/spring-context.xsd
  9. ">
  10. <bean id="dog" class="pojo.Dog"/>
  11. <bean id="cat" class="pojo.Cat"/>
  12. <bean id="user" class="pojo.User"/>
  13. <context:annotation-config/>
  14. </beans>

测试,一样成功。

@Autowired(required=false)

false:对象可以为null;

true:对象必须存对象,不能为null。

5.4 @Qualifier

  • @Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配
  • @Qualifier不能单独使用。

5.4.1 配置文件修改

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. https://www.springframework.org/schema/context/spring-context.xsd
  9. ">
  10. <bean id="dog" class="pojo.Dog"/>
  11. <bean id="dog1" class="pojo.Dog"/>
  12. <bean id="cat" class="pojo.Cat"/>
  13. <bean id="cat1" class="pojo.Cat"/>
  14. <bean id="user" class="pojo.User"/>
  15. <context:annotation-config/>
  16. </beans>

没有加Qualifier测试,直接报错

这时候,在属性上添加Qualifier注解

  1. @Autowired
  2. @Qualifier(value = "cat")
  3. private Cat cat;
  4. @Autowired
  5. @Qualifier(value = "dog")
  6. private Dog dog;
  7. private String str;

测试,成功输出。

5.5 @Resource

  • @Resource如有指定的name属性,先按该属性进行byName方式查找装配;
  • 其次再进行默认的byName方式进行装配;
  • 如果以上都不成功,则按byType的方式自动装配。
  • 都不成功,则报异常。

5.5.1 第一种

实体类

  1. public class User {
  2. @Resource(name = "cat")
  3. private Cat cat;
  4. @Resource
  5. private Dog dog;
  6. private String str;
  7. }

bean.xml

  1. <bean id="dog" class="pojo.Dog"/>
  2. <bean id="cat" class="pojo.Cat"/>
  3. <bean id="cat1" class="pojo.Cat"/>
  4. <bean id="user" class="pojo.User"/>

测试通过

5.5.2 第二种

bean.xml

  1. <bean id="dog" class="com.kuang.pojo.Dog"/>
  2. <bean id="cat" class="com.kuang.pojo.Cat"/>

实体类只保留注解

  1. @Resource
  2. private Cat cat;
  3. @Resource
  4. private Dog dog;

测试通过

5.6 注解总结

@Autowired与@Resource异同:

1、@Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。

2、@Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用

3、@Resource(属于J2EE复返),默认按照名称进行装配,名称可以通过name属性进行指定。如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先byName。

个人博客为:

MoYu's Github Blog

MoYu's Gitee Blog

Spring-04 Bean的自动装配的更多相关文章

  1. Spring基础——在 Spring Config 文件中基于 XML 的 Bean 的自动装配

    一.Spring IOC 容器支持自动装配 Bean,所谓自动装配是指,不需要通过 <property> 或 <constructor-arg> 为 Bean 的属性注入值的过 ...

  2. spring实战二之Bean的自动装配(非注解方式)

    Bean的自动装配 自动装配(autowiring)有助于减少甚至消除配置<property>元素和<constructor-arg>元素,让Spring自动识别如何装配Bea ...

  3. Spring学习--xml 中 Bean 的自动装配

    Spring IOC 容器可以自动装配 Bean. 只要在 <bean> 的 autowire 属性里指定自动装配的模式. byName(根据名称自动装配):必须将目标 Bean 的名称和 ...

  4. Spring(三):bean的自动装配

    Bean的自动装配 自动装配是Spring满足bean依赖的一种方式. Spring会在上下文中自动寻找,并自动给bean装配属性 Spring中三种装配方式 在xml中显式的配置. 在java中显式 ...

  5. Spring学习03(Bean的自动装配)

    6.Bean的自动装配 6.1 自动装配说明 自动装配是使用spring满足bean依赖的一种方法 spring会在应用上下文中为某个bean寻找其依赖的bean. Spring中bean的三种装配机 ...

  6. bean的自动装配,使用注解开发,使用java的方式配置Spring

    bean的自动装配 自动装配是Spring满足bean依赖一种方式! Spring会在上下文中自动寻找,并自动给bean装配属性! 在Spring中有三种装配的方式 在xml中显示的配置 在java中 ...

  7. Spring bean的自动装配属性

    bean的自动装配属性能简化xml文件配置. bean 的自动装配属性分为四种: 1.byName 2.byTyoe 3.constructor 4. autodetect byName: 它查找配置 ...

  8. Bean的自动装配

    再说自动装配之前,我们先聊一聊什么是手动装配. 手动装配就是我们在先前讲的那些,要自己给定属性,然后赋值 Spring IOC容器可以自动装配Bean,需要做的仅仅实在<bean>的aut ...

  9. 8 -- 深入使用Spring -- 7...4 使用自动装配

    8.7.4 使用自动装配 在自动装配策略下,Action还是由Spring插件创建,Spring 插件在创建Action实例时,利用Spring的自动装配策略,将对应的业务逻辑组件注入Action实例 ...

  10. Bean的自动装配及作用域

    1.XML配置里的Bean自动装配 Spring IOC 容器可以自动装配 Bean,需要做的仅仅是在 <bean> 的 autowire 属性里指定自动装配的模式.自动装配方式有: by ...

随机推荐

  1. 2019 Multi-University Training Contest 1 D.Vacation(思维)

    题意:有n俩车行驶在一条道路上,每辆车有车长li,距离终点的距离si,速度vi,不能超出,并且驶过终点后会依旧保持原状态行驶,问最后一辆车过终点的时间. 思路:因为行驶过终点后还是要保持之前的行驶方式 ...

  2. zoj3905 Cake

    Time Limit: 4 Seconds      Memory Limit: 65536 KB Alice and Bob like eating cake very much. One day, ...

  3. AtCoder Beginner Contest 181 E - Transformable Teacher (贪心,二分)

    题意:有一长度为奇数\(n\)的数组\(a\),和长度为\(m\)的数组\(b\),现要求从\(b\)中选择一个数放到\(a\)中,并将\(a\)分成\((n+1)/2\)个数对,求最小的所有数对差的 ...

  4. CF1463-D. Pairs

    CF1463-D. Pairs 题意: 有从\(1\)到\(2n\)一共\(2n\)个数字,让你将这\(2n\)个数字分成\(n\)组,每组有两个数字.对于这\(n\)组数字,你可以从中挑选\(x\) ...

  5. 在QT C++中调用 Python并将软件打包发布(裸机可运行)

    为了提高工作效率,需要一个可以自动生成多份相关联的word文档免去繁琐复制粘贴工作的软件.最后选定使用QT C++做界面和主要逻辑程序设计,对word的操作使用python写好对应的函数,然后在QT中 ...

  6. Error Code: 1055.Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'userinfo.

    环境:mysql-8.0.15-winx64 问题描述: Error querying database. Cause: java.sql.SQLSyntaxErrorException: Expre ...

  7. js code review

    js code review https://codereview.stackexchange.com/ refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只 ...

  8. cheerio & jQuery for server

    cheerio & jQuery for server Fast, flexible & lean implementation of core jQuery designed spe ...

  9. npm clear folder

    npm clear folder rm -rf rimraf rmrf & clear build / dist folder caches https://www.npmjs.com/pac ...

  10. Suspense for Data Fetching

    Suspense for Data Fetching Experimental https://reactjs.org/docs/concurrent-mode-suspense.html React ...