Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 3603|回复: 12

spring学习笔记

[复制链接]

697

主题

1142

帖子

4086

积分

认证用户组

Rank: 5Rank: 5

积分
4086
发表于 2017-6-22 09:23:59 | 显示全部楼层 |阅读模式
本帖最后由 java 于 2017-6-22 09:30 编辑

本教程是基于在 2015 年 3 月发布的 Spring 框架 4.1.6 版本编写的。

Spring 概述概述
Spring 是最受欢迎的企业级 Java 应用程序开发框架。数以百万的来自世界各地的开发人员使用 Spring 框架来创建好性能、易于测试、可重用的代码。
Spring 框架是一个开源的 Java 平台,它最初是由 Rod Johnson 编写的,并且 2003 年 6 月首次在 Apache 2.0 许可下发布。
当谈论到大小和透明度时, Spring 是轻量级的。 Spring 框架的基础版本是在 2 MB 左右的。
Spring 框架的核心特性可以用于开发任何 Java 应用程序,但是在 Java EE 平台上构建 web 应用程序是需要扩展的。 Spring 框架的目标是使 J2EE 开发变得更容易使用,通过启用基于 POJO 编程模型来促进良好的编程实践。

依赖注入(DI Dependecy Injection)
Spring 最认同的技术是控制反转的依赖注入(DI)模式。控制反转(IoC Inversion of Control)是一个通用的概念,它可以用许多不同的方式去表达,依赖注入仅仅是控制反转的一个具体的例子。
当编写一个复杂的 Java 应用程序时,应用程序类应该尽可能的独立于其他的 Java 类来增加这些类可重用可能性,当进行单元测试时,可以使它们独立于其他类进行测试。依赖注入(或者有时被称为配线)有助于将这些类粘合在一起,并且在同一时间让它们保持独立。
到底什么是依赖注入?让我们将这两个词分开来看一看。这里将依赖关系部分转化为两个类之间的关联。例如,类 A 依赖于类 B。现在,让我们看一看第二部分,注入。所有这一切都意味着类 B 将通过 IoC 被注入到类 A 中。
依赖注入可以以向构造函数传递参数的方式发生,或者通过使用 setter 方法 post-construction。由于依赖注入是 Spring 框架的核心部分,所以我将在一个单独的章节中利用很好的例子去解释这一概念。

面向方面的程序设计(AOP): AOP是OOP的延续,是(Aspect Oriented Programming)的缩写,意思是面向切面编程。
Spring 框架的一个关键组件是面向方面的程序设计(AOP)框架。一个程序中跨越多个点的功能被称为横切关注点,这些横切关注点在概念上独立于应用程序的业务逻辑。有各种各样常见的很好的关于方面的例子,比如日志记录、声明性事务、安全性,和缓存等等。
在 OOP 中模块化的关键单元是类,而在 AOP 中模块化的关键单元是方面。AOP 帮助你将横切关注点从它们所影响的对象中分离出来,然而依赖注入帮助你将你的应用程序对象从彼此中分离出来。
Spring 框架的 AOP 模块提供了面向方面的程序设计实现,允许你定义拦截器方法和切入点,可以实现将应该被分开的代码干净的分开功能。我将在一个独立的章节中讨论更多关于 Spring AOP 的概念。
https://www.w3cschool.cn/wkspring/pesy1icl.html



回复

使用道具 举报

697

主题

1142

帖子

4086

积分

认证用户组

Rank: 5Rank: 5

积分
4086
 楼主| 发表于 2017-6-22 09:39:40 | 显示全部楼层
本帖最后由 java 于 2017-6-22 10:05 编辑

Spring 体系结构体系结构
Spring 有可能成为所有企业应用程序的一站式服务点,然而,Spring 是模块化的,允许你挑选和选择适用于你的模块,不必要把剩余部分也引入。下面的部分对在 Spring 框架中所有可用的模块给出了详细的介绍。
Spring 框架提供约 20 个模块,可以根据应用程序的要求来使用。
核心容器
核心容器由核心,Bean,上下文和表达式语言模块组成,它们的细节如下:
  • 核心模块提供了框架的基本组成部分,包括 IoC 和依赖注入功能。
  • Bean 模块提供 BeanFactory,它是一个工厂模式的复杂实现。
  • 上下文模块建立在由核心和 Bean 模块提供的坚实基础上,它是访问定义和配置的任何对象的媒介。ApplicationContext 接口是上下文模块的重点。
  • spEl表达式语言模块(Spring表达式语言 Spring Expression Language)在运行时提供了查询和操作一个对象图的强大的表达式语言。
数据访问/集成
数据访问/集成层包括 JDBC,ORM,OXM,JMS 和事务处理模块,它们的细节如下:
  • JDBC 模块提供了删除冗余的 JDBC 相关编码的 JDBC 抽象层。
  • ORM 模块(对象关系映射 Object Relational Mapping)为流行的对象关系映射 API,包括 JPA,JDO,Hibernate 和 iBatis,提供了集成层。
  • OXM 模块提供了抽象层,它支持对 JAXB,Castor,XMLBeans,JiBX 和 XStream 的对象/XML 映射实现。[]
  • Java 消息服务 JMS 模块包含生产和消费的信息的功能。
  • 事务模块为实现特殊接口的类及所有的 POJO 支持编程式和声明式事务管理。
Web
Web 层由 Web,Web-MVC,Web-Socket 和 Web-Portlet 组成,它们的细节如下:
  • Web 模块提供了基本的面向 web 的集成功能,例如多个文件上传的功能和使用 servlet 监听器和面向 web 应用程序的上下文来初始化 IoC 容器。
  • Web-MVC 模块包含 Spring 的模型-视图-控制器(MVC),实现了 web 应用程序。
  • Web-Socket 模块为 WebSocket-based 提供了支持,而且在 web 应用程序中提供了客户端和服务器端之间通信的两种方式。
  • Web-Portlet 模块提供了在 portlet 环境中实现 MVC,并且反映了 Web-Servlet 模块的功能。
其他
还有其他一些重要的模块,像 AOP,Aspects,Instrumentation,Web 和测试模块,它们的细节如下:
  • AOP 模块提供了面向方面的编程实现,允许你定义方法拦截器和切入点对代码进行干净地解耦,它实现了应该分离的功能。
  • Aspects 模块提供了与 AspectJ 的集成,这是一个功能强大且成熟的面向切面编程(AOP)框架。
  • Instrumentation 模块在一定的应用服务器中提供了类 instrumentation 的支持和类加载器的实现。
  • Messaging 模块为 STOMP 提供了支持作为在应用程序中 WebSocket 子协议的使用。它也支持一个注解编程模型,它是为了选路和处理来自 WebSocket 客户端的 STOMP 信息。
  • 测试模块支持对具有 JUnit 或 TestNG 框架的 Spring 组件的测试。



注:
----------OXM------------------
O/X Mapper O/X 映射器.  O 代表 Object,X 代表 XML. 它的目的是在 Java 对象(几乎总是一个 plain old Java object,或简写为 POJO)和 XML 文档之间来回转换。
编组(marshalling) 也称为序列化(serializing):将 Java bean 转换成 XML 文档的过程,这意味着 Java bean 的所有字段和字段值都将作为 XML 元素或属性填充到 XML 文件中。
解组(unmarshalling) 也称为反序列化(deserializing):将 XML 文档转换为 Java bean,这意味着 XML 文档的所有元素或属性都作为 Java 字段填充到 Java bean 中。

-----------------STOMP--------------------
STOMP即Simple (or Streaming) Text Orientated Messaging Protocol,简单(流)文本定向消息协议,它提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消息代理(Broker)进行交互。STOMP协议由于设计简单,易于开发客户端,因此在多种语言和多种平台上得到广泛地应用。



回复 支持 反对

使用道具 举报

697

主题

1142

帖子

4086

积分

认证用户组

Rank: 5Rank: 5

积分
4086
 楼主| 发表于 2017-6-22 10:17:55 | 显示全部楼层
本帖最后由 java 于 2017-6-22 10:19 编辑

Spring 环境配置
https://www.w3cschool.cn/wkspring/f6pk1ic8.html
环境设置

本教程将指导你如何准备开发环境来使用 Spring 框架开始你的工作。本教程还将教你在安装 Spring 框架之前如何在你的机器上安装 JDK,Tomcat 和 Eclipse。
第 1 步:安装 Java 开发工具包(JDK)

你可以从 Oracle 的 Java 网站 Java SE Downloads 下载 SDK 的最新版本。你会在下载的文件中找到教你如何安装 JDK 的说明,按照给出的说明安装和配置 JDK 的设置。最后,设置 PATH 和 JAVAHOME 环境变量,引入包含 java 和 javac 的目录,通常分别为 java install dir/bin 和 java install _ dir。
如果你运行的是Windows,并在C:\jdk1.6.0_15上安装了JDK,你就可以把下面这行写入C:\autoexec.bat文件中。
set PATH=C:\jdk1.6.0_15\bin;%PATH%
set JAVA_HOME=C:\jdk1.6.0_15
或者,在 Windows XP/7/8 中,你也可以右键单击“我的电脑”,选择“属性”,然后是“高级”,然后是“环境变量”。接下来,你将更新 PATH 值,并且按下 OK 按钮。
在 Unix(Solaris、Linux 等等)上,如果在 /usr/local/jdk1.6.0_15 上安装 SDK,并且使用 C shell 命令,你将把下面的内容添加到 .cshrc 文件中。
setenv PATH /usr/local/jdk1.6.0_15/binPATH
setenv JAVA_HOME /usr/local/jdk1.6.0_15
或者,如果你使用集成开发环境(IDE),如 Borland JBuilder,Eclipse,IntelliJ IDEA 或者 Sun ONE Studio,编译和运行一个简单的程序,用来确认 IDE 知道你安装了 Java,否则应该根据 IDE 给定的文档做正确的设置。
第 2 步:安装 Apache Commons Logging API

你可以从 http://commons.apache.org/logging/ 下载 Apache Commons Logging API 的最新版本。一旦你下载完安装包,并且解压二进制的发行版本到一个方便的位置。例如在 windows 上的 C:\commons-logging-1.1.1 中,或在 Linux/Unix 上的 /usr/local/commons-logging-1.1.1 中。该目录将有如下的 jar 文件和其他支持的文件等。
确保你在这个目录上正确的设置 CLASSPATH 变量,否则你将会在运行应用程序时遇到问题。
第 3 步:安装 Eclipse IDE
本教程中的所有例子使用 Eclipse IDE 编写。所以我建议你应该在你的机器上安装 Eclipse 的最新版本。
为了安装 Eclipse IDE,从 http://www.eclipse.org/downloads/ 上下载最新的 Eclipse 二进制文件。一旦你下载完安装包,并且解压二进制的发行版本到一个方便的位置。例如在 windows 上的 C:\eclipse 中,或在 Linux/Unix 上的 /usr/local/eclipse 中,最后恰当的设置 PATH 变量。
在 Windows 机器上,可以通过执行以下命令启动 Eclipse,或者可以简单地双击 eclipse.exe。
%C:\eclipse\eclipse.exe
在 Unix(Solaris 和 Linux 等)上,可以通过执行下面的命令启动 Eclipse:
$/usr/local/eclipse/eclipse
启动成功后,如果一切正常,它应该显示下面的结果:

第 4 步:安装 Spring 框架库
现在如果一切正常,你就可以继续设置你的 Spring 框架。下面是在你的机器上下载并安装框架的简单步骤。
  • 选择是要在 Windows 还是在 UNIX 上安装 Spring,然后继续进行下一个步骤,在 Windows 上下载 .zip 文件,而在 Unix 上下载 .tz 文件。
  • http://repo.spring.io/release/org/springframework/spring 下载最新版本的 Spring 框架的二进制文件。
  • 在写本教程的时候,我在我的 Windows 机器上下载了 spring-framework-4.1.6.RELEASE-dist.zip,当你解压缩下载的文件时,它内置的目录结构为 E:\spring,如下所示。
你会在目录 E:\spring\libs 中发现所有的 Spring 库。确保你在这个目录上正确的设置 CLASSPATH 变量,否则你将会在运行应用程序时遇到问题。如果使用的是 Eclipse,就不需要设置 CLASSPATH,因为所有的设置将通过 Eclipse 完成。
一旦你完成了最后一步后,你就可以继续你的第一个 Spring 例子,你将会在下一章中看到。



回复 支持 反对

使用道具 举报

697

主题

1142

帖子

4086

积分

认证用户组

Rank: 5Rank: 5

积分
4086
 楼主| 发表于 2017-6-22 10:56:55 | 显示全部楼层
Spring Hello World 实例
让我们使用 Spring 框架开始实际的编程。在你开始使用 Spring 框架编写第一个例子之前,你必须确保已经正确地设置了 Spring 环境,正如在 Spring——环境设置 教程中如所说的。假设你有了解一些有关 Eclipse IDE 工作的知识。
因此,让我们继续编写一个简单的 Spring 应用程序,它将根据在 Spring Beans 配置文件中配置的信息输出 “Hello World!” 或其他信息。
第 1 步:创建 Java 项目
第一步是使用 Eclipse IDE 创建一个简单的 Java 项目。按照选项 File -> New -> Project,最后从向导列表中选择 Java Project 向导。现在,使用向导窗口将你的项目命名为 HelloSpring,如下所示:
一旦你的项目创建成功后,将在 Project Explorer 看到下面的内容:
第 2 步:添加必需的库
第二步让我们添加 Spring 框架和通用的日志 API 库到我们的项目中。为了做到这个,在你的项目名称 HelloSpring 上单击右键,然后在快捷菜单上按照下面可用的选项:Build Path -> Configure Build Path 显示 Java 构建路径窗口,如下所示:
现在,在 Libraries 标签中使用可用的 Add External JARs 按钮,添加从 Spring 框架和通用日志安装目录下面的核心 JAR 文件:
  • commons-logging-1.1.1
  • spring-aop-4.1.6.RELEASE
  • spring-aspects-4.1.6.RELEASE
  • spring-beans-4.1.6.RELEASE
  • spring-context-4.1.6.RELEASE
  • spring-context-support-4.1.6.RELEASE
  • spring-core-4.1.6.RELEASE
  • spring-expression-4.1.6.RELEASE
  • spring-instrument-4.1.6.RELEASE
  • spring-instrument-tomcat-4.1.6.RELEASE
  • spring-jdbc-4.1.6.RELEASE
  • spring-jms-4.1.6.RELEASE
  • spring-messaging-4.1.6.RELEASE
  • spring-orm-4.1.6.RELEASE
  • spring-oxm-4.1.6.RELEASE
  • spring-test-4.1.6.RELEASE
  • spring-tx-4.1.6.RELEASE
  • spring-web-4.1.6.RELEASE
  • spring-webmvc-4.1.6.RELEASE
  • spring-webmvc-portlet-4.1.6.RELEASE
  • spring-websocket-4.1.6.RELEASE
第 3 步:创建源文件
现在让我们在 HelloSpring 项目下创建实际的源文件。首先,我们需要创建一个名为 com.tutorialspoint 的包。为了做到这个,在 package explore 区域中的 src 上点击右键,并按照选项:New -> Package
接下来,我们在包 com.tutorialspoint 下创建 HelloWorld.javaMainApp.java 文件。
这里是 HelloWorld.java 文件的内容:
  1. package com.tutorialspoint;
  2. public class HelloWorld {
  3.    private String message;
  4.    public void setMessage(String message){
  5.       this.message  = message;
  6.    }
  7.    public void getMessage(){
  8.       System.out.println("Your Message : " + message);
  9.    }
  10. }
复制代码
下面是第二个文件 MainApp.java 的内容:
  1. package com.tutorialspoint;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class MainApp {
  5.    public static void main(String[] args) {
  6.       ApplicationContext context =
  7.              new ClassPathXmlApplicationContext("Beans.xml");
  8.       HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
  9.       obj.getMessage();
  10.    }
  11. }
复制代码
关于主要程序有以下两个要点需要注意:
  • 第一步是我们使用框架 API ClassPathXmlApplicationContext() 来创建应用程序的上下文。这个 API 加载 beans 的配置文件并最终基于所提供的 API,它处理创建并初始化所有的对象,即在配置文件中提到的 beans。
  • 第二步是使用已创建的上下文的 getBean() 方法来获得所需的 bean。这个方法使用 bean 的 ID 返回一个最终可以转换为实际对象的通用对象。一旦有了对象,你就可以使用这个对象调用任何类的方法。
第 4 步:创建 bean 的配置文件
你需要创建一个 Bean 的配置文件,该文件是一个 XML 文件,并且作为粘合 bean 的粘合剂即类。这个文件需要在 src 目录下创建,如下图所示:
通常开发人员保存该文件的名称为 Beans.xml 文件,但是你可以单独选择你喜欢的任何名称。你必须确保这个文件在 CLASSPATH 中是可用的,并在主应用程序中使用相同的名称,而在 MainApp.java 文件中创建应用程序的上下文,如图所示。
Beans.xml 用于给不同的 bean 分配唯一的 ID,并且控制不同值的对象的创建,而不会影响 Spring 的任何源文件。例如,使用下面的文件,你可以为 “message” 变量传递任何值,因此你就可以输出信息的不同值,而不会影响的 HelloWorld.java和MainApp.java 文件。让我们来看看它是如何工作的:

  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans
  5.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  6.    <bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
  7.        <property name="message" value="Hello World!"/>
  8.    </bean>

  9. </beans>
复制代码
当 Spring 应用程序被加载到内存中时,框架利用了上面的配置文件来创建所有已经定义的 beans,并且按照 标签的定义为它们分配一个唯一的 ID。你可以使用 标签来传递在创建对象时使用不同变量的值。
第 5 步:运行程序
一旦你完成了创建源代码和 bean 的配置文件后,准备好下一步编译和运行你的程序。为了做到这个,请保持 MainApp.Java 文件标签是有效的,并且在 Eclipse IDE 中使用可用的 Run 选项,或使用 Ctrl + F11 编译并运行你的应用程序 MainApp。如果你的应用程序一切都正常,将在 Eclipse IDE 控制台打印以下信息:
Your Message : Hello World!
祝贺,你已经成功地创建了你的第一个 Spring 应用程序。通过更改 “message” 属性的值并且保持两个源文件不变,你可以看到上述 Spring 应用程序的灵活性。下一步,我们开始在接下来的几个章节中做一些更有趣的事情。
https://www.w3cschool.cn/wkspring/dgte1ica.html


回复 支持 反对

使用道具 举报

697

主题

1142

帖子

4086

积分

认证用户组

Rank: 5Rank: 5

积分
4086
 楼主| 发表于 2017-6-22 11:21:07 | 显示全部楼层
Spring IoC 容器IoC 容器
Spring 容器是 Spring 框架的核心。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。Spring 容器使用依赖注入(DI)来管理组成一个应用程序的组件。这些对象被称为 Spring Beans,我们将在下一章中进行讨论。
通过阅读配置元数据提供的指令,容器知道对哪些对象进行实例化,配置和组装。配置元数据可以通过 XML,Java 注释或 Java 代码来表示。下图是 Spring 如何工作的高级视图。 Spring IoC 容器利用 Java 的 POJO 类和配置元数据来生成完全配置和可执行的系统或应用程序。
Spring 提供了以下两种不同类型的容器。
序号容器 & 描述
1Spring BeanFactory 容器
它是最简单的容器,给 DI 提供了基本的支持,它用 org.springframework.beans.factory.BeanFactory 接口来定义。BeanFactory 或者相关的接口,如 BeanFactoryAware,InitializingBean,DisposableBean,在 Spring 中仍然存在具有大量的与 Spring 整合的第三方框架的反向兼容性的目的。
2Spring ApplicationContext 容器
该容器添加了更多的企业特定的功能,例如从一个属性文件中解析文本信息的能力,发布应用程序事件给感兴趣的事件监听器的能力。该容器是由 org.springframework.context.ApplicationContext 接口定义。
ApplicationContext 容器包括 BeanFactory 容器的所有功能,所以通常建议超过 BeanFactory。BeanFactory 仍然可以用于轻量级的应用程序,如移动设备或基于 applet 的应用程序,其中它的数据量和速度是显著。
https://www.w3cschool.cn/wkspring/f8pc1hae.html


回复 支持 反对

使用道具 举报

697

主题

1142

帖子

4086

积分

认证用户组

Rank: 5Rank: 5

积分
4086
 楼主| 发表于 2017-6-22 15:32:15 | 显示全部楼层
Spring BeanFactory 容器Sping 的 BeanFactory 容器
这是一个最简单的容器,它主要的功能是为依赖注入 (DI) 提供支持,这个容器接口在 org.springframework.beans.factory.BeanFactor 中被定义。 BeanFactory 和相关的接口,比如,BeanFactoryAware、 DisposableBean、InitializingBean,仍旧保留在 Spring 中,主要目的是向后兼容已经存在的和那些 Spring 整合在一起的第三方框架。
在 Spring 中,有大量对 BeanFactory 接口的实现。其中,最常被使用的是 XmlBeanFactory 类。这个容器从一个 XML 文件中读取配置元数据,由这些元数据来生成一个被配置化的系统或者应用。
在资源宝贵的移动设备或者基于 applet 的应用当中, BeanFactory 会被优先选择。否则,一般使用的是 ApplicationContext,除非你有更好的理由选择 BeanFactory。



Spring ApplicationContext 容器
Application Context 是 spring 中较高级的容器。和 BeanFactory 类似,它可以加载配置文件中定义的 bean,将所有的 bean 集中在一起,当有请求的时候分配 bean。 另外,它增加了企业所需要的功能,比如,从属性文件从解析文本信息和将事件传递给所指定的监听器。这个容器在 org.springframework.context.ApplicationContext interface 接口中定义。
ApplicationContext 包含 BeanFactory 所有的功能,一般情况下,相对于 BeanFactory,ApplicationContext 会被推荐使用。BeanFactory 仍然可以在轻量级应用中使用,比如移动设备或者基于 applet 的应用程序。
最常被使用的 ApplicationContext 接口实现:
  • FileSystemXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器 XML 文件的完整路径
  • ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你不需要提供 XML 文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,因为,容器会从 CLASSPATH 中搜索 bean 配置文件。
  • WebXmlApplicationContext:该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。
我们已经在 Spring Hello World Example章节中看到过 ClassPathXmlApplicationContext 容器,并且,在基于 spring 的 web 应用程序这个独立的章节中,我们讨论了很多关于 XmlWebApplicationContext。所以,接下来,让我们看一个关于 FileSystemXmlApplicationContext 的例子。


注意 MainApp.java 内容的不同:
  1. package com.tutorialspoint;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.FileSystemXmlApplicationContext;
  4. public class MainApp {
  5.    public static void main(String[] args) {
  6.       ApplicationContext context = new FileSystemXmlApplicationContext
  7.             ("C:/Users/ZARA/workspace/HelloSpring/src/Beans.xml");
  8.       HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
  9.       obj.getMessage();
  10.    }
  11. }
复制代码


在主程序当中,我们需要注意以下两点:
  • 第一步生成工厂对象。加载完指定路径下 bean 配置文件后,利用框架提供的 FileSystemXmlApplicationContext API 去生成工厂 bean。FileSystemXmlApplicationContext 负责生成和初始化所有的对象,比如,所有在 XML bean 配置文件中的 bean。
  • 第二步利用第一步生成的上下文中的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean ID 来返回一个真正的对象。一旦得到这个对象,就可以利用这个对象来调用任何方法。
回复 支持 反对

使用道具 举报

697

主题

1142

帖子

4086

积分

认证用户组

Rank: 5Rank: 5

积分
4086
 楼主| 发表于 2017-6-22 15:40:29 | 显示全部楼层
本帖最后由 java 于 2017-6-22 16:19 编辑

Spring Bean 定义Bean 定义
被称作 bean 的对象是构成应用程序的支柱也是由 Spring IoC 容器管理的。bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。这些 bean 是由用容器提供的配置元数据创建的,例如,已经在先前章节看到的,在 XML 的表单中的 定义。
bean 定义包含称为配置元数据的信息,下述容器也需要知道配置元数据:
  • 如何创建一个 bean
  • bean 的生命周期的详细信息
  • bean 的依赖关系
上述所有的配置元数据转换成一组构成每个 bean 定义的下列属性。
属性描述
class这个属性是强制性的,并且指定用来创建 bean 的 bean 类。
name这个属性指定唯一的 bean 标识符。在基于 XML 的配置元数据中,你可以使用 ID 和/或 name 属性来指定 bean 标识符。
scope这个属性指定由特定的 bean 定义创建的对象的作用域,它将会在 bean 作用域的章节中进行讨论。
constructor-arg它是用来注入依赖关系的,并会在接下来的章节中进行讨论。
properties它是用来注入依赖关系的,并会在接下来的章节中进行讨论。
autowiring mode它是用来注入依赖关系的,并会在接下来的章节中进行讨论。
lazy-initialization mode延迟初始化的 bean 告诉 IoC 容器在它第一次被请求时,而不是在启动时去创建一个 bean 实例。
initialization 方法在 bean 的所有必需的属性被容器设置之后,调用回调方法。它将会在 bean 的生命周期章节中进行讨论。
destruction 方法当包含该 bean 的容器被销毁时,使用回调方法。它将会在 bean 的生命周期章节中进行讨论。
Spring 配置元数据
Spring IoC 容器完全由实际编写的配置元数据的格式解耦。有下面三个重要的方法把配置元数据提供给 Spring 容器:
  • 基于 XML 的配置文件。
  • 基于注解的配置
  • 基于 Java 的配置
你已经看到了如何把基于 XML 的配置元数据提供给容器,但是让我们看看另一个基于 XML 配置文件的例子,这个配置文件中有不同的 bean 定义,包括延迟初始化,初始化方法和销毁方法的:
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans
  5.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  6.    <!-- A simple bean definition -->
  7.    <bean id="..." class="...">
  8.        <!-- collaborators and configuration for this bean go here -->
  9.    </bean>

  10.    <!-- A bean definition with lazy init set on -->
  11.    <bean id="..." class="..." lazy-init="true">
  12.        <!-- collaborators and configuration for this bean go here -->
  13.    </bean>

  14.    <!-- A bean definition with initialization method -->
  15.    <bean id="..." class="..." init-method="...">
  16.        <!-- collaborators and configuration for this bean go here -->
  17.    </bean>

  18.    <!-- A bean definition with destruction method -->
  19.    <bean id="..." class="..." destroy-method="...">
  20.        <!-- collaborators and configuration for this bean go here -->
  21.    </bean>

  22.    <!-- more bean definitions go here -->

  23. </beans>
复制代码


Spring Bean 作用域Bean 的作用域
当在 Spring 中定义一个 时,你必须声明该 bean 的作用域的选项。例如,为了强制 Spring 在每次需要时都产生一个新的 bean 实例,你应该声明 bean 的作用域的属性为 prototype。同理,如果你想让 Spring 在每次需要时都返回同一个bean实例,你应该声明 bean 的作用域的属性为 singleton
Spring 框架支持以下五个作用域,如果你使用 web-aware ApplicationContext 时,其中三个是可用的。
作用域描述
singleton该作用域将 bean 的定义的限制在每一个 Spring IoC 容器中的一个单一实例(默认)。
prototype该作用域将单一 bean 的定义限制在任意数量的对象实例。
request该作用域将 bean 的定义限制为 HTTP 请求。只在 web-aware Spring ApplicationContext 的上下文中有效。
session该作用域将 bean 的定义限制为 HTTP 会话。 只在web-aware Spring ApplicationContext的上下文中有效。
global-session该作用域将 bean 的定义限制为全局 HTTP 会话。只在 web-aware Spring ApplicationContext 的上下文中有效。
本章将讨论前两个范围,当我们将讨论有关 web-aware Spring ApplicationContext 时,其余三个将被讨论。
singleton 作用域:
如果作用域设置为 singleton,那么 Spring IoC 容器刚好创建一个由该 bean 定义的对象的实例。该单一实例将存储在这种单例 bean 的高速缓存中,以及针对该 bean 的所有后续的请求和引用都返回缓存对象。
默认作用域是始终是 singleton,但是当仅仅需要 bean 的一个实例时,你可以在 bean 的配置文件中设置作用域的属性为 singleton,如下所示:
  1. <!-- A bean definition with singleton scope -->
  2. <bean id="..." class="..." scope="singleton">
  3.     <!-- collaborators and configuration for this bean go here -->
  4. </bean>
复制代码
prototype 作用域
如果作用域设置为 prototype,那么每次特定的 bean 发出请求时 Spring IoC 容器就创建对象的新的 Bean 实例。一般说来,满状态的 bean 使用 prototype 作用域和没有状态的 bean 使用 singleton 作用域。
为了定义 prototype 作用域,你可以在 bean 的配置文件中设置作用域的属性为 prototype,如下所示:
  1. <!-- A bean definition with singleton scope -->
  2. <bean id="..." class="..." scope="prototype">
  3.    <!-- collaborators and configuration for this bean go here -->
  4. </bean>
复制代码
https://www.w3cschool.cn/wkspring/nukv1ice.html



Spring Bean 生命周期
Bean 的生命周期
理解 Spring bean 的生命周期很容易。当一个 bean 被实例化时,它可能需要执行一些初始化使它转换成可用状态。同样,当 bean 不再需要,并且从容器中移除时,可能需要做一些清除工作。
尽管还有一些在 Bean 实例化和销毁之间发生的活动,但是本章将只讨论两个重要的生命周期回调方法,它们在 bean 的初始化和销毁的时候是必需的。
为了定义安装和拆卸一个 bean,我们只要声明带有 init-method 和/或 destroy-method 参数的 。init-method 属性指定一个方法,在实例化 bean 时,立即调用该方法。同样,destroy-method 指定一个方法,只有从容器中移除 bean 之后,才能调用该方法。
初始化回调
org.springframework.beans.factory.InitializingBean 接口指定一个单一的方法:
  1. void afterPropertiesSet() throws Exception;
复制代码
因此,你可以简单地实现上述接口和初始化工作可以在 afterPropertiesSet() 方法中执行,如下所示:
  1. public class ExampleBean implements InitializingBean {
  2.    public void afterPropertiesSet() {
  3.       // do some initialization work
  4.    }
  5. }
复制代码
在基于 XML 的配置元数据的情况下,你可以使用 init-method 属性来指定带有 void 无参数方法的名称。例如:
  1. <bean id="exampleBean"
  2.          class="examples.ExampleBean" init-method="init"/>
复制代码
下面是类的定义:
  1. public class ExampleBean {
  2.    public void init() {
  3.       // do some initialization work
  4.    }
  5. }
复制代码
销毁回调

org.springframework.beans.factory.DisposableBean 接口指定一个单一的方法:
void destroy() throws Exception;
因此,你可以简单地实现上述接口并且结束工作可以在 destroy() 方法中执行,如下所示:
public class ExampleBean implements DisposableBean {
   public void destroy() {
      // do some destruction work
   }
}
在基于 XML 的配置元数据的情况下,你可以使用 destroy-method 属性来指定带有 void 无参数方法的名称。例如:
<bean id="exampleBean"
         class="examples.ExampleBean" destroy-method="destroy"/>
下面是类的定义:
public class ExampleBean {
   public void destroy() {
      // do some destruction work
   }
}
如果你在非 web 应用程序环境中使用 Spring 的 IoC 容器;例如在丰富的客户端桌面环境中;那么在 JVM 中你要注册关闭 hook。这样做可以确保正常关闭,为了让所有的资源都被释放,可以在单个 beans 上调用 destroy 方法。
建议你不要使用 InitializingBean 或者 DisposableBean 的回调方法,因为 XML 配置在命名方法上提供了极大的灵活性。

回复 支持 反对

使用道具 举报

697

主题

1142

帖子

4086

积分

认证用户组

Rank: 5Rank: 5

积分
4086
 楼主| 发表于 2017-6-22 16:38:38 | 显示全部楼层
本帖最后由 java 于 2017-6-22 16:43 编辑

Spring Bean 后置处理器Spring——Bean 后置处理器
BeanPostProcessor 接口定义回调方法,你可以实现该方法来提供自己的实例化逻辑,依赖解析逻辑等。你也可以在 Spring 容器通过插入一个或多个 BeanPostProcessor 的实现来完成实例化,配置和初始化一个bean之后实现一些自定义逻辑回调方法。
你可以配置多个 BeanPostProcesso r接口,通过设置 BeanPostProcessor 实现的 Ordered 接口提供的 order 属性来控制这些 BeanPostProcessor 接口的执行顺序。
BeanPostProcessor 可以对 bean(或对象)实例进行操作,这意味着 Spring IoC 容器实例化一个 bean 实例,然后 BeanPostProcessor 接口进行它们的工作。
ApplicationContext 会自动检测由 BeanPostProcessor 接口的实现定义的 bean,注册这些 bean 为后置处理器,然后通过在容器中创建 bean,在适当的时候调用它。
例子:
下面的例子显示如何在 ApplicationContext 的上下文中编写,注册和使用 BeanPostProcessor。
我们在适当的位置使用 Eclipse IDE,然后按照下面的步骤来创建一个 Spring 应用程序:
步骤描述
1创建一个名称为 SpringExample 的项目,并且在创建项目的 src 文件夹中创建一个包 com.tutorialspoint
2使用 Add External JARs 选项,添加所需的 Spring 库,解释见 Spring Hello World Example 章节。
3com.tutorialspoint 包中创建 Java 类 HelloWorldInitHelloWorldMainApp
4src 文件夹中创建 Beans 配置文件 Beans.xml
5最后一步是创建的所有 Java 文件和 Bean 配置文件的内容,并运行应用程序,解释如下所示。
这里是 HelloWorld.java 文件的内容:
  1. package com.tutorialspoint;
  2. public class HelloWorld {
  3.    private String message;
  4.    public void setMessage(String message){
  5.       this.message  = message;
  6.    }
  7.    public void getMessage(){
  8.       System.out.println("Your Message : " + message);
  9.    }
  10.    public void init(){
  11.       System.out.println("Bean is going through init.");
  12.    }
  13.    public void destroy(){
  14.       System.out.println("Bean will destroy now.");
  15.    }
  16. }
复制代码


这是实现 BeanPostProcessor 的非常简单的例子,它在任何 bean 的初始化的之前和之后输入该 bean 的名称。你可以在初始化 bean 的之前和之后实现更复杂的逻辑,因为你有两个访问内置 bean 对象的后置处理程序的方法。
这里是 InitHelloWorld.java 文件的内容:
  1. package com.tutorialspoint;
  2. import org.springframework.beans.factory.config.BeanPostProcessor;
  3. import org.springframework.beans.BeansException;
  4. public class InitHelloWorld implements BeanPostProcessor {
  5.    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  6.       System.out.println("BeforeInitialization : " + beanName);
  7.       return bean;  // you can return any other object as well
  8.    }
  9.    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  10.       System.out.println("AfterInitialization : " + beanName);
  11.       return bean;  // you can return any other object as well
  12.    }
  13. }
复制代码
下面是 MainApp.java 文件的内容。在这里,你需要注册一个在 AbstractApplicationContext 类中声明的关闭 hook 的 registerShutdownHook() 方法。它将确保正常关闭,并且调用相关的 destroy 方法。
  1. package com.tutorialspoint;
  2. import org.springframework.context.support.AbstractApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class MainApp {
  5.    public static void main(String[] args) {
  6.       AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
  7.       HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
  8.       obj.getMessage();
  9.       context.registerShutdownHook();
  10.    }
  11. }
复制代码
下面是 init 和 destroy 方法需要的配置文件 Beans.xml 文件:
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans
  5.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  6.    <bean id="helloWorld" class="com.tutorialspoint.HelloWorld"
  7.        init-method="init" destroy-method="destroy">
  8.        <property name="message" value="Hello World!"/>
  9.    </bean>

  10.    <bean class="com.tutorialspoint.InitHelloWorld" />

  11. </beans>
复制代码
一旦你创建源代码和 bean 配置文件完成后,我们就可以运行该应用程序。如果你的应用程序一切都正常,将输出以下信息:
  1. BeforeInitialization : helloWorld
  2. Bean is going through init.
  3. AfterInitialization : helloWorld
  4. Your Message : Hello World!
  5. Bean will destroy now.
复制代码
https://www.w3cschool.cn/wkspring/xs181ici.html

回复 支持 反对

使用道具 举报

697

主题

1142

帖子

4086

积分

认证用户组

Rank: 5Rank: 5

积分
4086
 楼主| 发表于 2017-6-22 16:50:39 | 显示全部楼层
Spring Bean 定义继承Bean 定义继承https://www.w3cschool.cn/wkspring/tydj1ick.html
bean 定义可以包含很多的配置信息,包括构造函数的参数,属性值,容器的具体信息例如初始化方法,静态工厂方法名,等等。
子 bean 的定义继承父定义的配置数据。子定义可以根据需要重写一些值,或者添加其他值。
Spring Bean 定义的继承与 Java 类的继承无关,但是继承的概念是一样的。你可以定义一个父 bean 的定义作为模板和其他子 bean 就可以从父 bean 中继承所需的配置。
当你使用基于 XML 的配置元数据时,通过使用父属性,指定父 bean 作为该属性的值来表明子 bean 的定义。
例子
我们在适当的位置使用 Eclipse IDE,然后按照下面的步骤来创建一个 Spring 应用程序:
步骤描述
1创建一个名称为 SpringExample 的项目,并且在创建项目的 src 文件夹中创建一个包 com.tutorialspoint
2使用 Add External JARs 选项,添加所需的 Spring 库,解释见 Spring Hello World Example 章节。
3com.tutorialspoint 包中创建 Java 类 HelloWorldHelloIndiaMainApp
4src 文件夹中创建 Beans 配置文件 Beans.xml
5最后一步是创建的所有 Java 文件和 Bean 配置文件的内容,并运行应用程序,解释如下所示。
下面是配置文件 Beans.xml,在该配置文件中我们定义有两个属性 message1message2 的 “helloWorld” bean。然后,使用 parent 属性把 “helloIndia” bean 定义为 “helloWorld” bean 的孩子。这个子 bean 继承 message2 的属性,重写 message1 的属性,并且引入一个属性 message3
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans

   <bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
      <property name="message1" value="Hello World!"/>
      <property name="message2" value="Hello Second World!"/>
   </bean>

   <bean id="helloIndia" class="com.tutorialspoint.HelloIndia" parent="helloWorld">
      <property name="message1" value="Hello India!"/>
      <property name="message3" value="Namaste India!"/>
   </bean>

</beans>
这里是 HelloWorld.java 文件的内容:
package com.tutorialspoint;
public class HelloWorld {
   private String message1;
   private String message2;
   public void setMessage1(String message){
      this.message1  = message;
   }
   public void setMessage2(String message){
      this.message2  = message;
   }
   public void getMessage1(){
      System.out.println("World Message1 : " + message1);
   }
   public void getMessage2(){
      System.out.println("World Message2 : " + message2);
   }
}
这里是 HelloIndia.java 文件的内容:
package com.tutorialspoint;

public class HelloIndia {
   private String message1;
   private String message2;
   private String message3;

   public void setMessage1(String message){
      this.message1  = message;
   }

   public void setMessage2(String message){
      this.message2  = message;
   }

   public void setMessage3(String message){
      this.message3  = message;
   }

   public void getMessage1(){
      System.out.println("India Message1 : " + message1);
   }

   public void getMessage2(){
      System.out.println("India Message2 : " + message2);
   }

   public void getMessage3(){
      System.out.println("India Message3 : " + message3);
   }
}
下面是 MainApp.java 文件的内容:
package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld objA = (HelloWorld) context.getBean("helloWorld");

      objA.getMessage1();
      objA.getMessage2();

      HelloIndia objB = (HelloIndia) context.getBean("helloIndia");
      objB.getMessage1();
      objB.getMessage2();
      objB.getMessage3();
   }
}
一旦你创建源代码和 bean 配置文件完成后,我们就可以运行该应用程序。如果你的应用程序一切都正常,将输出以下信息:
World Message1 : Hello World!
World Message2 : Hello Second World!
India Message1 : Hello India!
India Message2 : Hello Second World!
India Message3 : Namaste India!
在这里你可以观察到,我们创建 “helloIndia” bean 的同时并没有传递 message2,但是由于 Bean 定义的继承,所以它传递了 message2。
Bean 定义模板

你可以创建一个 Bean 定义模板,不需要花太多功夫它就可以被其他子 bean 定义使用。在定义一个 Bean 定义模板时,你不应该指定类的属性,而应该指定带 true 值的抽象属性,如下所示:
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans

   <bean id="beanTeamplate" abstract="true">
      <property name="message1" value="Hello World!"/>
      <property name="message2" value="Hello Second World!"/>
      <property name="message3" value="Namaste India!"/>
   </bean>

   <bean id="helloIndia" class="com.tutorialspoint.HelloIndia" parent="beanTeamplate">
      <property name="message1" value="Hello India!"/>
      <property name="message3" value="Namaste India!"/>
   </bean>

</beans>
父 bean 自身不能被实例化,因为它是不完整的,而且它也被明确地标记为抽象的。当一个定义是抽象的,它仅仅作为一个纯粹的模板 bean 定义来使用的,充当子定义的父定义使用。



回复 支持 反对

使用道具 举报

697

主题

1142

帖子

4086

积分

认证用户组

Rank: 5Rank: 5

积分
4086
 楼主| 发表于 2017-6-22 17:12:18 | 显示全部楼层
本帖最后由 java 于 2017-6-22 17:29 编辑

Spring 依赖注入依赖注入

每个基于应用程序的 java 都有几个对象,这些对象一起工作来呈现出终端用户所看到的工作的应用程序。当编写一个复杂的 Java 应用程序时,应用程序类应该尽可能独立于其他 Java 类来增加这些类重用的可能性,并且在做单元测试时,测试独立于其他类的独立性。依赖注入(或有时称为布线)有助于把这些类粘合在一起,同时保持他们独立。
假设你有一个包含文本编辑器组件的应用程序,并且你想要提供拼写检查。标准代码看起来是这样的:
public class TextEditor {
   private SpellChecker spellChecker;  
   public TextEditor() {
      spellChecker = new SpellChecker();
   }
}

在这里,TextEditor 不应该担心 SpellChecker 的实现。SpellChecker 将会独立实现,并且在 TextEditor 实例化的时候将提供给 TextEditor,整个过程是由 Spring 框架的控制。
在这里,我们已经从 TextEditor 中删除了全面控制,并且把它保存到其他地方(即 XML 配置文件),且依赖关系(即 SpellChecker 类)通过类构造函数被注入到 TextEditor 类中。因此,控制流通过依赖注入(DI)已经“反转”,因为你已经有效地委托依赖关系到一些外部系统。
依赖注入的第二种方法是通过 TextEditor 类的 Setter 方法,我们将创建 SpellChecker 实例,该实例将被用于调用 setter 方法来初始化 TextEditor 的属性。
因此,DI 主要有两种变体和下面的两个子章将结合实例涵盖它们:
序号依赖注入类型 & 描述
1Constructor-based dependency injection
当容器调用带有多个参数的构造函数类时,实现基于构造函数的 DI,每个代表在其他类中的一个依赖关系。
2Setter-based dependency injection
基于 setter 方法的 DI 是通过在调用无参数的构造函数或无参数的静态工厂方法实例化 bean 之后容器调用 beans 的 setter 方法来实现的。
你可以混合这两种方法,基于构造函数和基于 setter 方法的 DI,然而使用有强制性依存关系的构造函数和有可选依赖关系的 sette r是一个好的做法。
代码是 DI 原理的清洗机,当对象与它们的依赖关系被提供时,解耦效果更明显。对象不查找它的依赖关系,也不知道依赖关系的位置或类,而这一切都由 Spring 框架控制的。

Spring 基于构造函数的依赖注入
当容器调用带有一组参数的类构造函数时,基于构造函数的 DI 就完成了,其中每个参数代表一个对其他类的依赖。


<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
    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">


   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.tutorialspoint.TextEditor">
      <constructor-arg ref="spellChecker"/>
   </bean>


   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
   </bean>


</beans>



构造函数参数解析:
如果存在不止一个参数时,当把参数传递给构造函数时,可能会存在歧义。要解决这个问题,那么构造函数的参数在 bean 定义中的顺序就是把这些参数提供给适当的构造函数的顺序就可以了。
<beans>
   <bean id="foo" class="x.y.Foo">
      <constructor-arg ref="bar"/>
      <constructor-arg ref="baz"/>
   </bean>

   <bean id="bar" class="x.y.Bar"/>
   <bean id="baz" class="x.y.Baz"/>
</beans>

如果你使用 type 属性显式的指定了构造函数参数的类型,容器也可以使用与简单类型匹配的类型
<beans>

   <bean id="exampleBean" class="examples.ExampleBean">
      <constructor-arg type="int" value="2001"/>
      <constructor-arg type="java.lang.String" value="Zara"/>
   </bean>


</beans>
最后并且也是最好的传递构造函数参数的方式,使用 index 属性来显式的指定构造函数参数的索引。下面是基于索引为 0 的例子,如下所示:
<beans>

   <bean id="exampleBean" class="examples.ExampleBean">
      <constructor-arg index="0" value="2001"/>
      <constructor-arg index="1" value="Zara"/>
   </bean>


</beans>

最后,如果你想要向一个对象传递一个引用,你需要使用 标签的 ref 属性,如果你想要直接传递值,那么你应该使用如上所示的 value 属性。


Spring 注入内部 Beans
Spring 基于设值函数的依赖注入当容器调用一个无参的构造函数或一个无参的静态 factory 方法来初始化你的 bean 后,通过容器在你的 bean 上调用设值函数,基于设值函数的 DI 就完成了。
<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
    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">


   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.tutorialspoint.TextEditor">
      <property name="spellChecker" ref="spellChecker"/>
   </bean>


   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
   </bean>


</beans>



使用 p-namespace 实现 XML 配置:
如果你有许多的设值函数方法,那么在 XML 配置文件中使用 p-namespace 是非常方便的。让我们查看一下区别:
以带有 标签的标准 XML 配置文件为例:
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans
  5.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  6.    <bean id="john-classic" class="com.example.Person">
  7.       <property name="name" value="John Doe"/>
  8.       <property name="spouse" ref="jane"/>
  9.    </bean>

  10.    <bean name="jane" class="com.example.Person">
  11.       <property name="name" value="John Doe"/>
  12.    </bean>

  13. </beans>
复制代码
上述 XML 配置文件可以使用 p-namespace 以一种更简洁的方式重写,如下所示:
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xmlns:p="http://www.springframework.org/schema/p"
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans
  6.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  7.    <bean id="john-classic" class="com.example.Person"
  8.       p:name="John Doe"
  9.       p:spouse-ref="jane"/>
  10.    </bean>

  11.    <bean name="jane" class="com.example.Person"
  12.       p:name="John Doe"/>
  13.    </bean>

  14. </beans>
复制代码


Spring 注入内部 Beans
注入内部 Beans
正如你所知道的 Java 内部类是在其他类的范围内被定义的,同理,inner beans 是在其他 bean 的范围内定义的 bean。因此在 或 元素内 元素被称为内部bean,如下所示。
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans
  5.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  6.    <bean id="outerBean" class="...">
  7.       <property name="target">
  8.          <bean id="innerBean" class="..."/>
  9.       </property>
  10.    </bean>

  11. </beans>
复制代码
下面是使用内部 bean 为基于 setter 注入进行配置的配置文件 Beans.xml 文件:
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans
  5.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  6.    <!-- Definition for textEditor bean using inner bean -->
  7.    <bean id="textEditor" class="com.tutorialspoint.TextEditor">
  8.       <property name="spellChecker">
  9.          <bean id="spellChecker" class="com.tutorialspoint.SpellChecker"/>
  10.        </property>
  11.    </bean>

  12. </beans>
复制代码

Spring 注入集合

你已经看到了如何使用 value 属性来配置基本数据类型和在你的 bean 配置文件中使用<property>标签的 ref 属性来配置对象引用。这两种情况下处理奇异值传递给一个 bean。
现在如果你想传递多个值,如 Java Collection 类型 List、Set、Map 和 Properties,应该怎么做呢。为了处理这种情况,Spring 提供了四种类型的集合的配置元素,如下所示:
元素描述
<list>它有助于连线,如注入一列值,允许重复。
<set>它有助于连线一组值,但不能重复。
<map>它可以用来注入名称-值对的集合,其中名称和值可以是任何类型。
<props>它可以用来注入名称-值对的集合,其中名称和值都是字符串类型。
你可以使用<list>或<set>来连接任何 java.util.Collection 的实现或数组。
你会遇到两种情况(a)传递集合中直接的值(b)传递一个 bean 的引用作为集合的元素。

这里是 JavaCollection.java 文件的内容:
  1. package com.tutorialspoint;
  2. import java.util.*;
  3. public class JavaCollection {
  4.    List addressList;
  5.    Set  addressSet;
  6.    Map  addressMap;
  7.    Properties addressProp;
  8.    // a setter method to set List
  9.    public void setAddressList(List addressList) {
  10.       this.addressList = addressList;
  11.    }
  12.    // prints and returns all the elements of the list.
  13.    public List getAddressList() {
  14.       System.out.println("List Elements :"  + addressList);
  15.       return addressList;
  16.    }
  17.    // a setter method to set Set
  18.    public void setAddressSet(Set addressSet) {
  19.       this.addressSet = addressSet;
  20.    }
  21.    // prints and returns all the elements of the Set.
  22.    public Set getAddressSet() {
  23.       System.out.println("Set Elements :"  + addressSet);
  24.       return addressSet;
  25.    }
  26.    // a setter method to set Map
  27.    public void setAddressMap(Map addressMap) {
  28.       this.addressMap = addressMap;
  29.    }  
  30.    // prints and returns all the elements of the Map.
  31.    public Map getAddressMap() {
  32.       System.out.println("Map Elements :"  + addressMap);
  33.       return addressMap;
  34.    }
  35.    // a setter method to set Property
  36.    public void setAddressProp(Properties addressProp) {
  37.       this.addressProp = addressProp;
  38.    }
  39.    // prints and returns all the elements of the Property.
  40.    public Properties getAddressProp() {
  41.       System.out.println("Property Elements :"  + addressProp);
  42.       return addressProp;
  43.    }
  44. }
复制代码

下面是配置所有类型的集合的配置文件 Beans.xml 文件:
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans
  5.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  6.    <!-- Definition for javaCollection -->
  7.    <bean id="javaCollection" class="com.tutorialspoint.JavaCollection">

  8.       <!-- results in a setAddressList(java.util.List) call -->
  9.       <property name="addressList">
  10.          <list>
  11.             <value>INDIA</value>
  12.             <value>Pakistan</value>
  13.             <value>USA</value>
  14.             <value>USA</value>
  15.          </list>
  16.       </property>

  17.       <!-- results in a setAddressSet(java.util.Set) call -->
  18.       <property name="addressSet">
  19.          <set>
  20.             <value>INDIA</value>
  21.             <value>Pakistan</value>
  22.             <value>USA</value>
  23.             <value>USA</value>
  24.         </set>
  25.       </property>

  26.       <!-- results in a setAddressMap(java.util.Map) call -->
  27.       <property name="addressMap">
  28.          <map>
  29.             <entry key="1" value="INDIA"/>
  30.             <entry key="2" value="Pakistan"/>
  31.             <entry key="3" value="USA"/>
  32.             <entry key="4" value="USA"/>
  33.          </map>
  34.       </property>

  35.       <!-- results in a setAddressProp(java.util.Properties) call -->
  36.       <property name="addressProp">
  37.          <props>
  38.             <prop key="one">INDIA</prop>
  39.             <prop key="two">Pakistan</prop>
  40.             <prop key="three">USA</prop>
  41.             <prop key="four">USA</prop>
  42.          </props>
  43.       </property>

  44.    </bean>

  45. </beans>
复制代码
注入 Bean 引用
下面的 Bean 定义将帮助你理解如何注入 bean 的引用作为集合的元素。甚至你可以将引用和值混合在一起,如下所示:
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans
  5.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  6.    <!-- Bean Definition to handle references and values -->
  7.    <bean id="..." class="...">

  8.       <!-- Passing bean reference  for java.util.List -->
  9.       <property name="addressList">
  10.          <list>
  11.             <ref bean="address1"/>
  12.             <ref bean="address2"/>
  13.             <value>Pakistan</value>
  14.          </list>
  15.       </property>

  16.       <!-- Passing bean reference  for java.util.Set -->
  17.       <property name="addressSet">
  18.          <set>
  19.             <ref bean="address1"/>
  20.             <ref bean="address2"/>
  21.             <value>Pakistan</value>
  22.          </set>
  23.       </property>

  24.       <!-- Passing bean reference  for java.util.Map -->
  25.       <property name="addressMap">
  26.          <map>
  27.             <entry key="one" value="INDIA"/>
  28.             <entry key ="two" value-ref="address1"/>
  29.             <entry key ="three" value-ref="address2"/>
  30.          </map>
  31.       </property>

  32.    </bean>

  33. </beans>
复制代码
为了使用上面的 bean 定义,你需要定义 setter 方法,它们应该也能够是用这种方式来处理引用。
注入 null 和空字符串的值

如果你需要传递一个空字符串作为值,那么你可以传递它,如下所示:
<bean id="..." class="exampleBean">
   <property name="email" value=""/>
</bean>
前面的例子相当于 Java 代码:exampleBean.setEmail("")。
如果你需要传递一个 NULL 值,那么你可以传递它,如下所示:
<bean id="..." class="exampleBean">
   <property name="email"><null/></property>
</bean>
前面的例子相当于 Java 代码:exampleBean.setEmail(null)。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|firemail ( 粤ICP备15085507号-1 )

GMT+8, 2024-3-29 21:25 , Processed in 0.090770 second(s), 19 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表