Spring中的实例生成方式及其生命周期
三种实例化bean的方式
1.使用类构造器实例化
<!-- 使用类构造器实例化,class属性表示要使用的类的全限定名 -->
<bean id="userDao1"
class="com.winner.dao.daoImpl.UserDaoImpl">
</bean>
使用反射利用类的无参构造器生成实例。
2.使用静态工厂方法实例化
--配置文件:
<!-- 使用静态工厂方法实例化
class属性表示工厂类的全限定名
factory-method属性表示这个工厂类中用于创建实例的静态方法名(必须是static的)
-->
<bean id="userDao2"
class="com.winner.dao.StaticDaoFactory"
factory-method="createUserDaoInstance">
</bean>
--工厂类:
public class StaticDaoFactory {
// 方法必须声明为static的
public static Object createUserDaoInstance() {
System.out.println("StaticDaoFactory.createUserDaoInstance()");
return new UserDaoImpl();
}
}
3.使用实例化的工厂对象中的方法实例化,首先要构造出工厂实例,然后在生成实例
--配置文件:
<!-- 使用实例化工厂对象中的方法实例化
一、定义工厂bean
二、定义这个bean是由工厂方法创建的,其中:
factory-bean属性表示工厂bean的名称(id或name)
factory-method属性表示这个工厂类中用于创建实例的方法名(不能是static的)
-->
<bean id="simpleDaoFactory"
class="com.winner.dao.SimpleDaoFactory"></bean>
<bean id="userDao3"
factory-bean="simpleDaoFactory"
factory-method="createUserDaoInstance">
</bean>
--工厂类:
public class SimpleDaoFactory {
// 方法不能声明为static的
public static Object createUserDaoInstance() {
System.out.println("SimpleDaoFactory.createUserDaoInstance()");
return new UserDaoImpl();
}
}
我们一般写代码的时候都会分层,显示层,业务层,数据访问层,显示层调用业务层,业务层调用数据访问层。
数据访问层Dao只需要一个实例,业务层Service只需要一个实例,但是action每一次访问都会生成一个实例。
------------
Bean的作用域
在Spring IoC容器中定义的bean默认只有一个实例(单例的),且默认情况下会在容器启动时初始化bean(饿汉式),但我们可以指定Bean节点的lazy-init="true"来延迟初始化bean(懒汉式),这时候,只有第一次获取bean会才初始化bean。如:
--创建类:
public class User {
public User() {
System.out.println("初始化了User...");
}
}
--配置文件:
<!--
scope属性:用于指定bean的生命周期 singleton:单例的,每次ac.getBean()返回的都是同一个实例.
prototype:多例的,第次ac.getBean()返回的都是一个新的实例. 默认为singleton。
lazy-init属性:用于指定在什么时候初始化单例的对象
false:表示在创建ApplicationContext时就初始化本单例的对象。
true:表示在第一次调用getBean()获取本对象时才初始化。 默认为default.
-->
<bean id="user1" class="com.winner.spring.User"/>
或是:
<bean id="user1" class="com.winner.spring.User" scope="singleton"/>
或是:
<bean id="user1" class="com.winner.spring.User" scope="singleton" lazy-init="default"/>
或是
<bean id="user1" class="com.winner.spring.User" scope="singleton" lazy-init="false"/>
以上几种配置,都是在ApplicationContext容器创建时就生成了User对象。
<bean id="user1" class="com.winner.spring.User" scope="singleton" lazy-init="true"/>
当lazy-init取值true时,容器创建不会创建User对象,只有在getBean()时才会创建对象,即延迟加载
对所有bean都应用延迟初始化:
方法是在根节点beans中设置属性default-lazy-init="true",如下所示:
<beans default-lazy-init="true" ...>
prototype(原型,表示每次获取的都是新对象)
每次从容器获取bean都是新的对象。
<bean id="user1" class="com.winner.spring.User" scope="prototype"/>
getBean()时生成实例。
指定Bean的初始化方法和销毁方法
--创建类:
public class UserDao {
private DataSource dataSource; public DataSource getDataSource() {
return dataSource;
} public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* 初始化方法
*/
public void init() {
System.out.println("UserDao.init() 初始化方法");
} /**
* 销毁的方法
*/
public void destroy() {
System.out.println("UserDao.destroy() 销毁的方法");
}
}
--配置:
<!-- 单例的对象,配置了初始化方法与销毁方法 -->
<bean id="userDao" class="com.winner.spring.UserDao"
init-method="init" destroy-method="destroy"
/>
--测试代码:
// 在ApplicationContext接口中没有定义close()方法,要想调用,就得先转为子类类型才行。
// 一定要关闭ApplicationContext,给bean配置的销毁方法才会被调用。
// 在单例时,配置的初始化与销毁方法都会被调用。
// 在多例时,只有配置的初始化才会被调用。
@Test
public void test() throws Exception {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml", getClass());
UserDao userDao = (UserDao) ac.getBean("userDao");
System.out.println(userDao); ac.close();
}
--注意:
---如果scope属性为prototype则不受spring缓存的控制,destory方法也将不会执行(scope调为singleton时才会有效)。
---要调用ApplicationContext的close()方法才会执行destory方法(在ApplicationContext接口中没有close()方法,需要强转为具体的实现类才可以调用)
Spring中的实例生成方式及其生命周期的更多相关文章
- Spring中与bean有关的生命周期
前言 记得以前的时候,每次提起Spring中的bean相关的生命周期时,内心都无比的恐惧,因为好像有很多,自己又理不清楚,然后看网上的帖子,好像都是那么一套,什么beanFactory啊,aware接 ...
- 详解Spring中Bean的作用域与生命周期
摘要:在利用Spring进行IOC配置时,关于bean的配置和使用一直都是比较重要的一部分,同时如何合理的使用和创建bean对象,也是小伙伴们在学习和使用Spring时需要注意的部分,所以这一篇文章我 ...
- Spring中Bean的作用域、生命周期
Bean的作用域.生命周期 Bean的作用域 Spring 3中为Bean定义了5中作用域,分别为singleton(单例).protot ...
- Spring中bean的作用域与生命周期
在 Spring 中,那些组成应用程序的主体及由 Spring IOC 容器所管理的对象,被称之为 bean.简单地讲,bean 就是由 IOC 容器初始化.装配及管理的对象,除此之外,bean 就与 ...
- Spring中Bean的作用域和生命周期
作用域的种类 Spring 容器在初始化一个 Bean 的实例时,同时会指定该实例的作用域.Spring3 为 Bean 定义了五种作用域,具体如下. 1)singleton 单例模式,使用 sing ...
- 阶段3 2.Spring_03.Spring的 IOC 和 DI_8 spring中bean的细节之生命周期
区分单例还是多例对象 单例的几个状态 初始化方法和销毁方法 设置成我们定义的方法 测试 有创建和初始化.但是没有销毁,.对象一直没有销毁的方法 main方法是一切应用程序的入门.当main方法结束后. ...
- 如何在web.config文件中配置Session变量的生命周期
实例说明:在网上购物商城中,为了维护在线购物环境,一般只有注册会员才可以购买商品.实现购物功能时,先通过Session变量记录会员的登录名,然后在购买商品页面通过判断会员是否登录确定其能否购买商品. ...
- Flutter--Flutter中Widget、App的生命周期
前言 在App的开发过程中,我们通常都需要了解App以及各个页面的生命周期,方便我们在App进入前台时启动一些任务,在进入后台后暂停一些任务.同时,各个页面的生命周期也很重要,每个页面消失时要做一些内 ...
- C/C++——C++变量的作用域与生命周期,C语言中变量的作用域和生命周期
全局变量 作用域:全局作用域(全局变量只需在一个源文件中定义,就可以作用于所有的源文件.) 生命周期:程序运行期一直存在 引用方法:其他文件中要使用必须用extern 关键字声明要引用的全局变量. 内 ...
随机推荐
- Percona-Server-5.5.33-31.1安装
一.下载 http://www.percona.com/downloads/Percona-Server-5.5/ Percona-Server-5.5.33-31.1 选择 binary 选择lin ...
- Java 学习计划
第一部分 在搭建SSM的过程中,可能会经常接触到一个叫maven的工具.这个工具也是你以后工作当中几乎是必须要使用的工具,所以你在搭建SSM的过程中,也可以顺便了解一下maven的知识.在你目前这个阶 ...
- 在ThinkPHP3.x框架中实现将原创文章第一时间推送到百度收录
前两天自己写的一篇文章“针对BootStrap中tabs控件的美化和完善”被别的网站给转载了,这也许是值得高兴的一件事情,但是有些网站并没有注明来源和作者.而去百度搜索这篇文章,排名第一的居然是那些转 ...
- 排序,求几个最值问题,输入n个整数,输出其中最小的k个元素。
看完两个求最大值算法之后的一些感想. 如果想直接看算法的可以跳过.但是我觉得我这些想法还是比较有用的,至少对我将来的算法设计是这样的. 算法的功能越强大,必然意味着速度慢,因为根据丛林法则,那种慢又功 ...
- 使用XFire+Spring构建Web Service
XFire是与Axis 2并列的新一代Web Service框架,通过提供简单的API支持Web Service各项标准协议,帮助你方便快速地开发Web Service应用. 相 对于Axis来说,目 ...
- php入门单引号与双引号区别
[1]单引号和双引号在处理变量的时候做法: 括在双引号内的变量会解释出值,但是括在单引号内则不做处理,直接输出: <?php $var = 'my name is huige'; echo &q ...
- Delphi Base64 编解码函数
Delphi 自带 Base64 编解码的单元, EncdDecd这个单元提供两套四个公开函数: 对流的编解码:procedure EncodeStream(Input, Output: TStrea ...
- 在emacs里用w3m浏览网页
给w3m配置个~/.emacs老是暴错误,在配置里把这个注掉就OK了;(require 'mime-w3m) ;;支持w3m (add-to-list 'load-path "/usr/sh ...
- Linux进程间通信IPC学习笔记之消息队列(Posix)
基础知识: 消息队列可认为是一个消息链表,有足够写权限的线程可往队列中放置消息,有足够读权限的线程可以从队列中取走消息.在某个进程往一人队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达. ...
- SharedPreference.Editor的apply与commit方法不同之处
定义: void apply boolean commit; 相同:二者都是提交修改的数据 手机里的文件存放在/data/data/<package_name>/shared_prefs ...