首页 > 代码库 > Spring框架[一]——spring概念和ioc入门(ioc操作xml配置文件)

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@b7dd107cn.cbb.ioc.User@b7dd107
    • prototype:多例
      <!-- scope="prototype"测试 --><bean id="user" class="cn.cbb.ioc.User" scope="prototype"></bean>
      cn.cbb.ioc.User@b7dd107cn.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方法获取;

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