Spring 的IOC容器之XML方式
1. Spring 入门
1.1 概述
- Spring 是一个分层的 JavaEE 轻量级开源框架;
 - Spring 的核心是控制反转(IOC)和面向切面(AOP);
 
1.2 特点
- 方便解耦,简化开发;
 - AOP 编程的支持;
 - 声明式事务的支持;
 - 方便程序的测试;
 - 方便集成各种优秀框架;
 - 降低 JavaEE API的使用难度;
 
2. Spring 框架的IOC核心功能快速入门
2.1 IOC介绍
- IOC, Inverse of Control, 控制反转,将对象的创建权反转给Spring;
 - 使用IOC可以解决程序耦合性高的问题;
 


2.2 IOC 环境搭建

2.2.1 导入 jar 包
BeansCoreContextExpression Languagecom.springsource.org.apache.commons.logging-1.1.1.jar: 日志包规范com.springsource.org.apache.log4j-1.2.15.jar: 日志实现,log4j- 在 src 目录下,配置 
log4j.properties 
2.2.2 编写接口和实现类
cn.itcast.demoUserService: 接口;UserServiceImpl: 具体实现类;
2.2.3 编写配置文件
- 要想把 UserServiceImpl 实现类的创建交给 Spring 框架来管理,需要创建 Spring 框架的配置文件;
 - 在 src 目录下创建
applicationContext.xml的配置文件,名称可以任意,一般都会使用默认的名称; 
// Spring 框架的配置文件采用 schema 约束
// applicationContext.xml
<?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.xsd">
    // 配置实现类 UserServiceImpl
    <bean id="userService" class="cn.itcast.demo.UserServiceImpl"/>
</beans>
2.2.4 编写测试程序
- 采用 Spring 框架的工厂方式获取到UserService接口的具体实现类
 
public void fun(){
    // 创建工厂,配置核心配置文件
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    // 通过工厂获得对象
    // 参数 userService 对应配置文件中 id 的值
    UserService userService = (UserService)ac.getBean("userService");
    // 调用对象的方法
    userService.sayHello();
}
3. Spring 框架中的工厂
ApplicationContext 接口
- 使用该接口可以获取到具体的 Bean 对象;
 - 该接口有两个具体的实现类:
ClassPathXmlApplicationContext: 加载类路径下的Spring配置文件;FileSystemXmlApplicationContext: 加载本地磁盘下的Spring配置文件;
 
BeanFactory 工厂(已过时)
public void fun(){
    BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
    UserService us = (UserService)factory.getBean("userService");
    us.sayHello();
}
4. Spring 框架中<bean>标签的配置
- id 属性
- 在约束中采用ID约束,唯一;
 - 取值要求: 必须以字母开始,可以使用字母,数字,连字符,下划线,句号,冒号,但是不能出现特殊字符;
 
 - name 属性
- 可以当做 id 使用;
 - 取值要求: 可以出现特殊字符("/");
 
 - class 属性: Bean 对象的全路径;
 - scope 属性: 代表 Bean 的作用范围
singleton:单例(默认值);prototype: 多例,在 Spring 框架整合 Struts2 框架的时候,Action 类也需要交给 Spring 做管理,
需要把 Action 类配置成多例;request: 应用在 Web 项目中,每次 HTTP 请求都会创建一个新的 Bean;session: 应用在 Web 项目中,同一个 Http Session 共享一个 Bean;globalsession: 应用在 Web 项目中,多服务器间的 session;
 - Bean 对象的创建和销毁的两个属性配置
init-method: 当bean被载入到容器的时候,调用init-method属性指定的方法;destroy-method: 当bean从容器中删除的时候,调用destroy-method属性指定的方法;
 
5. 依赖注入(DI)
- DI: Dependency Injection,依赖注入,在 Spring 框架负责创建 Bean 对象时,动态的将依赖对象注入到 Bean 组件中.
 
// 第一种方式: 注入字符串
// UserServiceImpl.java
    public class UserServiceImpl implements UserService {
        // 成员属性,需要提供 set 方法
        private String name;
        public void setName(String name){
            this.name = name;
        }
        public viod sayHello(){
            System.out.println("hello Spring! " + name);
        }
    }
// Demo.java
    public class Demo{
        // 传统方法,给 name 赋值
        public void fun2(){
            UserServiceImpl us = new UserServiceImpl();
            us.setName("张三");
            us.sayHello();
        }
        // Spring 依赖注入
        public void fun3(){
            // 创建工厂,配置核心配置文件
            ApplicationContext ac =
                            new ClassPathXmlApplicationContext("applicationContext.xml");
            // 通过工厂获得对象
            UserService userService = (UserService)ac.getBean("userService");
            // 调用对象的方法
            userService.sayHello(); // 此时输出: hello Spring! 张三
        }
    }
// applicationContext.xml 配置文件
    <bean id="userService" class="cn.itcast.demo.UserServiceImpl">
        <property name="name" value="张三"/>
    </bean>
// 第二种情况: 注入对象
    // BookDaoImpl.java
    public class BookDaoImpl{
        public void save(){
            System.out.println("保存图书...");
        }
    }
    // BookServiceImpl.java
    public class BookServiceImpl{
        public void save(){
            new BookDaoImpl().save();
        }
    }
    // Demo.java
    public class Demo{
        public void fun(){
              // 传统 javaweb 方式, 使用 new 创建对象
            BookServiceImpl bs = new BookServiceImpl();
            bs.save();
        }
    }
    // Spring 方式
    // BookDaoImpl.java
    public class BookDaoImpl{
        public void save(){
            System.out.println("保存图书...");
        }
    }
    // BookServiceImpl.java
    public class BookServiceImpl{
        // 提供成员属性,提供 set 方法
        private BookDaoImpl bookDao;
        public void setBookDao(BookDaoImpl bookDao){
            this.bookDao = bookDao;
        }
        public void save(){
            bookDao.save();
        }
    }
    // Demo.java
    public class Demo{
        public void fun(){
            ApplicationContext ac =
                        new ClassPathXmlApplicationContext("applicactionContext.xml");
            BookServiceImpl bs = (BookServiceImpl)ac.getBean("bookService");
            bs.save();
        }
    }
    // applicationContext.xml 配置文件
    // 依赖注入
    <bean id="bookDao" class="cn.itcast.demo.BookDaoImpl"/>
    <bean id="bookService" class="cn.itcast.demo.BookServiceImpl">
        // name 表示 BookServletImpl.java 中的名称;
        // ref 表示 applicationContext.xml 配置文件中的名称;
        <property name="bookDao" ref="bookDao"/>
    </bean>
5.1 对于类成员变量,常用的两种注入方式
- 构造方法注入;
 - 属性 setter 方法注入(见上面"注入字符串");
 
// User.java
    public class User{
        private String name;
        private Integer age;
        public User(String name, Integer age){
            this.name = name;
            this.age = age;
        }
    }
// applicationContext.xml
    // 构造方法的注入方式
    <bean id="user" class="cn.itcast.demo.User">
        // 第一种传入值的方式
        <constructor-arg name="name" value="张三"/>
        <constructor-arg name="age" value="23"/>
        // 第二种传入值的方式, 使用下标
        <constructor-arg index="0" value="李四"/>
        <constructor-arg name="1" value="22"/>
    </bean>
5.2 p 名称空间的注入(了解)
// 1. 需要先引入 p 名称空间
    // 在 schema 的名称空间中加入:
    xmlns:p="http://www.springframework.org/schema/p"
// 2. 语法: p:属性名 = ""   p:属性名-ref = ""
    <bean id="customer" class="cn.itcast.demo.Customer" p:name="张三" p:linkmans-ref="linkman"/>
5.3 SpEL 注入方式(了解)
// SpEL: Spring Expression Language
//  语法: #(SpEL)
    <bean id="user" class="cn.itcast.demo.User">
        <property name="name" value="#{'张三'}"/>
        <property name="age" value="#{23}"/>
    </bean>
5.4 数组,集合(List,Set,Map),Properties等的注入
// 数组或List 集合,配置文件的编写方式一样
    <bean id="book" class="cn.itcast.demo.Book">
        <property name="arrs">
            <list>
                <value>Java 编程思想</value>
                <value>Effective Java</value>
            </list>
        </property>
    </bean>
// Set 集合,配置文件的编写方式
    <property name="sets">
        <set>
            <value>Java 编程思想</value>
            <value>Effective Java</value>
        </set>
    </property>
// Map 集合
    <property name="map">
        <map>
            <entry key="张三" value="22"/>
            <entry key="李四" value="24"/>
        </map>
    </property>
// properties 属性文件
    <property name="prop2">
        <props>
            <prop key="uname">root</prop>
            <prop key="password">root</prop>
        </props>
    </property>
5.5 Spring 框架的配置文件分开管理
- 在 src 目录下又多创建了一个配置文件,现在是两个核心的配置文件,那么加载这两个配置文件的方式有两种:
 
// 第一种方式
    // 在主配置文件中包含其他的配置文件
    <import resource="applicationContext2.xml"/>
// 第二种方式
    // 工厂创建的时候,直接加载多个配置文件
ApplicationContext ac =
   new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext2.xml");
6. Spring 框架整合 Web(初级整合)
6.1 创建 JavaWeb 项目,引入 Spring 的开发包,编写具体的类和方法
- 存在问题: 每次action使用工厂创建具体的类时,都会加载一次配置文件,这样效率比较低;
 
6.2 解决方案
- 工厂创建完成后,存入到 ServletContext 域中,使用工厂的时候,从 ServletContext 域中获得;
ServletContextListener: 用来监听ServletContext对象的创建和销毁;- 当 ServletContext 对象创建的时候,加载"applicationContext.xml"配置文件创建工厂,
并将工厂存入到 ServletContext 域中; 
 
6.3 Srping 整合 Web 项目
1. 引入 spring-web-4.3.10.RELEASE.jar包;
2. web.xml 中配置监听器
  <!-- 配置Spring的核心监听器 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
    <!-- 加载方式:默认只能加载 WEB-INF 目录下的配置文件; 自定义配置方式,加载 src 目录下配置文件 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
3. 修改 Action 类代码
// 从 ServletContext 中获得工厂
    ServletContext servletContext = ServletActionContext.getServletContext();
    WebApplicationContext ac =
            WebApplicationContextUtils.getWebApplicationContext(servletContext);
    CustomerService cs = (CustomerService)ac.getBean("customerService");
    cs.save();
参考资料
Spring 的IOC容器之XML方式的更多相关文章
- spring揭密学习笔记(3)-spring ioc容器:Spring的IoC容器之BeanFactory
		
1. Spring的IoC容器和IoC Service Provider的关系 Spring的IoC容器和IoC Service Provider所提供的服务之间存在一定的交集,二者的关系如图4-1所 ...
 - spring揭秘读书笔记----spring的ioc容器之BeanFactory
		
spring的ioc容器是一种特殊的Ioc Service Provider(ioc服务提供者),如果把普通的ioc容器认为是工厂模式(其实很相似),那spring的ioc容器只是让这个工厂的功能更强 ...
 - 【spring源码学习】Spring的IOC容器之BeanPostProcessor接口学习
		
一:含义作用 ==>BeanPostProcessor接口是众多Spring提供给开发者的bean生命周期内自定义逻辑拓展接口中的一个 二:接口定义 package org.springfram ...
 - 【spring源码学习】spring的IOC容器之BeanFactoryPostProcessor接口学习
		
[一]org.springframework.beans.factory.config.BeanFactoryPostProcessor接口==>该接口实现方法的执行时机:该接口void pos ...
 - Spring 的 Bean 管理(XML 方式)
		
Spring 的 Bean 管理(XML 方式) 1. 三种实例化 Bean 的方式 使用类构造器实例化(默认无参数) 使用静态工厂方法实例化(简单工厂模式) 使用实例工厂方法实例化(工厂方法模式) ...
 - spring与hibernate注解及XML方式集成
		
spring与hibernate注解及XML方式集成 Hibernate Xml方式 该种方式需要在sessionFactory中引入对应的hbm.xml文件,样例如下: <!-- spring ...
 - IOC容器之Autofac
		
讲到IOC容器,就必须提到DIP(依赖倒置原则). DIP是OOD(面向对象设计)的一个重要思想,在该原则上引申出了\IOC(控制反转)\DI(依赖注入)\IOC容器. 居然讲到IOC容器,当然我们要 ...
 - Spring深入浅出(三)XML方式以及注解的方式操作IOC
		
在日常的开发过程中,我们把程序分为3层:Controller层,Service层,DAO层.Controller类似于Servlet,也就是MVC中的控制层. 调用的顺序是: Controller层调 ...
 - Spring源码解析02:Spring IOC容器之XmlBeanFactory启动流程分析和源码解析
		
一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...
 
随机推荐
- 关于阿里云ECS Centos 5/6/7 Linux Glibc库严重安全漏洞修复方法
			
日前Linux GNU glibc标准库的 gethostbyname函数爆出缓冲区溢出漏洞,漏洞编号为CVE-2015-0235.黑客可以通过gethostbyname系列函数实现远程代码执行,获取 ...
 - 文件指针/句柄(FILE*)、文件描述符(fd)以及 文件路径(filepath)的相互转换(转)
			
转自: http://blog.csdn.net/jenghau/article/details/5532265 文件指针/句柄(FILE*).文件描述符(fd)以及 文件路径(filepath)的相 ...
 - Dijkstra普通算法及优先队列优化
			
#include<stdio.h> #include<iostream> #define maxv 100 #define inf 0x3fffffff using names ...
 - requireJS的匿名模块和命名模块的区别和最佳实践
			
requirejs是一个简单的javascript框架,支持模块化编码和模块的异步载入. 在requireJS中模块能够分为:匿名模块和命名模块这2种. requireJS定义一个匿名模块 defin ...
 - curl 远程下载图片
			
<?php echo httpcopy("http://www.baidu.com/img/baidu_sylogo1.gif"); function httpcopy($u ...
 - RTT第一个工程
			
第一个RTT工程 1. 配置工程 选择芯片STM32F103C8(其包含该芯片的Flash及SRAM介绍): Jlink SW模式 output->Debug info/Browse info ...
 - 【跟我一步一步学Struts2】——Struts2工作流程
			
上一篇博客通过一个简单的小样例对struts2的流程有一个简单的了解,这篇博客继续. 当用户要登陆某一个站点.输入username,password,点击登陆就会触发以下一系列过程 : 1.请求过来之 ...
 - 谈谈对MVC、MVP和MVVM的理解
			
刚出来工作的时候维护过一个老系统,该系统是用微软的ASP(Active Server Pages 动态服务器页面)写的.每一个页面都是一个ASP文件,每一个一个ASP文件中又同时包含了HTML.CSS ...
 - GridLayout 可使容器中的各个组件呈网格状布局
			
GridLayout 可使容器中的各个组件呈网格状布局,平局占据容器的空间,即使容器的大小发生变化,每个组件还是平均占据容器的空间. 和FlowLayout一样,GridLayout也是按照从上到下, ...
 - .NET开发相关使用工具和框架
			
转自: http://www.cnblogs.com/NatureSex/archive/2011/04/21/2023265.html 开发类 visual_studio 2005-2010系列-- ...