Spring之路(11)--在xml配置中显示装配、自动装配bean

简介: 本文目录1. 何为装配1.1 显示装配实例1.2 通过类型自动装配bean1.3 如果类型不能唯一确定bean,会装配失败1.4 通过名称自动装配bean1.5 如果名称不能唯一确定bean,会装配失败2. 总结

1. 何为装配

向bean中注入依赖项的过程即为装配,Spring中的装配大体有两种类型,一种就是显示的指定依赖项,另一种是通过一些规则自动的注入依赖项。


具体的讲,显示指定依赖项是直接指定依赖项的名称,非常明显和确定,所以称之为显示装配。而根据规则自动注入依赖项,是指由Spring容器自动的将符合指定类型或指定名称的依赖项注入到bean的属性中,这种装配称为自动装配。


显而易见的是,由于自动装配无须显示指定依赖项,所以更加的简单快速,目前应用的也是越来越多。


由于装配非常的重要,涵盖的内容也是Spring的核心技巧,所以本篇我们先介绍下如何在xml配置中进行显示、自动装配。


1.1 显示装配实例

显示装配就是显示出来,让大家看到,明明白白的指定要装配的依赖项,此处举个实例。既然大过年的,我们就搞个晚会,过年要开开心心的,我们把唱歌跳舞的都请过来。


package org.maoge.xmlassemble;

//歌手类

public class Singer {

private String name;

public String getName() {

 return name;

}

public void setName(String name) {

 this.name = name;

}

}


package org.maoge.xmlassemble;

//舞者类

public class Dancer {

private String name;

public String getName() {

 return name;

}

public void setName(String name) {

 this.name = name;

}

}


歌手唱歌、舞者跳舞都得需要一个舞台啊,我们来一个舞台类,这个舞台可以容纳歌手和舞者表演。


package org.maoge.xmlassemble;

//舞台类

public class Stage {

//歌手

private Singer singer;

//舞者

private Dancer dancer;

public Singer getSinger() {

 return singer;

}

public void setSinger(Singer singer) {

 this.singer = singer;

}

public Dancer getDancer() {

 return dancer;

}

public void setDancer(Dancer dancer) {

 this.dancer = dancer;

}

}


然后我们通过xml配置文件,显示指定要装配的bean对象,歌手的话我们请刀郎吧,那个歌真是唱出了西北的苍凉,特别喜欢他的《冲动的惩罚》和《喀什噶尔胡杨》,带劲!

OK,看下面的配置中,注意当为state对象的属性singer和dancer注入依赖项时,使用ref显示的指定了bean的id,所以这是非常明确的装配,所以叫显示装配。


<?xml version="1.0" encoding="UTF-8"?><!-- spring.xml文件 -->

<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="daolang" class="org.maoge.xmlassemble.Singer">

 <!-- 直接将"刀郎"注入到name属性 -->

 <property name="name" value="刀郎"></property>

</bean>

<!-- 请来了舞者刘迦 -->

<bean id="liujia" class="org.maoge.xmlassemble.Dancer">

 <!-- 直接将"刘迦"注入到name属性 -->

 <property name="name" value="刘迦"></property>

</bean>

<!-- 安排了一个舞台 -->

<bean id="stage" class="org.maoge.xmlassemble.Stage">

 <!-- 显示指定id=daolang的bean装配到singer属性 -->

 <property name="singer" ref="daolang" />

 <!-- 显示指定id=liujia的bean装配到dancer属性 -->

 <property name="dancer" ref="liujia" />

</bean>

</beans>


此处注意,int、boolean、String等可以直接使用<property value="xxx">注入,而对于其他bean的引用,需要使用<property ref="xxx">指定。<property name="xxx">中的name表示bean中被注入的属性名称。


OK,接下来,可以测试啦:


package org.maoge.xmlassemble;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

public static void main(String[] args) {

 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(

   "/org/maoge/xmlassemble/spring.xml");

 Stage stage=(Stage)context.getBean("stage");

 System.out.println(stage.getSinger().getName());

 System.out.println(stage.getDancer().getName());

}

}


控制台输出如下,可见state中的singer和dancer属性已经被注入相应的bean。


刀郎

刘迦


1.2 通过类型自动装配bean

在上面的实例中,State舞台类中有一个歌手类属性还有一个舞者类属性,而xml中定义的bean也是有一个歌手类对象和一个舞者类对象,此时只要告诉Spring容器,对state对象进行按类型自动装配,Spring容器就知道将bean注入相应类型的属性中了。


所以我们将xml修改如下:


<?xml version="1.0" encoding="UTF-8"?><!-- spring.xml文件 -->

<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="daolang" class="org.maoge.xmlassemble.Singer">

   <property name="name" value="刀郎"></property>

  </bean>

  <!-- 请来了舞者刘迦 -->

  <bean id="liujia" class="org.maoge.xmlassemble.Dancer">

   <property name="name" value="刘迦"></property>

  </bean>

  <!-- 安排了一个舞台 -->

  <bean id="stage" class="org.maoge.xmlassemble.Stage" autowire="byType"><!-- byType表示按类型自动装配 -->

  </bean>

</beans>


再次运行Main.java,依然正常输出,说明按类型自动装配成功。


1.3 如果类型不能唯一确定bean,会装配失败

既然我们通过autowire="byType"告诉容器按类型去装配,那么我们就得保证每个类型只有一个bean存在,否则容器就容器懵圈,根本不知道该用哪个bean注入啊。


如下,我们请来两个歌手,刀郎和他的好朋友谭咏麟,就出麻烦了


<?xml version="1.0" encoding="UTF-8"?><!-- spring.xml文件 -->

<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="daolang" class="org.maoge.xmlassemble.Singer">

 <property name="name" value="刀郎"></property>

</bean>

<!-- 请来了歌手谭咏麟 -->

<bean id="tanyonglin" class="org.maoge.xmlassemble.Singer">

 <property name="name" value="谭咏麟"></property>

</bean>

<!-- 请来了舞者刘迦 -->

<bean id="liujia" class="org.maoge.xmlassemble.Dancer">

 <property name="name" value="刘迦"></property>

</bean>

<!-- 安排了一个舞台 -->

<bean id="stage" class="org.maoge.xmlassemble.Stage"

 autowire="byType"><!-- byType表示按类型自动装配 -->

</bean>

</beans>


我们运行Main,发现控制台报错信息中有:


No qualifying bean of type 'org.maoge.xmlassemble.Singer' available:

expected single matching bean but found 2: daolang,tanyonglin

1

2

可以看出,期待一个,结果有两个类型符合的依赖项,所以无法知道合格(qualifying)的bean,导致全盘失败。


当然啦,自动方便时方便了,但是只有在符合有规则时,才能自动执行!


1.4 通过名称自动装配bean

那这种情况下,只能显示指定bean了吗,比如我们如果在舞台上同时请两个歌手,就不能利用一些规则自动的让bean装配到属性中么。


其实还有一个办法,就是通过名称自动装配,也就是说通过让bean的名称与被装配bean的属性名称相同这个规则,来装配那个符合的bean。


如下我们改造下舞台类:


package org.maoge.xmlassemble;

//舞台类

public class Stage {

// 歌手,属性名为daolagn

private Singer daolang;

// 舞者,属性名为liujia

private Dancer liujia;

public Singer getDaolang() {

 return daolang;

}

public void setDaolang(Singer daolang) {

 this.daolang = daolang;

}

public Dancer getLiujia() {

 return liujia;

}

public void setLiujia(Dancer liujia) {

 this.liujia = liujia;

}

}


然后同样是下面的xml,有两个歌手一个舞者,但是注意我们将自动装配方式改为按名称byName。


<?xml version="1.0" encoding="UTF-8"?><!-- spring.xml文件 -->

<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="daolang" class="org.maoge.xmlassemble.Singer">

 <property name="name" value="刀郎"></property>

</bean>

<!-- 请来了歌手谭咏麟 -->

<bean id="tanyonglin" class="org.maoge.xmlassemble.Singer">

 <property name="name" value="谭咏麟"></property>

</bean>

<!-- 请来了舞者刘迦 -->

<bean id="liujia" class="org.maoge.xmlassemble.Dancer">

 <property name="name" value="刘迦"></property>

</bean>

<!-- 安排了一个舞台 -->

<bean id="stage" class="org.maoge.xmlassemble.Stage"

 autowire="byName"><!-- byName表示按名称自动装配 -->

</bean>

</beans>


此时,由于State类中的daolang属性、liujia属性,与已存在的<bean id="daolang"> <bean id="liujia">名称匹配,所以自动装配成功。


运行Man类如下:


package org.maoge.xmlassemble;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

public static void main(String[] args) {

 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(

   "/org/maoge/xmlassemble/spring.xml");

 Stage stage = (Stage) context.getBean("stage");

 System.out.println(stage.getDaolang().getName());

 System.out.println(stage.getLiujia().getName());

}

}


正常输出:


刀郎

刘迦


1.5 如果名称不能唯一确定bean,会装配失败

同样,如果我们在使用名称自动装配时,找不到确定的bean,也会失败,例如我们将xml中daolang去掉。


<?xml version="1.0" encoding="UTF-8"?><!-- spring.xml文件 -->

<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="tanyonglin" class="org.maoge.xmlassemble.Singer">

 <property name="name" value="谭咏麟"></property>

</bean>

<!-- 请来了舞者刘迦 -->

<bean id="liujia" class="org.maoge.xmlassemble.Dancer">

 <property name="name" value="刘迦"></property>

</bean>

<!-- 安排了一个舞台 -->

<bean id="stage" class="org.maoge.xmlassemble.Stage"

 autowire="byName"><!-- byName表示按名称自动装配 -->

</bean>

</beans>


则控制台报错:


Exception in thread "main" java.lang.NullPointerException

at org.maoge.xmlassemble.Main.main(Main.java:8)


这是因为没有名称是daolang的bean,导致state中的daolang属性装配失败,此时daolang属性值为null,所以调用null对象的方法报NullPointerException异常。


2. 总结

大多数情况下,自动装配其实就够用了,但是偶尔也得显示装配,所以都得掌握啊兄弟们。

相关文章
|
12月前
|
Java 关系型数据库 MySQL
Spring Boot自动配置:魔法背后的秘密
Spring Boot 自动配置揭秘:只需简单配置即可启动项目,背后依赖“约定大于配置”与条件化装配。核心在于 `@EnableAutoConfiguration` 注解与 `@Conditional` 系列条件判断,通过 `spring.factories` 或 `AutoConfiguration.imports` 加载配置类,实现按需自动装配 Bean。
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
3056 0
|
11月前
|
前端开发 Java 应用服务中间件
《深入理解Spring》 Spring Boot——约定优于配置的革命者
Spring Boot基于“约定优于配置”理念,通过自动配置、起步依赖、嵌入式容器和Actuator四大特性,简化Spring应用的开发与部署,提升效率,降低门槛,成为现代Java开发的事实标准。
|
12月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
1928 5
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
931 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
618 6
|
XML 前端开发 Java
Spring xml配置
Spring xml配置
|
XML Java 数据格式
Spring高手之路18——从XML配置角度理解Spring AOP
本文是全面解析面向切面编程的实践指南。通过深入讲解切面、连接点、通知等关键概念,以及通过XML配置实现Spring AOP的步骤。
532 6
Spring高手之路18——从XML配置角度理解Spring AOP
|
XML Java 数据格式
手动开发-简单的Spring基于XML配置的程序--源码解析
手动开发-简单的Spring基于XML配置的程序--源码解析
415 0
|
XML Java 数据格式
Spring IOC—基于XML配置和管理Bean 万字详解(通俗易懂)
Spring 第二节 IOC—基于XML配置和管理Bean 万字详解!。
1454 5