Spring(二)装配Bean(注入)

来源:互联网 发布:dns域名解析软件 编辑:程序博客网 时间:2024/06/01 23:10

什么是装配Bean?

所谓装配Bean就是指创建应用对象之间协作关系的行为,这是依赖注入的本质!Spring容器使用依赖注入管理构成应用的组件,它会创建相互协作的组件之间的关系!

Spring自带了两种不同的容器:

1、BeanFactory,org.Springframework.beans.factory.BeanFactory接口定义,他是最简单的容器,提供基本的DI支持
2、应用上下文,由org.springframework.context.ApplicationContext接口定义,基于BeanFactory之上构建,并提供面向应用的服务,例如从属性文件解析文本信息的能力,以及发布应用事件给感兴趣的事件监听者的能力。

大部分情况下我们使用第二种容器:ApplicationContext。

Spring自带了几种类型的应用上下文。下面3钟是比较常用的:
1、ClassPathXmlApplicationContext:加载位于应用系统classpath下的一个或多个XML文件。
2、FileSystemXmlApplicationContext:读取文件系统下的XML配置文件并加载上下文定义。
3、XmlWebApplicationContext:读取Wweb应用下的XML配置文件并装载上下文。
1、创建相应的Bean
创建一个相应的java类,生成get和set方法,设置toString即可。
2、在bean包里建一个xml文件,文件名没有要求,这个xml文件就是Bean的配置文件
所有的Bean配置全在写在Beans根元素下面

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:context="http://www.springframework.org/schema/context"    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-3.0.xsd        http://www.springframework.org/schema/context        http://www.springfamework.org/schema/context/spring-context-3.0.xsd"></beans>

在< beans>元素内,可以配置所有的Spring配置信息,包括< bean>声明。beans命名空间不是唯一的Spring命名空间,Spring的核心框架自带了10个命名空间的配置:
这里写图片描述

3、根据Bean与Bean之间的关系,配置xml文件
解释:声明一个普通Bean

    <!-- 调用默认构造器(无参) -->    <bean id="gun" class="com.zh.bean.Gun"></bean>

解释:声明一个Bean,并调用有参构造器,value为参数值

<!-- 调用有参构造器(基本类型) -->    <bean id="gun2" class="com.zh.bean.Gun">        <constructor-arg value="12" />    </bean>

解释:创建一个有参构造器Bean,参数为引用对象,用ref指向引用ID

<!-- 调用有参构造器(引用类型) 先创建引用对象 -->    <bean id="bullet" class="com.zh.bean.Bullet"></bean>    <bean id="gun3" class="com.zh.bean.Gun">        <!-- 参数跟构造器参数一致  value:基本,ref:引用 -->        <constructor-arg value="12" />        <constructor-arg ref="bullet" />    </bean>

解释:通过指定静态方法声明一个Bean

<!-- 调用静态方法装配Bean -->    <bean id="earth" class="com.zh.bean.Earth"  factory-method="getInstance" />

Bean的作用域:

所有Spring Bean默认都是单例,要改变Bean的作用范围,只需要配置Bean的scope属性,scope属性有以下取值
这里写图片描述
实例如下:
解释:是否确定每次引用都会创建一个实例

<!-- Bean作用域 -->    <bean id="singleton_student" class="com.zh.bean.Student" scope="singleton"></bean>    <!-- scope="prototype" (每次调用都创建一个实例) -->    <bean id="prototype_student" class="com.zh.bean.Student" scope="prototype"></bean>

初始化和销毁Bean

为Bean定义初始化和销毁操作,需要使用init-method和destory-method参数来配置< bean>元素。init-method属性指定在初始化Bean时要调用的方法,destory-method属性指定了Bean从容器中移除之前要调用的方法。

这里写图片描述

解释:实例化Bean调用初始化方法,关闭、结束调用destroy方法<!-- Bean初始化和销毁 -->    <bean id="light" class="com.zh.bean.Light" init-method="init" destroy-method="destroy" />

注入Bean属性

在Spring中可以使用< property>元素配置Bean的属性。< property>和< constructor-arg>在很多方面都类似,只不过一个是通过构造器参数注入值,一个是通过setter方法注入值。
解释:声明两个Bean,一个作为另外一个的属性

<!-- Bean 方法注入(引用类型) -->    <bean id="address" class="com.zh.bean.Address">        <property name="street" value="抚琴西路" />        <property name="house" value="158号" />        <property name="postcode" value="610110" />    </bean><!-- 对象注入 -->    <bean id="user" class="com.zh.bean.User">        <property name="name" value="张三" />        <property name="age" value="25" />        <property name="sex" value="男" />        <property name="address" ref="address" />    </bean>

内部注入

内部Bean通过直接声明一个< bean>元素作为< property>元素的子节点而定义的。内部Bean不仅限于setter注入,我们还可以把内部Bean装配到构造方法的参数中。
*注:内部Bean没有id属性,因为我们永远不会通过名字来引用内部Bean,这也突出了使用内部Bean的最大缺点:它不能被复用。内部Bean仅适用于一次注入,而且不能被其他Bean所引用。

<!-- 内部Bean装配 (构造器注入)-->    <bean id="musician" class="com.zh.bean.Musician">        <constructor-arg>            <bean class="com.zh.bean.Piano" />        </constructor-arg>    </bean>    <!-- 内部Bean装配 (方法注入) -->    <bean id="musician2" class="com.zh.bean.Musician">        <property name="piano">            <bean class="com.zh.bean.Piano" />        </property>    </bean>

装配集合

Spring提供了4中类型的集合配置元素:
这里写图片描述

<!-- 装配List/Set/Map集合bean -->    <bean id="chinses" class="com.zh.bean.Subject">        <property name="name" value="语文"></property>        <property name="score" value="80"></property>    </bean>    <bean id="math" class="com.zh.bean.Subject">        <property name="name" value="数学"></property>        <property name="score" value="70"></property>    </bean>    <bean id="english" class="com.zh.bean.Subject">        <property name="name" value="英语"></property>        <property name="score" value="60"></property>    </bean>        //list集合    <bean id="grade" class="com.zh.bean.Grade">        <property name="subjects">            <list>                <ref bean="chinses"/>                <ref bean="math"/>                <ref bean="english"/>            </list>        </property>        //set集合        <property name="classes">            <set>                <value>"j143"</value>                <value>"j144"</value>                <value>"j145"</value>            </set>        </property>        //map集合        <property name="numbers">            <map>                <entry key="j143" value="35" />                <entry key="j144" value="40" />                <entry key="j145" value="30" />            </map>        </property>    </bean>

这里写图片描述

装配Properties

<!-- 装配Properties集合Bean -->    <bean id="config" class="com.zh.bean.Config">    <!--name 为properties所在类的属性名-->        <property name="property">            <props>                <prop key="用户名">张三</prop>                <prop key="密码">123456</prop>                <prop key="邮箱">111@163.com</prop>            </props>        </property>    </bean>

SpEL表达式:

<!-- spel字面量,定义类的属性 -->    <bean id="goods" class="com.zh.spel.Goods">        <property name="name" value="#{'苹果'}"></property>        <property name="count" value="#{100}"></property>        <property name="price" value="#{12.5}"></property>        <property name="isBuy" value="#{true}"></property>    </bean>
<!-- SpEL引用bean --><bean id="father" class="com.zh.spel.Song">        <property name="name" value="#{'父亲'}"/>    </bean>    <bean id="singer" class="com.zh.spel.Singer">        <property name="name" value="#{'筷子兄弟'}" />        //name:类属性名,value:对应的ID        <property name="song" value="#{father}" />    </bean>
<bean id="songSelector" class="com.zh.spel.SongSelector">        <property name="songs">            <list>                <ref bean="smallApple"/>                <ref bean="oldBoy"/>                <ref bean="father"/>            </list>        </property>    </bean>
<!-- SpEL引用Bean的方法 -->    <bean id="ktvSinger" class="com.zh.spel.Singer">        <property name="name" value="#{'麦霸'}" />        <property name="song" value="#{songSelector.selectSong()}" />    </bean>
<!-- spel静态类引用 -->    <bean id="circle" class="com.zh.spel.Circle">        <property name="pi" value="#{T(java.lang.Math).PI}" />        <property name="radius" value="#{12.5}" />         <property name="random" value="#{T(java.lang.Math).random()}" />     </bean>

自动装配

1、byName:把Bean的属性具有相同名字(或ID)的其他Bean自动装配到Bean的对应属性中。
2、byType:把与Bean的属性具有相同类型的其他Bean自动装配到Bean的对应属性中。
byType使用与byName类似,只不过此处检测的是类型是否相同。如果匹配到多个Bean类型相同,Spring会抛出异常。
经测试,byType会匹配子类型,同样如果匹配到多个子类型也会抛出异常。
3、constructor:把与Bean的构造器入参具有相同类型的其他Bean自动装配到Bean构造器的对应入参中。

    <!-- 自动装配Bean -->    <bean id="boat" class="com.zh.bean.Boat" />    <!-- byName类型自动装配 -->       <bean id="people" class="com.zh.bean.People" autowire="byName" />    <!-- byType类型自动装配 -->    <bean id="people2" class="com.zh.bean.People" autowire="byType" />    <!-- constructor类型自动装配 -->    <bean id="people3" class="com.zh.bean.people" autowire="constructor" />

4、通过ApplicationContext读取配置文件,实例化一个应用上下文(applicationContext)

//读取配置文件private ApplicationContext applicationContext=new ClassPathXmlApplicationContext("com/zh/bean/springioc.xml");//实例化Bean//getBean(""),字符串为对应配置Bean的id,返回一个对象Goods goods=(Goods) applicationContext.getBean("goods");        System.out.println(goods);
原创粉丝点击