您的位置:首页 > 编程语言 > Java开发

Spring(二)装配Bean(注入)

2017-11-21 23:21 267 查看

什么是装配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">
<
4000
span class="hljs-comment"><!-- 参数跟构造器参数一致  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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring 装配