`
gao_xianglong
  • 浏览: 467785 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

详解SSJ(Spring3.x mvc + Spring3.x Core + JPA2.x)轻量级集成开发—第2章 剖析IOC容器进阶

阅读更多

上一章 详解SSJ(Spring3.x mvc + Spring3.x Core + JPA2.x)轻量级集成开发—第1章 剖析IOC容器

下一章 详解SSJ(Spring3.x mvc + Spring3.x Core + JPA2.x)轻量级集成开发—第3章 剖析依赖装配参数

 

 目录

一、BeanFactory和ApplicationContext详解

二、初始化IOC容器的二种方式
三、IOC容器中Bean的生命周期

四、IOC容器中Bean的作用域

五、Bean之懒加载

六、依赖注入之参数详解

七、整合多个配置文件

 

 前言

上一章节,笔者详细的为大家讲解了关于IOC容器的基本原理以及如何构建Spring应用。你可以把本章内容当做是上一章的进阶,因为笔者在本章会详细为大家讲解关于IOC容器的一些常用配置。当然在此笔者也要感谢那些支持笔者的朋友,因为没有你们的支持就没有笔者坚持写下去的动力,在此笔者深深的谢谢你们。

 

一、BeanFactory和ApplicationContext详解
上一章其实笔者已经对BeanFactory和ApplicationContext做了大致的介绍,并且大家都已经知道IOC(控制反转)容器仅是一个抽象的概念,而BeanFactory和ApplicationContext才是它具体的容器实现。当然可能不全面,既然是这样,那么笔者有必要在本章对此进行详细的补充,以便于让不了解的朋友更能够清晰的明白它们两个彼此之间的依赖关系

先从BeanFactory开始吧。BeanFactory作为IOC容器的顶层抽象接口,从理论上来说该接口仅仅只是一个维护依赖关系建立的Bean工厂,却由它负责IOC容器的初始化工作以及提供访问Bean定义的权限。该接口处于org.springframework.beans包下,其代表派生类有XmlBeanFactory(3.1版本以后该类型已经过时)。BeanFactory接口允许使用InputStream或者Resource的方式加载IOC配置文件。

使用BeanFactory初始化IOC容器:

/* 加载Ioc配置文件 */
Resource resource = new ClassPathResource("root-context.xml");
		
/* 初始化Ioc容器 */
BeanFactory factory = new XmlBeanFactory(resource);
	
或:

/* 加载Ioc配置文件 */
InputStream in = new FileInputStream("root-context.xml");
		
/* 初始化Ioc容器 */
BeanFactory factory = new XmlBeanFactory((Resource)in);

 

BeanFactory为我们提供的方法不多,但最为常用的就是getBean()方法了,我们可以通过该方法获取定义在IOC配置文件中的指定Bean类型的实例

使用BeanFactory获取Bean实例:

public class ClientTest 
{
	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception 
	{
		/* 加载Ioc配置文件,并初始化Ioc容器 */
		Resource resource = new ClassPathResource("root-context.xml");
		BeanFactory context = new XmlBeanFactory(resource);
		
		/* 获取LoginBean实例 */
		LoginBean loginBean = (LoginBean) context.getBean("loginBean");
		System.out.println(loginBean.getUserAccount());
		System.out.println(loginBean.getPassWord());
	}
}

  

ApplicationContext其实也是派生于BeanFactory,并且还进一步扩展了BeanFactory接口。比如:更易与Spring AOP集成、国际化处理、事件传递及各种不同应用层的上下文实现。
由于ApplicationContext完全派生自BeanFactory接口,也就是说BeanFactory所具备的特征,ApplicationContext同样具备,并且还拥有一些独有特性,所以一般开发者多选择ApplicationContext作为IOC容器接口。

ApplicationContext的派生类如下:

1、ClassPathXmlApplicationContext;

2、FileSystemXmlApplicationContext;

3、XmlWebApplicationContext;

 

如上派生类中,以ClassPathXmlApplicationContext最为常用。ClassPathXmlApplicationContext是从ClassPath路径下去加载指定的IOC配置文件。FileSystemXmlApplicationContext则是用磁盘的文件路径去寻找IOC配置文件。至于XmlWebApplicationContext则是从Web应用中去寻找IOC配置文件。你不用想太多,只要记住一点选用ApplicationContext初始化IOC容器时,你选用ClassPathXmlApplicationContext派生类就可以了。

当然除了加载IOC配置文件的路径不同以外,这些派生类初始化IOC容器的方式也是各不相同的。不过不用担心的是一旦成功初始化IOC容器以后,获取指定Bean实例的方式和BeanFactory是一样的,都是采用getBean()方法的形式。

使用ApplicationContext初始化IOC容器:

/* 加载多个配置文件 */
ApplicationContext context1 = new ClassPathXmlApplicationContext(
		new String[]{"a-context.xml", "b-context.xml"});

/* 使用通配符加载多个配置文件 */
ApplicationContext context2 = new ClassPathXmlApplicationContext("*-context.xml");

 

使用Applicationcontext获取Bean实例:

public class ClientTest 
{
	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception 
	{
		/* 加载Ioc配置文件,并初始化Ioc容器 */
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"root-context.xml");
		
		/* 获取LoginBean实例 */
		LoginBean loginBean = (LoginBean) context.getBean("loginBean");
		System.out.println(loginBean.getUserAccount());
		System.out.println(loginBean.getPassWord());
	}
}

 

提示:
BeanFactory和ApplicationContext还是存在一定区别的,当然这些区别并不影响你的使用。在程序中我们一旦成功初始化ApplicationContext容器后,ApplicationContext会自动实例化定义在IOC配置文件中的单例Bean实例以及自动完成参数的依赖装配。BeanFactory恰恰反之,只有当真正用到的时候BeanFactory才会对Bean进行实例以及依赖装配,也就是说BeanFactory其实很大程序上是基于懒加载(Lazy)模式的。


二、初始化IOC容器的二种方式
我们在上一章节中其实已经使用了IOC的初始方式之一,没错那就是手动初始化。你可能会想既然有手动初始化,那必然会有自动初始化?没错不过那是在Web项目中,通常都是由Web容器来负责IOC容器的自动初始化工作,无需开发人员手动干预。也就是说当Web容器启动运行时,便会自动初始化定义在web.xml文件中的IOC容器。
果我们希望由Web容器来帮助咱们实现自动初始化IOC容器的操作时,我们有两种自动实例方式可以选择:

1、ContextLoaderListener;

2、ContextLoaderServlet;

 

如果我们采用ContextLoaderListener的方式实现IOC容器的自动实例化,则需要在web.xml文件中配置如下信息:

<!-- 初始化ioc容器等相关配置 -->
<listener>
	<listener-class>org.springframework.web.context.
        ContextLoaderListener</listener-class>
</listener>
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>/WEB-INF/*-context.xml</param-value>
</context-param>

 

当你成功配置好上述文件后,一旦Web容器运行时,便会自动初始化咱们的IOC容器。上述程序我们采用监听的形式配置IOC容器,当然此方式仅限于Servlet2.4及以上规范的Servlet容器。如果你的Servlet容器规范低于2.4你可以选用ContextLoaderServlet的方式实现:

<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:spring-config/root-context.xml</param-value>
</context-param>
<servlet>
	<servlet-name>context</servlet-name>
	<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>

 

提示:

当Web容器启动的时候,Listener组件的加载顺序必然优先于Servlet组件。 至于ContextLoaderServlet的出现其最大的目的还是为了满足那些低于2.4 Servlet容器规范的Web容器。

 

三、IOC容器中Bean的生命周期

我们都知道一个POJO的生命周期大致可以由3部分组成,new创建-->就绪-->GC回收,但Spring的Bean实例的生命周期却远比这个复杂,下图为Bean的生命周期示例:

 

通过上图我们可以清晰的看见,IOC容器中的Bean实例的生命周期基本可以由5部分组成。首先当IOC(ApplicationContext)容器成功初始化后,便会实例化定义在配置文件中的所有单例Bean实例,接着再对参数进行依赖装配,如果<bean/>标签中配置有“init-method”属性时,则会优先执行Bean实例的指定方法乃至这个Bean实例就绪到最后的销毁,这便是整个Spring的Bean实例的生命周期。

在这里我们要明确一点,定义在配置文件中的Bean实例在缺省状态下都是单例模式,在Spring2.5以前我们可以在<bean/>标签中指定“singleton”属性为 “false”,这样定义在配置文件中的Bean实例则不会再为单利,一般我们在和Struts2.x做集成的时候,往往需要将Struts2.x的Action都设置为非单例,否则请求都会是同一个。只不过在Spring2.5以上后,我们将不能再继续使用 “singleton”属性,取而代之的是“scope”属性,我们只需要将该属性的值改为“prototype”即为非单利即可,缺省为属性值为“singleton”,也就是单例模式。

 

 四、IOC容器中Bean的作用域

在IOC容器中,如果Bean实例选用的是单例模式,其作用域范围为当IOC容器成功初始化后便会对其进行实例化。如果Bean实例选用的是非单例模式,其作用域范围为当IOC容器成功初始化后,并且当真正需要使用到Bean实例时,IOC容器才会对其进行实例化以及依赖装配。

以上是单例模式与非单例模式Bean的不同作用域范围。当然如果Bean实例本身就是单例模式的,但<bean/>标签中的“lazy-init”属性设置为“true”时,其作用域仍然与非单例模式保持一致,都是当需要真正使用到的时候才会对其进行实例化和依赖装配。 

 

五、Bean之懒加载

在上一章节笔者已经给大家介绍了有关Bean懒加载的一些概念,本章笔者将继续对懒加载模式进行讲解。其实所谓懒加载(Lazy)也可以叫做延迟加载,指的是当对象真正需要使用到的时候才会对其进行加载操作。这是概念上对懒加载模式的一种定义,但笔者接下来会告诉你关于如何在IOC配置文件中定义Bean的懒加载模式,以及懒加载模式的一些优缺点。

在配置文件中添加Bean实例的懒加载支持:

<!-- 定义LoginBean实例 -->
<bean id="loginBean" class="org.johngao.bean.LoginBean" lazy-init="true">
	<property name="userAccount" value="JohnGao" />
	<property name="passWord" value="123456" />
</bean>

 

通过上述配置,这个Bean则会采用懒加载模式进行加载,也就是说只有当客户端采用getBean()方法的时候IOC容器才会去对其进行实例化及依赖装配操作。

懒加载模式最大的优点在于可以降低资源开销平率,因为对象只有在真正需要使用到的时候才会选择加载。但懒加载的缺点同样也很显著,由于是运行期加载,很多未知的错误我们无法在程序启动时发现,换句话说就是无法在程序编译时发现错误,这样所对于开发人员而言是不太友好的。

 

提示:

在Spring的配置文件中,实现懒加载模式有2种方式。一种是在"<bean></bean>"标签中定义“lazy-init”属性,而另外一种则是使用“scope”属性定义非单例Bean。通过这2种方式均可以实现Bean的懒加载。

 

六、依赖注入之参数详解

本章节笔者将会对IOC的配置文件做一次详细的讲解,如果你对如何配置IOC容器中的相关参数已经非常熟悉了,笔者建议你直接跳过本章,因为免得耽误你的时间。但是对于刚接触Spring没有多久的开发人员,笔者建议你还是认真的阅读笔者接下来要讲解的诸多知识点,或许只有好处没有坏处,你认为呢?

IOC配置文件的存放路径Spring并没有强制要求你只能一定要放在ClassPath下,你可以选择放在任意目录下,甚至是远程目录,只是你需要选用不同的IOC容器实现来满足你的要求,仅此而已。

我们首先来看,在IOC配置文件中,如果你需要定义一个Bean实例你需要使用<bean>标签即可,在该标签内部你还可以使用<property/>标签或<constructor-arg/>标签来实现依赖装配。先来看一个常规的IOC配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
	<!-- 定义LoginBean实例 -->
	<bean id="loginBean" class="org.johngao.bean.LoginBean" lazy-init="true" 
		scope="prototype" destroy-method="destroy">
		<property name="userAccount" value="JohnGao" />
		<property name="passWord" value="123456" />
		<property name="objectTest" ref="userInfo" />
		<constructor-arg type="java.lang.String" value="JonGao123"/>
	</bean>
	
	<!-- 定义UserInfo实例 -->
	<bean id="userInfo" class="org.johngao.bean.UserInfo"/>
</beans>

 

笔者在上述配置文件中定义了2个Bean实例,其中loginBean笔者显式的指定了采用懒加载模式,以及非单例模式,并且笔者还才使用了“destroy-method”属性设置Bean在被销毁前要关闭一些资源等操作。在<bean/>标签中<property/>属性用于投值注入,其中“name”属性定义了参数的名称,这里笔者需要提示一下参数名称一定要和Bean的属性名称一致并且要保证唯一性,最后Bean还需要生成setter方法,Spring才会注入(后期笔者会讲解关于如何进行Bean的自动装配)。而“value”属性指定了具体的参数,这里参数不仅限是字符串而是任意类型的参数都可以,也就是Object类型,当然如果你想引用其他<bean/>标签中的实例,你可以使用“ref”属性进行引用。如果是构造注入你还需要标注其参数的类型,这一点仍然很很重要,在<constructor-arg/>标签中除了可以直接定义属性值,仍然可以使用“ref”属性进行引用。

 

提示:

关于Spring配置文件的DTD或者Xmlns笔者将不做讲解,如有需要,你可以参考其他文旦。

 

七、整合多个配置文件

在实际开发过程中,我们不可能只使用一个IOC配置文件来完成我们所有的操作和定义。往往我们需要编写多个配置文件来满足我们的需求,比如:web-context,dao-context,root-context等等,当然定义多少个配置文件在于你,关键是我们需要将这些配置文件整合在一起相互引用,否则这些配置文件分的再多,再细致也起不到丝毫作用。

 

提示:

假设A配置文件中配置有通用参数,B配置文件引用A文件以后,无需再次重复定义。

 

Spring允许在配置文件中使用<import/>标签手动引用其它配置文件:

<import resource="testB-context.xml"/>

 

上述方式我们是通过手动的方式在IOC配置文件中标注的,但如果你的配置文件特别多,而且相互存在引用,这个时候我们根本没有必要在使用<import/>标签,我们完全可以依靠IOC容器在初始化的时候使用通配符来实现:

/* 使用通配符加载多个配置文件 */
ApplicationContext context2 = new ClassPathXmlApplicationContext("*-context.xml"); 

 

一旦IOC容器对其多个配置文件进行加载后,这些配置文件已经存在相互关联和引用,无需我们再配置文件中使用<import/>进行导入。

本章内容到此结束,由于时间仓库,本文或许有很多不尽人意的地方,希望各位能够理解和体谅。关于下一章什么的跟新时间笔者初步订到后天晚上,谢谢各位的支持,晚安。

12
3
分享到:
评论
15 楼 蒙太奇 2013-05-31  
这几天一直在找关于SpringMVC,JPA的资料,没有一遍有你写的这么详细,很有耐心啊,可以出书了!
14 楼 hyl523 2013-01-22  
谢谢作者,很给力,启动spring aop,mvc
13 楼 gao_xianglong 2013-01-19  
好文章,受教了,谢谢。呵呵,提个小问题:这篇博文中总共出现了22次“笔者”,感觉好别扭呀,去掉一
WuNan2 写道
好文章,受教了,谢谢。呵呵,提个小问题:这篇博文中总共出现了22次“笔者”,感觉好别扭呀,去掉一去也许会更通俗流畅。


有吗,我们怎么没发现啊,哈哈
12 楼 WuNan2 2013-01-19  
好文章,受教了,谢谢。呵呵,提个小问题:这篇博文中总共出现了22次“笔者”,感觉好别扭呀,去掉一去也许会更通俗流畅。
11 楼 gao_xianglong 2013-01-17  
bifa37 写道
讲得很好。期待下文!

谢谢支持
10 楼 bifa37 2013-01-17  
讲得很好。期待下文!
9 楼 gao_xianglong 2013-01-17  
eprecated
longfor5 写道
看你这篇文字的时候顺便看了一下spring-beans的中XmlBeanFactory源码,结果发现这个类在spring3.1已经被废弃了。
org.springframework.beans.factory.xml.XmlBeanFactory


@Deprecated


Deprecated. as of Spring 3.1 in favor of DefaultListableBeanFactory and XmlBeanDefinitionReader




是的,确实已经是过时了,谢谢提醒。
8 楼 longfor5 2013-01-17  
看你这篇文字的时候顺便看了一下spring-beans的中XmlBeanFactory源码,结果发现这个类在spring3.1已经被废弃了。
org.springframework.beans.factory.xml.XmlBeanFactory


@Deprecated


Deprecated. as of Spring 3.1 in favor of DefaultListableBeanFactory and XmlBeanDefinitionReader


7 楼 gao_xianglong 2013-01-17  
zhengcong 写道
期待您的下篇文章,  

3q
6 楼 gao_xianglong 2013-01-17  
longfor5 写道
持续关注,再接再厉!

3Q
5 楼 zhengcong 2013-01-17  
期待您的下篇文章,  
4 楼 longfor5 2013-01-17  
持续关注,再接再厉!
3 楼 o_o_0 2013-01-17  
 
2 楼 gao_xianglong 2013-01-17  
duoduodeai 写道
   好文章,期待下篇

感谢支持。
1 楼 duoduodeai 2013-01-16  
   好文章,期待下篇

相关推荐

    spring-ssj.rar_spring_spring+Struts2+jpa集成

    在"spring-ssj.rar_spring_spring+Struts2+jpa集成"这个压缩包中,我们很可能会找到一个示例项目,展示了如何将Spring、Struts2和JPA进行集成。以下是这个集成过程的一些关键知识点: 1. **Spring配置**:首先,...

    Spring MVC+Spring+Spring data JPA

    Spring MVC、Spring 和 Spring Data JPA 是 Java 开发中非常重要的三个框架,它们共同构建了一个强大的企业级应用开发环境。Spring MVC 是一个用于构建 Web 应用的模型-视图-控制器(MVC)框架,Spring 提供了依赖...

    ssj(spring+Struts2+jpa)框架的集成(含jar包)

    综上所述,SSJ框架的集成利用了Spring的灵活性和控制反转,Struts2的MVC设计模式,以及JPA的数据持久化能力,为企业级应用提供了强大而灵活的开发基础。在实际项目中,开发者可以根据需求调整和扩展这个框架,以满足...

    Spring+Struts2+JPA

    **Spring+Struts2+JPA 整合详解** 在Java Web开发中,Spring、Struts2和JPA是三个非常重要的框架。Spring作为一个全面的轻量级框架,提供了依赖注入(DI)和面向切面编程(AOP)等功能;Struts2是一个强大的MVC框架...

    struts1.x+spring+jta集成例子(包含所有jar包)

    Struts1.x、Spring 和 JTA(Java Transaction API)是Java Web开发中常见的三大技术,它们各自在应用程序架构中承担着不同的角色。本集成例子旨在展示如何将这三者结合,构建一个完整的业务处理系统。 Struts1.x是...

    SSJ(struts2+spring+jpa)

    SSJ,全称为Struts2、Spring和JPA的组合,是Java开发中常见的Web应用程序架构模式。这个项目采用SSH框架,即Struts2作为MVC(Model-View-Controller)框架,Spring作为依赖注入(Dependency Injection,DI)和应用上...

    SSH/SSJ整合,Spring 3.1.0M1,Hibernate 3.X,struts2.1.8

    本项目结合了Spring 3.1.0M1、Hibernate 3.X以及Struts2.1.8,旨在提供一个最新的整合示例。 Spring作为核心框架,3.1.0M1是其早期的一个里程碑版本,带来了许多改进和新特性。例如,它强化了依赖注入(DI),使得...

    struts2+spring+jpa整合的完整例子(含分页)

    在学习jpa时候做的一个struts2+spring+jpa整合的完整例子 包含分页,一个简单的 资产入库系统 并实现了登陆等。

    Struts+spring+JPA例子

    Struts2、Spring和JPA是Java开发中的三大核心框架,它们各自负责应用程序的不同层面,协同工作能够构建出高效、可维护的企业级Web应用。在这个"Struts2.2.3+Spring3.0.5+JPA2.0"的例子中,我们将深入探讨这三个框架...

    SSJ.rar_Jap spring_ssj

    SSJ.rar_Jap_spring_ssj 是一个与Java应用程序开发相关的压缩包,它结合了Struts、Spring和JAP(可能是Java应用平台)这三种技术。这个项目可能是一个示例或者教程,展示了如何将这三个框架集成在一起以实现特定的...

    Spring2.5+struts1.2+JPA集成

    由于文件的大小限制,所需jar包请自行加入。但要注意在项目发部的时候,tomcat启动时总是报错,解决办法是把Tomcat中项目的lib文件夹下的asm-2.2.3.jar包删掉!或者把Spring的AOP Library包移除就OK了!

    JPA+Spring+Struts整合实例

    在Java企业级应用开发中,Spring、Struts和JPA(Java Persistence API)是三个非常重要的框架。它们分别负责不同的职责:Spring作为一个全能型框架,提供了依赖注入(DI)和面向切面编程(AOP),以及对其他框架的...

    ssj.rar_jpi框架_spring的jpi_struts2 jsp spring

    SSJ.rar是一个包含示例代码的压缩包,主要展示了如何集成和使用JPI(可能是Java Persistence Interface或自定义的框架)框架与Spring以及Struts2进行Web应用开发。在这个项目中,开发者可能想要演示如何在Spring中...

    spring-mvc-demo.zip

    Spring MVC 框架是Java开发中的一个核心组件,它为构建Web应用程序提供了一种模型-视图-控制器(MVC)架构。Spring框架本身提供了丰富的功能,包括依赖注入、AOP(面向切面编程)、事务管理等,而Spring MVC则是...

    ssj整合开发jar包清单

    Spring 是一个开源的轻量级 Java EE 开发框架,其核心功能包括依赖注入、面向切面编程等。Spring 3.0 版本带来了许多新的特性和改进,如支持 HTTP 方法注解、更强大的 XML 配置等。 - **核心库**: - `spring-core...

    Struts1.3+spring2.5+JPA(hibernate) demo

    Struts1.3、Spring2.5和JPA(基于Hibernate)是Java Web开发中三个重要的框架,它们的集成使用可以构建出强大的企业级应用。这个"Struts1.3+spring2.5+JPA(hibernate) demo"提供了一个实践性的学习案例,帮助初学者...

    ssh+ssj+ssi jar包第一部分

    苦恼直接使用此包可以进行ssh ssi ssj 使用jpa开发时支持给中ROM,版本:struts2.1.8+spring2.5.6+ibatis2.3+hibernate3.3.2+structjson+dwr不多说了 分两部分,因为每次不超过 15M, 这些包一共 18M多 第二部分 ...

    spring jpa操作数据库 级联数据 hibernate

    SSJ通常指的是Struts2、Spring和JPA的集成,这种架构常见于大型企业应用。通过PPTX文件"ssj框架搭建",我们可以了解到如何配置这三个框架,实现它们之间的协作。 6. **示例项目和资源:** - "JPA+-amp+Hibernate+...

    struts2+spring2.5+jpa(基于注释)

    Struts2、Spring2.5 和 JPA 是Java企业级开发中的三大核心技术,它们共同构建了一个强大且灵活的Web应用程序框架。在这个“SSJ使用注释版”项目中,开发者利用注解的方式简化了配置,使得整个应用的搭建更加直观和...

    Spring SpringMVC Jpa整合Demo

    在JavaEE开发中,Spring、SpringMVC和JPA是三个非常重要的框架,它们的整合应用可以极大地提高开发效率和代码质量。这个"Spring SpringMVC Jpa整合Demo"就是一个典型的例子,它展示了如何将这三个框架协同工作,构建...

Global site tag (gtag.js) - Google Analytics