• 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 包
    • Beans
    • Core
    • Context
    • Expression Language
    • com.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.demo
      • UserService: 接口;
      • 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 框架中的工厂

    1. ApplicationContext 接口

      • 使用该接口可以获取到具体的 Bean 对象;
      • 该接口有两个具体的实现类:
        • ClassPathXmlApplicationContext: 加载类路径下的Spring配置文件;
        • FileSystemXmlApplicationContext: 加载本地磁盘下的Spring配置文件;
    2. BeanFactory 工厂(已过时)

    public void fun(){
        BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
        UserService us = (UserService)factory.getBean("userService");
        us.sayHello();
    }
    

    4. Spring 框架中<bean>标签的配置

    1. id 属性
      • 在约束中采用ID约束,唯一;
      • 取值要求: 必须以字母开始,可以使用字母,数字,连字符,下划线,句号,冒号,但是不能出现特殊字符;
    2. name 属性
      • 可以当做 id 使用;
      • 取值要求: 可以出现特殊字符("/");
    3. class 属性: Bean 对象的全路径;
    4. scope 属性: 代表 Bean 的作用范围
      • singleton:单例(默认值);
      • prototype: 多例,在 Spring 框架整合 Struts2 框架的时候,Action 类也需要交给 Spring 做管理,
        需要把 Action 类配置成多例;
      • request: 应用在 Web 项目中,每次 HTTP 请求都会创建一个新的 Bean;
      • session: 应用在 Web 项目中,同一个 Http Session 共享一个 Bean;
      • globalsession: 应用在 Web 项目中,多服务器间的 session;
    5. Bean 对象的创建和销毁的两个属性配置
      • init-method: 当bean被载入到容器的时候,调用init-method属性指定的方法;
      • destroy-method: 当bean从容器中删除的时候,调用destroy-method属性指定的方法;

    5. 依赖注入(DI)

    1. 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 框架的配置文件分开管理

    1. 在 src 目录下又多创建了一个配置文件,现在是两个核心的配置文件,那么加载这两个配置文件的方式有两种:
    // 第一种方式
        // 在主配置文件中包含其他的配置文件
        <import resource="applicationContext2.xml"/>
    
    // 第二种方式
        // 工厂创建的时候,直接加载多个配置文件
    ApplicationContext ac =
       new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext2.xml");
    

    6. Spring 框架整合 Web(初级整合)

    6.1 创建 JavaWeb 项目,引入 Spring 的开发包,编写具体的类和方法

    • 存在问题: 每次action使用工厂创建具体的类时,都会加载一次配置文件,这样效率比较低;

    6.2 解决方案

    1. 工厂创建完成后,存入到 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();
    

    参考资料

  • 相关阅读:
    ironic port bind
    pdb /usr/bin/neutron-server
    networking_generic_switch
    [CodeForces586D]Phillip and Trains
    [CodeForces598D]Igor In the Museum
    [poj3468]A Simple Problem with Integers
    [bzoj1503][NOI2004]郁闷的出纳员
    [bzoj1208][HNOI2004]宠物收养所
    [luogu3384][模板]树链剖分
    [CodeForces869A]The Artful Expedient
  • 原文地址:https://www.cnblogs.com/linkworld/p/7718274.html
Copyright © 2020-2023  润新知