Spring框架[一]——spring概念和ioc入门(ioc操作xml配置文件)

Spring概念

  • spring是开源的轻量级框架(即不需要依赖其他东西,可用直接使用)

spring核心主要两部分

  • aop:面向切面编程,扩展功能不是修改源代码来实现;
  • ioc:控制反转,比如:有一个类,在类中有个方法(非静态的方法),要调用类中的这个方法,则需要创建类的对象,使用对象调用方法。创建类对象的过程,需要new出来对象;而ioc则是将对象的创建不是通过new方式实现,而是交给spring配置来创建对象(即,将对象的创建交给spring来管理);

spring是一站式框架

  • spring在javaee三层结构中,每一层都提供不同的解决技术
    • web层:springMVC
    • service层:spring的ioc
    • dao层:spring的jdbcTemplate

spring版本

  • hibernate5.x
  • spring4.x

Spring入门

Spring的ioc操作

  • 即:把对象的创建交给spring进行管理
  • ioc两种操作方式:
    • ioc的配置文件方式
    • ioc的注解方式

IOC底层原理

  • ioc底层原理使用的技术
    • xml配置文件
    • dome4j解析xml
    • 工厂设计模式
    • 反射
  • 画图分析ioc实现原理
     

IOC入门案例

  • 步骤:
    • 导入jar包
      • 解压下载的spring-framework-4.2.4.RELEASE.zip文件,jar包特点:都有三个jar包(基本jar、文档jar、源码jar);
      • 做spring基本功能,只需导入四个核心点jar包即可(Beans、core、Context、SpEL);
      • 导入支持日志输出的jar包-logging、log4j(因为spring本身没有提供这种jar包);
    • 创建类,在类中创建方法
      package cn.cbb.ioc;
      
      public class User {
      
          public void add() {
              System.out.println("add ...");
          }
          
          public static void main(String[] args) {
              /**
               * 调用类中的方法,原始做法是创建类对象,用对象调用方法;而现在则不再这样做了,
               * 而是将对象的创建过程交给spring来配置实现,但是底层用的肯定是反射,我们不需
               * 要写反射代码,由spring代我们做此操作
               */
              User user = new User();
              user.add();
          }
      }
    • 创建spring配置文件,配置创建类
      • spring核心配置文件名称和位置不是固定的,建议放在src下面,官方建议applicationContext.xml
      • 引入schema约束
      • 配置对象创建,配置如下:
        <?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">
        
            <!-- ioc入门,配置对象的创建 -->
            <bean id="user" class="cn.cbb.ioc.User"></bean>
        </beans>
    • 写代码测试对象创建:
      package cn.cbb.ioc;
      
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class IOCTest {
      
          @Test
          public void IOCTest() {
              //1、加载spring配置文件,根据配置创建对象
              ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
              //2、得到配置创建的对象
              User user = (User) context.getBean("user");
              System.out.println(user);
              user.add();
          }
      }

配置文件无提示问题

Spring引入schema约束,把约束文件引入到eclipse中,以便配置文件编写提示:

spring的bean管理(xml配置文件)

bean实例化三种方式

  • bean实例化,即:在spring里面通过配置文件创建对象;
  • bean实例化的三种方式实现(掌握一种,其他两种知道即可):
    • 无参构造函数创建重点🌟🌟🌟
      <!-- ioc入门,配置对象的创建 -->
      <bean id="user" class="cn.cbb.ioc.User"></bean>

      对象对应的类中,若没有无参构造(定义了有参构造),则将出现异常

      org.springframework.beans.factory.BeanCreationException:...No default constructor found;...
    • 静态工厂创建
      通过工厂创建的静态方法来返回类对象(如:IOC底层原理图析工厂类UserFactory创建的静态方法getService
      <!-- 使用静态工厂创建对象 -->
      <bean id="bean2Factory" class="cn.cbb.bean.Bean2Factory" factory-method="getBean2"></bean>
      package cn.cbb.bean;
      
      public class Bean2Factory {
      
          //静态方法返回Bean2对象
          public static Bean2 getBean2() {
              return new Bean2();
          }
      }
    • 实例工厂创建
      通过工厂的非静态方法来返回对象
      <!-- 使用实例工厂创建对象 -->
      <!-- 首先,创建工厂对象 -->
      <bean id="bean3Factory" class="cn.cbb.bean.Bean3Factory"></bean>
      <!-- 其次,通过实例化的工厂对象的方法来创建对象bean3 -->
      <bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>
      package cn.cbb.bean;
      
      public class Bean3Factory {
      
          //普通方法返回Bean3对象
          public Bean3 getBean3() {
              return new Bean3();
          }
      }

bean标签常用属性

  • id属性:命名,可任意命名。
    • id属性值,不能包含特殊符号;
    • spring是根据id值找到配置对象;
  • class属性:创建对象所在类的全路径
  • name属性:功能和id属性一致,都可以找到配置对象(主要区别:name可以包含特殊符号);现在用的较少,主要是为了整合strus1那种框架而遗留下来的一个属性。
  • scope属性:

    User user1 = (User) context.getBean("user");
    User user2 = (User) context.getBean("user");
    System.out.println(user1);
    System.out.println(user2);

    • singleton:默认值,单例
      <!-- 默认scope="singleton" -->
      <bean id="user" class="cn.cbb.ioc.User"></bean>
      cn.cbb.ioc.User@b7dd107
      cn.cbb.ioc.User@b7dd107
    • prototype:多例
      <!-- scope="prototype"测试 -->
      <bean id="user" class="cn.cbb.ioc.User" scope="prototype"></bean>
      cn.cbb.ioc.User@b7dd107
      cn.cbb.ioc.User@42eca56e

属性注入方式介绍

  • 属性注入:创建对象时,为对象的属性设置值
  • 注入方式介绍(三种)

    • 属性的setXXX方法注入
    • 有参构造注入
    • 接口注入

spring注入基本类型属性(仅支持前两种方式:有参构造和set方法)

  • set方式注入(最常用)
    <!-- 使用set方法注入属性 -->
    <bean id="book" class="cn.cbb.property.Book">
        <!-- 注入属性之:
            name属性值:类中的属性名称; value属性:设置的具体值
        -->
        <property name="bookName" value="红楼梦"></property>
    </bean>
    package cn.cbb.property;
    
    public class Book {
    
        private String bookName;
        //set方法
        public void setBookName(String bookName) {
            this.bookName = bookName;
        }
        
        public void testBook() {
            System.out.println("bookName通过set注入值为:"+bookName);
        }
    }
  • 有参构造注入
    <!-- 使用有参数构造注入属性 -->
    <bean id="propertyDemo1" class="cn.cbb.property.PropertyDemo1">
        <constructor-arg name="userName" value="小码"></constructor-arg>
    </bean>
    package cn.cbb.property;
    
    public class PropertyDemo1 {
    
        private String userName;
    
        public PropertyDemo1(String userName) {
            this.userName = userName;
        }
        
        public void test1() {
            System.out.println("userName通过有参构造注入值为:"+userName);
        }
    }

spring注入对象类型属性(重点

  • 首先,准备service类和dao类
  • 其次,要在service中得到dao对象,具体实现:
    • 在service中把dao作为类型属性
    • 生成dao类型属性的set方法
      package cn.cbb.ioc;
      
      public class UserService {
          //定义dao类型属性
          private UserDao userDao;
          //生成set方法,在service中得到dao对象,就可以调用dao中的方法
          public void setUserDao(UserDao userDao) {
              this.userDao = userDao;
          }
      
          public void add() {
              System.out.println("service add ...");
              userDao.add();
          }
      }
    • 配置文件关系
      <!-- 注入对象类型的属性 -->
      <!-- 配置service和dao对象 -->
      <bean id="userDao" class="cn.cbb.ioc.UserDao"></bean>
      <bean id="userService" class="cn.cbb.ioc.UserService">
          <!-- 注入dao对象:
              name属性值:service中的属性名称,对象类型属性就不要写value了,用ref属性:dao配置bean的id值
          -->
          <property name="userDao" ref="userDao"></property>
      </bean>

P命名空间注入(不常用,了解即可)

package cn.cbb.property;

public class Person {

    private String pname;

    public void setPname(String pname) {
        this.pname = pname;
    }
    
    public void testP() {
        System.out.println("P名称空间注入pname值为"+pname);
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p"
    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">

    <!-- P名称空间注入 -->
    <bean id="person" class="cn.cbb.property.Person" p:pname="小张"></bean>
</beans>

spring注入复杂数据

  • 数组
  • list集合
  • map集合
  • properties类型(键值对文件)
    package cn.cbb.property;
    
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    
    public class Animal {
    
        private String[] arrs;
        private List<String> list;
        private Map<String,String> map;
        private Properties properties;
        
        public void setArrs(String[] arrs) {
            this.arrs = arrs;
        }
    
        public void setList(List<String> list) {
            this.list = list;
        }
    
        public void setMap(Map<String, String> map) {
            this.map = map;
        }
    
        public void setProperties(Properties properties) {
            this.properties = properties;
        }
        
        public void testAnimal() {
            System.out.println("复杂数据注入arrs:"+arrs);
            System.out.println("复杂数据注入list:"+list);
            System.out.println("复杂数据注入map:"+map);
            System.out.println("复杂数据注入properties:"+properties);
        }
    }
    <!-- 注入复杂类型属性值 -->
    <bean id="animal" class="cn.cbb.property.Animal">
        <!-- 数组 -->
        <property name="arrs">
            <list>
                <value>小王</value>
                <value>小李</value>
                <value>小张</value>
            </list>
        </property>
        <!-- list -->
        <property name="list">
            <list>
                <value>奥迪</value>
                <value>宝马</value>
                <value>奔驰</value>
            </list>
        </property>
        <!-- map -->
        <property name="map">
            <map>
                <entry key="aa" value="lucy"></entry>
                <entry key="bb" value="lili"></entry>
                <entry key="cc" value="tom"></entry>
            </map>
        </property>
        <!-- properties -->
        <property name="properties">
            <props>
                <prop key="driverclass">com.mysql.jdbc.Driver</prop>
                <prop key="username">root</prop>
            </props>
        </property>
    </bean>

IOC和DI区别

  • IOC:控制反转,把对象的创建交给spring进行配置管理;
  • DI:依赖注入,向类中属性中设置值;
  • 关系:依赖注入不能单独存在,需要在IOC的基础之上铼完成操作。

spring整合web项目原理✨✨✨

  • 加载spring核心配置文件
    //1、加载spring配置文件,根据配置创建对象
    ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");

    new对象,功能可以实现,但是效率太低!

  • 解决思路:把加载配置文件和创建对象的过程,放在服务器启动的时候来完成。
  • 实现原理
    • ServletContext对象(服务器启动后,项目中唯一一个对象)
    • 监听器(监听ServletContext对象在什么时候创建)
    • 具体使用:
      • 在服务器启动的时候,为每个项目创建一个ServletContext对象;
      • 使用监听器监听ServletContext对象创建时间;
      • 监听到ServletContext对象创建的时候,加载spring配置文件,然后把配置文件配置的对象进行创建;
      • 把创建出来的对象放到ServletContext域对象中(setAttribute方法)
      • 获取对象时,到ServletContext域中通过getAttribute方法获取;
posted @ 2017-08-13 22:57  灰太郎^_^  阅读(2385)  评论(0编辑  收藏  举报