Spring(二)装配Bean(注入)

什么是装配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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值