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初学者随笔(一)_ 用Python写的第一个游戏“猜数字”

    如标题所写,这篇随笔主要记录下学习Python过程中用Python写的第一个游戏--"猜数字"_跟着"小甲鱼"学Python,链接: https://b23.t ...

  2. Codeforces Round #671 (Div. 2)

    比赛链接:https://codeforces.com/contest/1419 A. Digit Game 题意 给出一个 $n$ 位数,游戏规则如下: 1-indexed Raze标记奇数位 Br ...

  3. Codeforces Round #651 (Div. 2) C. Number Game(数论)

    题目链接:https://codeforces.com/contest/1370/problem/C 题意 给出一个正整数 $n$,Ashishgup 和 FastestFinger 依次选择执行以下 ...

  4. Java_web项目中在Java文件里面通过类装载器对资源文件读取

    承接上一节:在eclipse完成对Java_web项目里面资源文件的读取 我们首先在src目录下创建一个资源文件db.properties 内容如下: url=127.0.0.1 name=root ...

  5. Codeforces Round #305 (Div. 1) B. Mike and Feet

    Mike is the president of country What-The-Fatherland. There are n bears living in this country besid ...

  6. System.Windows.Forms.Help

    在开发过程中,基本都需要实现帮助功能,而一般帮助功能就是打开一个帮助文档,System.Windows.Forms提供了Help类用于打开帮助文档,挺方便的. Help类提供的方法如下:   Name ...

  7. leetcode5 最长回文字符串 动态规划 Manacher法

    dp 注意没有声明S不空,处理一下 o(n^2) class Solution { public: string longestPalindrome(string s) { if (s.empty() ...

  8. MQTT 协议 部分细节

    这里不纪录协议文档中大部分通用内容主要记录一下自己比较困惑的细节处理机制.主要有如下几个点: 连接时的具体细节行为? client 在连接到broker时同时指定自己的keepaliveTime和 w ...

  9. 转载:FreeRTOS 配置文件详细功能解释

    原文链接:http://blog.sina.com.cn/s/blog_98ee3a930102wf8c.html 本章节为大家讲解FreeRTOS的配置文件FreeRTOSConfig.h中每个选项 ...

  10. O&#178; & O₂

    O² & O₂ special symbol O² & O₂ HTML HTML subscript and superscript Tags HTML 下标元素 HTML 上标元素 ...