实例化Bean的几种方式
- 基于默认构造方法实例化
- 基于构造方法实例化
- 基于静态工厂实例化 了解即可
- 基于工厂实例方法实例化 了解即可
接下来, 我们演示一下, 从构造方法怎么实例化对象.
applicatioinContext.xml
<bean id="sweetApple" class="com.imooc.spring.ioc.entity.Apple">
<!-- 没有constructor-arg则代表调用默认构造方法实例化 -->
<constructor-arg name="title" value="红富士"></property>
<constructor-arg name="origin" value="欧洲"></property>
<constructor-arg name="color" value="红色"></property>
</bean>
<bean id="apple2" class="com.imooc.spring.ioc.entity.Apple">
<!-- 可以利用index属性代替name属性 -->
<constructor-arg index="0" value="红富士"></constructor-arg>
<constructor-arg index="1" value="欧洲"></constructor-arg>
<constructor-arg index="2" value="红色"></constructor-arg>
</bean>
利用静态工厂获取实例
applicationContext.xml
<!-- 利用静态工厂对象 -->
<bean id="apple4" class="com.imooc.spring.ioc.factory.AppleStaticFactory" factory-method="createSweetApple" />
AppleStaticFactory.java
public class AppleStaticFactory{
public static Apple createSweetApple(){
Apple apple=new Apple();
apple.setTitle("红富士");
apple.setOrigin("欧洲");
apple.setColor("红色");
return apple;
}
}
利用工厂实例方法获取对象
applicationContext.xml
<bean id="factoryInstance" class="com.imooc.spring.ioc.factory.AppleFactoryInstance"/>
<bean id="apple5" factory-bean="factoryInstance" factory-method="createSweetApple" />
代码中获取Bean的两种写法
//第一种方式获取
Apple sweetApple = context.getBean("sweetApple",Apple.class);
//第二种方式获取 强转
Apple sweetApple2 = (Apple) context.getBean("sweetApple");
xml中 id与name的区别
相同点
- bean id和name都是设置对象在IoC容器中唯一标识
- 两者在同一个配置文件中都不允许出现重复
- 两者允许在多个配置文件中出现重复, 新对象覆盖旧对象
- tips:id与name的命名要求有意义, 按驼峰命名书写
区别
- id要求更为严格, 一次只能定一个对象标识(推荐)
- name更为宽松, 一次允许定义多个name标识, 用逗号隔开, 例如 name=“apple1,apple2”
注意:
- 如果在两个配置文件中出现了重复的id或name, 那么根据加载顺序, 新的对象覆盖掉旧对象.
路径表达式
表达式实例 | 说明 |
---|---|
classpath:config.xml | 扫描classpath根路径(不包含jar)的config.xml |
classpath:com/imooc/config.xml | 扫描classpath下(不包含jar)com.imooc包中的config.xml |
classpath*:com/imooc/config.xml | 扫描classpath下(包含jar)com.imooc包中的config.xml |
classpath:config-*.xml | 扫描classpath根路径下所有以config-开头的XML文件 |
classpath:com/**/config.xml | 扫描com包下(包含任何子包)的config.xml |
file:c:/config.xml | 扫描c盘根路径config.xml |
路径表达式一般不用修改, 直接从resource根目录下加载即可.
注入集合对象
注入List(String)
<bean id="company" class="com.imooc.spring.ioc.entity.Company">
<property name="rooms">
<list>
<value>2001-总裁办</value>
<value>2003-总经理办公室</value>
<value>2010-研发部会议室</value>
</list>
</property>
</bean>
注入Set(String)
<bean id="company" class="com.imooc.spring.ioc.entity.Company">
<property name="rooms">
<set>
<value>2001-总裁办</value>
<value>2003-总经理办公室</value>
<value>2010-研发部会议室</value>
</set>
</property>
</bean>
注入Map(String,Object)
<bean id="c1" class="com.imooc.spring.ioc.entity.Computer">
<constructor-arg name="brand" value="联想"/>
<constructor-arg name="type" value="台式机"/>
<constructor-arg name="sn" value="838928012"/>
<constructor-arg name="price" value="3085"/>
</bean>
<bean id="company" class="com.imooc.spring.ioc.entity.Company">
<property name="computers">
<map>
<entry key="dev-88172" value-ref="c1" />
<entry key="dev-88173">
<bean class="com.imooc.spring.ioc.entity,Computer">
<constructor-arg name="brand" value="惠普"/>
<constructor-arg name="type" value="笔记本 "/>
<constructor-arg name="sn" value="4677556775"/>
<constructor-arg name="price" value="4399"/>
</bean>
</entry>
</map>
</property>
</bean>
注入Properties
<bean id="company" class="com.imooc.spring.ioc.entity.Company">
<property name="info">
<props>
<prop key="phone">010-12345678</prop>
<prop key="address">北京市朝阳区XX路XX大厦</prop>
<prop key="website">http://www.xxx.com</prop>
</props>
</property>
</bean>
获取容器内所有bean的名称
ApplicationContext context=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
Company company = context.getBean("company",Company.class);
String website = company.getInfo().getProperty("website");
//获取容器内所有beanId数组
String [] beanNames=context.getBeanDefinitionNames();
bean scope
- bean scope属性用于决定对象何时被创建与作用范围
- bean scope配置将影响容器内对象的数量
- bean scope默认值singleton(单例), 指全局共享同一个对象实例
- 默认情况下bean会在IoC容器创建后自动实例化, 全局唯一
scope 属性清单
scope属性 | 说明 |
---|---|
singleton | 单例(默认值), 每一个容器有且只有唯一的实例, 实例被全局共享 |
prototype | 多例, 每次使用时都是创建一个实例 |
request | web环境下, 每一次独立请求存在唯一实例 |
session | web环境下, 每一个session存在有唯一实例 |
application | web环境下, ServletContext存在唯一实例 |
websocket | 每一次WebSocket连接中存在唯一实例 |
注意:
singleton在容器是单例多线程执行, 存在线程安全风险
prototype多例, 每一次获取, 都会创建一个新的. prototype在容器中多实例, 占用更多资源, 不存在线程安全问题.
singleton与prototype对比
singleton | prototype | |
---|---|---|
对象数量 | 全局唯一 | 存在多个 |
实例化时机 | IoC容器启动时 | getBean()或对象注入时 |
线程安全问题 | 存在 | 不存在 |
执行效率 | 高 | 低 |
Bean的生命周期
图片 406
init-method - 配置初始化方法
<bean id="order1" class="com.imooc.spring.ioc.entity.Order" init-method="init" >
<property name="price" value="19.8" />
<property name="quantity" value="1000" />
</bean>
destory - 配置销毁方法
<bean id="order1" class="com.imooc.spring.ioc.entity.Order" destroy-method="destroy" >
<property name="price" value="19.8" />
<property name="quantity" value="1000" />
</bean>
注意, 在手动调用((ClassPathXmlApplicationContext)context).registerShutdownHook();
后, bean实例会调用destory方法