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 创建实体类

public class Cat {
public void shout() {
System.out.println("miao~");
}
}
public class Dog {
public void shout() {
System.out.println("wang~");
}
}
public class User {
private Cat cat;
private Dog dog;
private String str;
public Cat getCat() {
return cat;
}
public Dog getDog() {
return dog;
}
public String getStr() {
return str;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public void setStr(String str) {
this.str = str;
}
}

2.2 创建配置文件

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

2.3 测试

    @Test
public void Test(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
User user = (User) context.getBean("user");
user.getCat().shout();
user.getDog().shout();
}

3.按名称自动装配

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

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

修改bean配置:autowire="byName"

<bean id="user" class="pojo.User" autowire="byName">
<property name="str" value="zc"/>
</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"

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

再次测试,一切正常。

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

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

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

综上:

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

5.注解实现自动装配

5.1 引入context文件头

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

5.2 开启属性注解支持!

<context:annotation-config/>

5.3 @Autowired

5.3.1 导入依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.3</version>
</dependency>

5.3.2 修改案例

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

public class User {
@Autowired
private Cat cat;
@Autowired
private Dog dog;
private String str;
public Cat getCat() {
return cat;
}
public Dog getDog() {
return dog;
}
public String getStr() {
return str;
}
}

5.3.3 修改配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
"> <bean id="dog" class="pojo.Dog"/>
<bean id="cat" class="pojo.Cat"/>
<bean id="user" class="pojo.User"/> <context:annotation-config/> </beans>

测试,一样成功。

@Autowired(required=false)

false:对象可以为null;

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

5.4 @Qualifier

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

5.4.1 配置文件修改

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
"> <bean id="dog" class="pojo.Dog"/>
<bean id="dog1" class="pojo.Dog"/>
<bean id="cat" class="pojo.Cat"/>
<bean id="cat1" class="pojo.Cat"/>
<bean id="user" class="pojo.User"/>
<context:annotation-config/> </beans>

没有加Qualifier测试,直接报错

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

    @Autowired
@Qualifier(value = "cat")
private Cat cat;
@Autowired
@Qualifier(value = "dog")
private Dog dog; private String str;

测试,成功输出。

5.5 @Resource

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

5.5.1 第一种

实体类

public class User {
@Resource(name = "cat")
private Cat cat;
@Resource
private Dog dog;
private String str;
}

bean.xml

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

测试通过

5.5.2 第二种

bean.xml

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

实体类只保留注解

@Resource
private Cat cat;
@Resource
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. 如何安装Python 3.9.1?

    首先打开浏览器输入网址:https://www.python.org或者通过百度搜索python进入Python官网. 选择Downloads,弹出最新版本下载链接,当前版本为3.9.1,如图所示: ...

  2. 纯js添加类

    1.el.setAttribute('class','abc'); <!DOCTYPE HTML><HTML><HEAD><meta charset=&quo ...

  3. windows10与linux进行ftp遇到550 Failed to change directory及553 Could not creat file

    第一个原因: 没有权限,可以使用带有l参数的ls命令来看文件或者目录的权限 ls -l 解决:给本地用户添加一个可写权限 chmod +w /home/student ##给对应的本地用户添加一个可写 ...

  4. Codeforces Round #533 (Div. 2) C. Ayoub and Lost Array(递推)

    题意: 长为 n,由 l ~ r 中的数组成,其和模 3 为 0 的数组数目. 思路: dp[ i ][ j ] 为长为 i,模 3 为 j 的数组数目. #include <bits/stdc ...

  5. hdu 1045 Fire Net 二分图匹配 && HDU-1281-棋盘游戏

    题意:任意两个个'车'不能出现在同一行或同一列,当然如果他们中间有墙的话那就没有什么事,问最多能放多少个'车' 代码+注释: 1 //二分图最大匹配问题 2 //难点在建图方面,如果这个图里面一道墙也 ...

  6. HDU - 2066 最短路+加一个节点

    一个图上,有M条边,Z个出发点,Y个终止点.求一条最短路,其中起点是Z中的任意一点,终点是Y中任意一点. Input 输入数据有多组,输入直到文件结束. 每组的第一行是三个整数M,Z,Y 接着有M行, ...

  7. AtCoder Beginner Contest 177 E - Coprime (数学)

    题意:给你\(n\)个数,首先判断它们是否全都__两两互质__.然后再判断它们是否全都互质. 题解:判断所有数互质很简单,直接枚举跑个gcd就行,关键是第一个条件我们要怎么去判断,其实我们可以对所有数 ...

  8. 2.PowerShell概述

    PowerShell PowerShell命令窗一般随系统带着,运行->输入:powershell,即可打开命令窗口. 命令 Powershell有诸多命令,兼容cmd命令 语法和命令 在此我推 ...

  9. 大数据开发-Spark Join原理详解

    数据分析中将两个数据集进行 Join 操作是很常见的场景.在 Spark 的物理计划阶段,Spark 的 Join Selection 类会根 据 Join hints 策略.Join 表的大小. J ...

  10. Prometheus监控k8s企业级应用

    Prometheus架构图 常见的镜像 pod 备注 kube-state-metric 用来收集K8S基本状态信息的监控代理 node-exporter 专门用来收集K8S运算节点基础信息,需要部署 ...