初识Spring框架(一)

框架简介

  1. 框架: 具有约束性的去支撑我们实现各种功能的半成品项目.
    • 简单说就是使用别人搭好的舞台,你来做表演.
    • 即框架封装了各种技术, 但缺少业务逻辑.
    • 项目 = 框架 + 业务逻辑.
  2. MVC
    • M: 模型层;  V: 视图;  C: 控制器;
    • 客户端发送一个请求
    • 控制层进行处理
    • 由模型层装载并传输数据, 并在视图层进行展示.
  3. 框架的历史
    • MVC框架
      • struct1(封装了Servlet), struct2(封装了过滤器).
      • springMVC(封装了Servlet)
    • 持久层框架
      • hibernate(自动化持久层框架)
      • mybatis(半自动化持久层框架)
    • 整合型框架
      • spring

Spring概述

  • 简介
  1. Spring为简化企业级开发而生.
  2. 使用Spring,JavaBean就可以实现很多以前要靠EJB才能实现的功能.
  3. 同样的功能,在EJB中要通过繁琐的配置和复杂的代码才能够实现,而在Spring中却非常的优雅和简洁.
  4. Spring是一个IOC(DI)和AOP容器框架.
  5. Spring的优良特性
    • 非侵入性: 该框架对原来的技术不造成影响
    • 依赖注入: DI, 是反转控制(IOC)最经典的实现
    • 面向切面编程: AOP, 是对OOP的补充.
    • 容器: Spring是一个容器, 因为包含并管理应用对象的生命周期.
    • 组件化: Spring实现了使用简单的组件配置组合成一个复杂的应用.
      • 可用XML或注解组合这些对象.
    • 一站式: IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的 第三方类库.
  • 搭建Spring环境
  1. 新建一个maven项目
  2. 导入依赖
    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.8.RELEASE</version>
        </dependency>
  3. 在Resources下创建一个Spring Config
    • applicationContext.xml
  • 案例
  1. 目标: 使用Spring创建对象, 为属性赋值
  2. 创建Person类
    public class Person {
    
        private Integer id;
        private String name;
    
        //...
    }
  3. 创建Spring配置文件: applicationContext.xml
    • 使用bean元素定义一个由IOC容器创建的对象.
    • class属性指定用于创建bean的全类名
    • id属性是该对象的唯一标识, 不能重复. 在通过类型获取bean中可以不设置.
    • scope为作用域, singleton为单例, prototype为原型.
    • property子元素为bean的属性赋值
    • name: 属性名, value:属性值
      <bean id="person" class="spring.bean.Person">
              <property name="id" value="111"></property>
              <property name="name" value="zhangsan"></property>
          </bean>
  4. 测试
    • 通过Spring的IOC容器创建Person类实例: TestBySpring.java
    • 初始化容器
      • ClassPathXmlApplicationContext("配置文件路径");
    • getBean()获取对象
      • getBean(String id): 这样获取的是Object对象.
      • getBean(类名.class): 使用此方法获取对象时, 要求spring管理的此类型的对象只能有一个.
      • getBean(id, 类名.class): 最好使用这个方法.
        public class TestBySpring {
        
            public static void main(String[] args) {
                //初始化容器
                ClassPathXmlApplicationContext cac = new ClassPathXmlApplicationContext("applicationContext.xml");
        
                //通过getBean()获取对象
                Person person = cac.getBean("person", Person.class);
                System.out.println(person);
        
                cac.close();
            }
        }
    • Spring是如何帮我们创建对象的?
      • 我们把对象以bean标签的形式写入spring的配置文件中.
      • 初始化容器时会加载配置文件并读取.
      • 用反射forName("全类名")获取class对象, 再通过newInstance()方法创建对象.

Spring配置介绍

  • IOC和DI
  1. IOC: 反转控制
    • 把原来由程序员管理对象的权利反转给程序本身, 让程序自己管理.
  2. 反转控制思想
    • 反转了资源的获取方向——改由容器主动的将资源推送给需要的组件, 开发人员不需要知道容器是如何创建资源对象的,只需要提供接收资源 的方式即可,极大的降低了学习成本,提高了开发的效率。这种行为也 称为查找的被动形式.
    • 举例: 原来自己买菜做饭, 现在点外卖(不用知道操作细节)
  3. DI: 依赖注入
    • DI是IOC的另一种表述方式, 即组件以一些预先定义好的方式(如setter) 接受来自于容器的资源注入, 相对于IOC而言, 这样更直接.
    • 依赖谁就注入谁(为谁赋值)
  4. 总结: IOC是一种反转控制思想, 而DI是它的具体实现.
  • IOC容器在Spring中的实现
  1. 前提: spring中的IOC思想需基于IOC容器完成, 而IOC容器在最底层是个对象工厂.
  2. 在通过IOC读取Bean实例前, 需先将IOC容器本身实例化.
  3. spring提供了IOC容器的两种实现方式
    • BeanFactory: 基本实现, 是spring内部的基础设施, 面向spring本身, 不提供给开发人员使用.
    • ApplicationContext: BeanFactory的子接口, 提供了更多高级特性。面向Spring的使用者.
    • 几乎所有场合都使用ApplicationContext而不是底层的BeanFactory.
  • Application的主要实现类
  1. 两个主要实现类
    • ClassPathXmlApplicationContext: 对应类路径下的xml格式的配置文件.(写相对路径)
    • FileSystemXmlApplicationContext: 加载磁盘路径下的配置文件.
  2. Application的子接口
    • ConfigurableApplicationContext
      • 包含一些扩展方法: refresh()和close()让ApplicationContext具有启动, 关闭和刷新上下文的能力.
    • WebApplicationContext
      • 专门为Web应用而准备的, 它允许从相对于web根目录的路径中完成初始化工作.
  • 给bean的属性赋值
  1. 依赖注入方式
    • set注入: 用property标签
      <bean id="person" class="Person" scope="singleton">
              <property name="id" value="222"></property>
              <property name="name" value="李四"></property>
          </bean>
      • 这里是利用setXxx()进行赋值的.
    • 构造方法注入: 用constructor-arg标签
      • constructor-arg中的参数: index(索引), name(参数名), ref(引用), type(类型), value(值)
      • 会自动匹配类中相应的构造方法.
        <bean id="person3" class="top.binwenhome.spring.bean.Person">
                <constructor-arg value="333"></constructor-arg>
                <constructor-arg value="wangwu"></constructor-arg>
            </bean>
      • 若有重载的构造方法, 用name注明参数.
        <bean id="person4" class="top.binwenhome.spring.bean.Person">
                <constructor-arg name="name" value="zhaoliu"></constructor-arg>
            </bean>
  2. p名称空间
    • 引入P名称空间后, 可在bean标签中通过p:属性进行赋值
      <bean
              id="person5" class="top.binwenhome.spring.bean.Person"
              p:id="444" p:name="xiaoming">
          </bean>
      
      IDEA中的名称空间是可以自动导入的.
  • 为属性赋值时可以使用的值
  1. 字面量
    • 能把值写成字符串方式的就叫字面量
    • 如: 所有基本类型及其包装类, String
  2. 可以直接赋null值.
  3. value只能填写字面量, 若要填其他内容, 需用ref标签
    • 引用: 用于引用当前spring管理范围内bean的id
      <bean id="teacher1" class="bean.Teacher">
              <property name="tid" value="1"></property>
              <property name="tname" value="xiaoming"></property>
          </bean>
      
          <bean id="student1" class="bean.Student">
              <property name="id" value="11"></property>
              <property name="name" value="xiaohong"></property>
              <property name="age" value="18"></property>
              <property name="sex" value="female"></property>
              <property name="teacher" ref="teacher1"></property>
          </bean>
  4. 给bean的级联属性
    <bean id="teacher1" class="bean.Teacher">
            <property name="tid" value="1"></property>
            <property name="tname" value="xiaoming"></property>
        </bean>
    
        <bean id="student1" class="bean.Student">
            <property name="id" value="11"></property>
            <property name="name" value="xiaohong"></property>
            <property name="age" value="18"></property>
            <property name="sex" value="female"></property>
            <property name="teacher" ref="teacher1"></property>
            <property name="teacher.tid" value="2"></property>
        </bean>
    
    这样, tid就从1变成了2
  5. 内部bean
    • 当bean实例仅仅给一个特定的属性使用时, 可以将其声明为内部bean.
    • 内部bean声明直接包含在<property>或<constructor-arg>元素里, 不 需要设置任何id或name属性.
      <bean id="student1" class="bean.Student">
              <property name="id" value="11"></property>
              <property name="name" value="xiaohong"></property>
              <property name="age" value="18"></property>
              <property name="sex" value="female"></property>
              <property name="teacher">
                  <bean class="bean.Teacher"
                       p:tid="3" p:tname="haha" ></bean>
              </property>
          </bean>

集合属性

  • 在spring中可以通过一组内置的xml标签来配置集合属性, 如<list>, <map>
  • 数组, list, set
  1. 配置数组内元素属性时, 需要指定<array>标签.
    • 通过<value>指定简单的常量值.
    • 通过<ref/>指定对其他Bean的引用: 使用<ref bean="id" />
    • 通过<bean>指定内置bean.
    • 通过<null/>指定空元素, 甚至可以内嵌其他集合.
  2. 配置List类型的属性: <list>, 和<array>类似
  3. 配置set类型属性: <set>, 和<array>类似
    <bean id="teacher" class="bean.Teacher">
            <property name="tid" value="102"></property>
            <property name="tname" value="xiaoming"></property>
            <property name="grades">
                <array>
                    <value>一年级</value>
                    <value>二年级</value>
                </array>
            </property>
            <property name="persons">
                <list>
                    <ref bean="person" />
                    <ref bean="person2" />
                    <ref bean="person3" />
                </list>
            </property>
        </bean>
  • Map
  1. <map>标签里可以使用多个<entry>作为子标签, 每个条目包含一个键和值.
    • 必须在<key>标签里定义键.
    • 因为键和值的类型无限制, 故可以自由地指定<value>, <ref/>, <bean>或 <null/>
      <bean id="teacher" class="bean.Teacher">
              <property name="tid" value="102"></property>
              <property name="tname" value="xiaoming"></property>
              <property name="map">
                  <map>
                      <entry>
                          <key><value>1</value></key>
                          <ref bean="person2"></ref>
                      </entry>
                      <entry>
                          <key><value>2</value></key>
                          <ref bean="person3"></ref>
                      </entry>
                  </map>
              </property>
          </bean>
  • 集合类型的bean
  1. 若只能将集合对象配置在某个bean内部, 则该集合对象的配置不能重用, 我们将 集合bean的配置拿到外面, 供其他bean引用.
  2. 需要用到util名称空间
    <bean id="teacher" class="bean.Teacher">
            <property name="tid" value="102"></property>
            <property name="tname" value="xiaoming"></property>
            <property name="persons" ref="list"></property>
            <property name="grades" ref="string"></property>
        </bean>
    
        <util:list id="string">
            <value>一年级</value>
            <value>二年级</value>
            <value>三年级</value>
        </util:list>
    
        <util:list id="list">
            <ref bean="person" />
            <ref bean="person2" />
            <ref bean="person3" />
        </util:list>

FactoryBean

  • spring中有两种类型的bean, 一种是普通bean, 另一种是工厂bean, 即 FactoryBean.

  • 工厂Bean
  1. 工厂模式就是把创建对象的过程交给工厂, 工厂创建好后交给我们.
  2. FactoryBean是个接口, 实现了该接口的类就是工厂Bean.
    • 要实现三个抽象方法
      • getObject():  获取对象
      • getObjectType():  获取对象类型
      • isSingleton():  是否为单例
  3. 举例
    • Car
      public class Car {
      
          private String brand;
          private Double price;
      }
    • MyFactory
      public class MyFactory implements FactoryBean<Car> {
          @Override
          public Car getObject() throws Exception {
              Car car = new Car("baoma", 3000000D);
              return car;
          }
      
          @Override
          public Class<?> getObjectType() {
              return Car.class;
          }
      
          @Override
          public boolean isSingleton() {
              return false;
          }
      }
    • 配置文件
      <!-- 虽然这里写的是工厂的全类名, 但实际返回的是工厂创建的对象: getObject()返回的对象 -->
          <bean id="factory" class="factory.MyFactory"></bean>
    • 测试
      Object bean = cac.getBean("factory");
      System.out.println(bean);

相关推荐