您的位置:首页 > 文旅 > 美景 > 网站安全防护方案_最新房地产新闻_定制网站开发_最有效的恶意点击软件

网站安全防护方案_最新房地产新闻_定制网站开发_最有效的恶意点击软件

2024/12/23 9:10:58 来源:https://blog.csdn.net/cgrs5572/article/details/144314858  浏览:    关键词:网站安全防护方案_最新房地产新闻_定制网站开发_最有效的恶意点击软件
网站安全防护方案_最新房地产新闻_定制网站开发_最有效的恶意点击软件

Spring简介

  • 额外知识点

    • 在之前的学习中我们在Service业务层创建Dao/Mapper数据访问层(持久层)的对象是通过工具类来获取对应Dao/Mapper数据访问层(持久层)的接口代理对象
    • 在此处我们不用工具类来获取对应Dao/Mapper数据访问层(持久层)的接口代理对象,而是创建一个Dao/Mapper数据访问层(持久层)的接口的实现类,通过创建实现类的对象进而得到接口对象以供使用
      • 讲解程序开发原理以及后续IOC和DI示例均是以此形式讲解
  • 定义

    • Spring是分层的JavaSE/EE应用full-stack轻量级开源框架,以IOC(Inversion of Control:控制反转)AOP(Aspect Oriented Programming:面向切面编程) 为内核
    • 它提供了**web/Controller表现层SpringMVC** 、Service业务层SpringDao/Mapper数据访问层(持久层)MyBatis/Spring JDBCTemplate 等众多企业级应用技术
    • 他整合开源了众多第三方框架和类库,它是使用最多的JavaEE企业级应用开源框架
  • 优点

    • 方便解耦,简化开发,降低企业级开发的复杂性
      • 通过Spring提供的IOC容器 ,可将对象间的依赖关系交由Spring进行控制,避免硬编码造成的过度耦合。
      • 用户可不必再为单例模式类、属性文件解析等这些底层的需求编写代码,可更专注于上层应用
    • 对AOP编程支持
      • 通过Spring的AOP功能,方便进行面向切面编程。许多不易用传统OOP实现的功能可以用AOP轻松实现
    • 对声明式事务的支持
      • 可将开发人员从事务管理代码中解脱出来,通过声明式的方式灵活的进行事务管理,提高开发效率和质量
    • 方便程序测试
      • 可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是可随手做的操作
    • 框架整合,集成了各种优秀框架
      • 比如:StrusHibemateHessianQuartz
    • 降低JavaEE API的使用难度
      • 它对JavaEE API(eg:JDBC、JavaMail、远程调用等)进行了封装,降低其使用难度
  • Spring有一套属于自己的开发生态圈,它提供了若干项目,每个项目对应完成特定的功能,详见官网

    在这里插入图片描述

  • 主要学习

    • Spring Framework:Spring技术基础
    • Spring Boot:提高开发效率
    • Spring Cloud:分布式开发相关技术

Spring体系结构

在这里插入图片描述

  • 第一模块:核心容器(Core Container

    • Spring框架最核心部分
  • 第二模块

    • 面向切面编程(AOP):依赖于核心容器
    • AOP思想实现(Aspects):是对AOP的一个思想实现
  • 第三模块

    • 数据访问(Data Access/Integration
    • 数据集成(Data Integration
  • 第四模块:Web开发

  • 第五模块:单元测试与集成测试(Test

    • 该框架整体均可进行测试
  • 学习线路

    在这里插入图片描述

Spring程序开发原理

  • Spring程序开发步骤

    在这里插入图片描述

  • 开发步骤详解

    • 在之前的学习中,我们在Service业务层创建Dao/Mapper数据访问层(持久层)的对象是通过new Dao/Mapper数据访问层(持久层)的接口实现类实现的,但是这种方式容易造成高耦合问题,所以我们现在舍弃该方式
    • 而是通过配置Spring的xml配置文件来获取到Dao/Mapper数据访问层(持久层)的接口实现类对象
      • 方式是:利用id唯一标识标记Dao/Mapper数据访问层(持久层)接口实现类的全限定名
    • 唯一标识后,在Service业务层就不需要在newDao/Mapper数据访问层接口实现类的对象,而是通过Spring客户端来调用Spring客户端提供的getBean("id标识")方法来获取到Dao/Mapper数据访问层(持久层)的接口实现类的对象
  • 开发步骤详解中Spring客户端获取到对象的原理如下:

    • Spring会先读取XML配置文件,然后根据id标识获取bean全限定名,Spring框架在获得bean全限定名后会通过反射创建bean对象,然后将该对象返回给开发人员

IOC(Inversion of Control:控制反转)

  • 定义

    • 对象的创建控制权由程序内部转移到外部
  • 解释

    • 使用对象时,由主动new产生对象转换为由外部提供对象,在此过程中对象创建控制权由程序内部转移到外部

    • 外部” 指的是IOC容器,它负责象的创建、初始化等一系列工作,被创建或管理的对象在IOC容器中称为bean

    • 示例:

      在原来的学习中我们在Service业务层时会在成员变量的位置new一个共有的数据访问层(持久层)的对象,如图一所示,如果数据层有两个实现类,那么我们在业务层就需要针对不同的场景new不同的对象,只要我们重新new一次对象,那系统就需要重新编译、重新测试、重新部署和发布,造成高耦合问题

      在这里插入图片描述

      为了避免高耦合,我们可以在使用对象的时候,在程序中不主动使用new来产生对象,转换为由外部提供对象。Spring就提供了一个Ioc容器,用来充当Ioc思想中的”外部“,它可以管理对象的创建和初始化的过程,若想用对象就从IOC容器中拿出来使用即可,如图二所示。但是此时就算拿出来使用也不会运行,原因详见DI依赖注入

      在这里插入图片描述

  • IOC容器

    • 它负责象的创建、初始化等一系列工作,被创建或管理的对象在IOC容器中统称为bean
  • .注意

    • IOCIOC容器、bean是三个不同的概念
    • IOC(控制反转)能够避免高耦合,但是并不能降低不同架构层的依赖关系,若想降低依赖关系需依靠DI(依赖注入)

Spring的IOC快速入门

  • 开发步骤

    • 导入Spring坐标

      <!--spring坐标-->
      <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.6</version>
      </dependency>
      
    • 编写Dao/Mapper数据访问层(持久层)接口及其实现类

    • 创建Spring核心配置文件,文件命名为applicationContext.xml

    • 在Spring配置文件中配置用到的接口的实现类

    • 使用Spring的API获取bean实例(即对应接口实现类的对象)

  • 完整步骤示例

    • Step1: 创建Web项目,导入Spring坐标及Tomcat插件,pom.xml文件如下:(在之后的示例中均需要该步,只是省略了)

      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>SpringDemo</artifactId><packaging>war</packaging><version>1.0-SNAPSHOT</version><name>SpringDemo Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!--spring坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.6</version></dependency></dependencies><build><finalName>SpringDemo</finalName><plugins><!-- Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version></plugin></plugins></build>
      </project>
      
    • Step2: 创建三层架构的包结构,并编写Dao/Mapper数据访问层(持久层)接口及其实现类。如图所示

      • 实现类要写对应架构包的impl包下

      在这里插入图片描述

    • Step3: 右键源代码配置文件目录(即资源文件resources)→NewXML Configuration FileSpring Config,文件名为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"></beans>
      

      在这里插入图片描述

    • Step4: 配置用到的接口的实现类:在applicationContext.xml文件中利用<bean>标签配置bean,代码如下所示

      该标签用到的属性解释
      idSpring容器中的bean的唯一标识符,可用来引用特定的bean实例
      classbean的实现类的全限定名
      <?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"><!--配置bean--><bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"/><!--等同于<bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"></bean>-->
      </beans>
      
    • Step5: 使用Spring的API获取bean的实例:创建测试类代码TestOne,代码及使用IOC容器步骤如下:

      • 测试类代码是在测试目录test下进行的测试
      package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestOne {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象UserDaoImpl userDao = (UserDaoImpl) app.getBean("userDaoImpl");//3 方法运行userDao.save();}
      }
      

      在这里插入图片描述

  • 普通获取IOC容器两种方式

    • 在以上测试代码中我们获取IOC容器是通过加载类路径下的配置文件来获取的。即new ClassPathXmlApplicationContext("applicationContext.xml");
    • 若我们从硬盘上获取则改为new FileSystemXmlApplicationContext("F:\\node\\idea\\ssm\\SpringDemo\\SpringWebTwo\\src\\main\\resources\\applicationContext.xml");
    • 若想获取多个
  • 从IOC容器中获取bean对应的对象

    • 使用bean的idname获取(需要强转):(UserDaoImpl) app.getBean("userDaoImpl");
    • 使用bean的idname获取时并指定类型(不需要强转):app.getBean("userDaoImpl", UserDaoImpl.class);
    • 按类型进行自动装配时(必须保证对应的bean唯一,否则失效):app.getBean(UserDaoImpl.class);
  • ApplicationContext接口及其相关的接口和类如图所示

    • ApplicationContext接口的最顶级父类为BeanFactory接口
    • BeanFactory接口为IOC容器的顶层接口,初始化BeanFactory对象时所有的bean均为延迟加载
    • ApplicationContext接口是Spring容器的核心接口,初始化ApplicationContext对象时所有的bean均为立即加载
    • ApplicationContext接口提供基础的bean操作的相关方法,通过其它接口拓展其功能
    • ApplicationContext的子接口ConfigurableApplicationContext拓展了一个ApplicationContext接口没有的colse()方法(即关闭容器的功能
    • ConfigurableApplicationContext下有常用的初始化实现类ClassPathXmlApplicationContextFileSystemXmlApplicationContext

    在这里插入图片描述

Spring配置文件applicationContext.xml <bean>标签详解一

  • 作用:用于配置对象并交由Spring来创建(即定义Spring核心容器管理的对象)

  • 默认情况下它调用的是类中的无参构造函数 ,若没有无参构造函数则会创建失败

  • 基本属性

    该标签用到的属性解释
    idSpring容器中的bean的个唯一的标识符,可用来引用特定的bean实例
    name定义bean的别名,定义多个别名时可用, ; 或空格分隔。
    classbean的实现类的全限定名
    scope指定对象的作用范围
    init-method指定类中初始化方法的名称
    destory-method指定类中销毁方法的名称
    factory-bean使用指定的工厂bean实例来调用工厂方法创建指定的bean实例
    factory-method使用指定工厂bean的方法来指定的bean实例
    p:propertyName="propertyValue"P命名空间依赖注入时使用的属性,此属性形式只适用于基本数据类型、字符串类型。propertyName: bean 中要设置的属性的名称。propertyValue:是要为该属性设置的值
    p:propertyName-ref="propertyValue"P命名空间依赖注入时使用的属性,此属性形式只适用于引用类型,其中ref代表是引用类型。propertyName: bean 中要设置的属性的名称。propertyValue:是要为该属性设置的值
    autowire自动装配 bean 的依赖关系
    autowire-candidate用于控制一个 bean 是否可以作为其他 bean 自动装配的候选者,默认为true
    lazy-init控制bean的延迟加载,默认为false(非延迟)
    scope属性取值解释
    singleton默认值,单例。即在IOC容器中对应bean的对象只有一个
    prototype多例。即在IOC容器中对应bean的对象有多个,每次在使用app.getBean()方法时都会获得对应bean的新对象
    requestWeb项目中,Spring创建一个bean的对象,将对象存入到request域中
    sessionWeb项目中,Spring创建一个bean的对象,将对象存入到session域中
    global sessionWeb项目中,应用在Portlet环境,若没有Portlet环境则global session相当于session
    autowire属性取值解释
    no默认值,默认不使用自动装配
    byType通过属性的类型进行自动装配
    byName通过属性名称进行自动装配
    constructor通过构造函数进行自动装配

name属性——别名配置

  • 创建三层架构的包结构,并编写Dao/Mapper数据访问层(持久层)接口及其实现类。如图所示

    • Step1: 实现类要写对应架构包的impl包下

    在这里插入图片描述

    • Step2: 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"><!--配置bean--><bean id="userDaoImpl" name="userDao1 userDao2" class="at.guigu.dao.impl.UserDaoImpl"/><!--等同于<bean id="userDaoImpl" name="userDao1 userDao2" class="at.guigu.dao.impl.UserDaoImpl"></bean>-->
    </beans>
    
    • Step3: 在测试目录下创建测试类TestTwo,代码如下:
    package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestTwo {/*** 测试name属性*/@Testpublic void Test2() {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象//利用name属性定义别名后getBean方法的参数不仅可以是id(即对应bean的唯一标识),还可以是对应bean的别名UserDaoImpl userDao1 = (UserDaoImpl) app.getBean("userDaoImpl");//等同于UserDaoImpl userDao2 = (UserDaoImpl) app.getBean("userDao1");//等同于UserDaoImpl userDao3 = (UserDaoImpl) app.getBean("userDao2");}
    }
    

    在这里插入图片描述

scope属性——作用范围配置

  • scope = "singleton"示例(以Spring的IOC快速入门代码为例进行讲解)

    • Step1: 创建三层架构的包结构,并编写Dao/Mapper数据访问层(持久层)接口及其实现类。如图所示

      • 实现类要写对应架构包的impl包下

      在这里插入图片描述

    • Step2: 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"><!--配置bean--><bean id="userDaoImpl" scope="singleton" class="at.guigu.dao.impl.UserDaoImpl"/><!--等同于<bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"/><bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"></bean>-->
      </beans>
      
    • Step3: 在测试目录下创建测试类TestTwo,代码如下:

      package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestTwo {/*** 测试scope = "singleton"*/@Testpublic void Test1() {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象UserDaoImpl userDao1 = (UserDaoImpl) app.getBean("userDaoImpl");UserDaoImpl userDao2 = (UserDaoImpl) app.getBean("userDaoImpl");//3 对象地址打印看是否是同一个地址System.out.println(userDao1);System.out.println(userDao2);}
      }
      

      运行该测试用例后,截图如下

      在这里插入图片描述

  • scope = "prototype"示例(以Spring的IOC快速入门代码为例进行讲解)

    • 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"><!--配置bean--><bean id="userDaoImpl" scope="prototype" class="at.guigu.dao.impl.UserDaoImpl"/></beans>
      
    • 测试类TestTwo代码不变,运行结果如下所示

      在这里插入图片描述

  • 注意: scope = "singleton"scope = "prototype"创建bean对象的时机不同

    • scope = "singleton"时(即默认情况下),bean对象随着这句代码ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");的执行就会立即创建并保存到IOC容器中
    • scope = "prototype"时,bean对象会随着getBean()方法的执行被创建
  • scope = "singleton"scope = "prototype"异同

    • scope = "singleton"
      • bean的实例化个数:1
      • bean的实例化时机:当Spring核心文件被加载时
      • bean的生命周期
        • 对象创建:当应用加载,创建容器时对象就被创建了
        • 对象运行:只要容器存在,对象就一直存活
        • 对象销毁:当应用卸载,销毁容器时,对象就会被销毁
    • scope = "prototype"
      • bean的实例化个数:多个
      • bean的实例化时机:当调用getBean()方法时
      • bean的生命周期
        • 对象创建:当使用对象时,就会创建新的对象实例
        • 对象运行:只要对象在使用中就一直存活
        • 对象销毁:当对象长时间不用时,就会被Java的垃圾回收器回收
  • 为什么IOC容器默认为单例?

    • Spring容器管理的对象为单例对象,也就是我们可以复用的对象,这次用完以后下次还会用这个对象,这样可以提高性能和资源利用效率,避免重复创建对象导致的资源浪费,同时简化开发和管理,确保应用中的一致性和数据共享。
  • 适合为单例对象的bean

    • Dao/Mapper数据层(持久层)对象
    • Service业务对象
    • Web/Controller表现层对象
    • util包的工具对象
    • 以上的bean适合交给Spring的IOC容器管理
  • 不适合为单例对象的bean

    • 在pojo包下封装实体的域对象:因为这种对象每次的属性值都不同

init-methoddestory-method属性——初始、销毁

  • init-method:指定类中初始化方法的名称
  • destory-method:指定类中销毁方法的名称
  • 容器关闭前会触发bean的销毁

初始、销毁方式一

  • 步骤如下

    • Step1:Dao/Mapper数据访问层(持久层)接口的实现类UserDaoImpl代码更改如下:

      package at.guigu.dao.impl;import at.guigu.dao.UserDao;public class UserDaoImpl implements UserDao {public UserDaoImpl () {System.out.println("UserDaoImpl被创建...");}// bean初始化时对应的操作public void init() {System.out.println("初始化方法");}// bean销毁前对应的操作public void destroy() {System.out.println("销毁方法");}public void save() {System.out.println("UserDao save running...");}
      }
      

      注意:init()和destroy()只是我们定义的两个方法,我们还需要在Spring配置文件中给其进行配置后,这两个方法才是真正的初始化方法和销毁方法

    • Step2: Spring配置文件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"><!--配置bean--><bean id="userDaoImpl" init-method="init" destroy-method="destroy" class="at.guigu.dao.impl.UserDaoImpl"/></beans>
      
    • Step3: 在测试目录下创建测试类TestThree,代码如下

      package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestThree {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象UserDaoImpl userDao = (UserDaoImpl) app.getBean("userDaoImpl");System.out.println(userDao);}
      }
      

      运行该测试用例后,截图如下

      在这里插入图片描述

  • 注意: 在上述运行截图中可看出该单元测试没有执行destroy()方法原因是:我们现在运行的程序是运行在Java虚拟机上的,当程序执行完毕后虚拟机会立即退出,并不会给bean销毁的机会。所以我们可以通过两种方式来销毁bean

    • 方式一: 在虚拟机退出之前手动释放容器资源,代码做如下更改:

      • 注意:ApplicationContex接口没有释放资源的close()方法,而我们所使用的其子接口的实现类ClassPathXmlApplicationContext有释放资源的close()方法,所以我们要进行强制转换
      package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestThree {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象UserDaoImpl userDao = (UserDaoImpl) app.getBean("userDaoImpl");System.out.println(userDao);//方式一: 手动关闭((ClassPathXmlApplicationContext) app).close();}
      }
      

      运行该测试用例后,截图如下

      在这里插入图片描述

    • 方式二: 设置关闭钩子 ,即允许在 JVM虚拟机 关闭之前执行一些清理操作,如释放资源、保存状态等。代码更改如下

      • 注意:registerShutdownHook()方法是AbstractApplicationContext接口的方法,所以需要先强制转换在调用
      package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.AbstractApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestThree {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//方式二: 设置关闭钩子((AbstractApplicationContext) app).registerShutdownHook();//2 从IOC容器中获取bean对应的对象UserDaoImpl userDao = (UserDaoImpl) app.getBean("userDaoImpl");System.out.println(userDao);/*方式一:手动关闭((ClassPathXmlApplicationContext) app).close();*/}
      }
      

      运行该测试用例后,截图如下

      在这里插入图片描述

    • 两种执行销毁方法的方式区别

      • 手动释放容器资源必须在放在最后,属于暴力手段
      • 设置关闭钩子可在任意位置,属于柔软手段

初始、销毁方式二

  • 初始、销毁方式一比较复杂,因为当类比较多时就需要重复配置配置文件,所以就有了初始、销毁方式二

  • 步骤如下

    • Step1: Dao/Mapper数据访问层(持久层)接口的实现类UserDaoImpl代码如下:

      • 该实现类除了要实现UserDao接口外还要实现Initializingbean,和Disposablebean两个接口,并分别重写这两个接口中的afterPropertiesSet()方法和destroy()方法
      package at.guigu.dao.impl;import at.guigu.dao.UserDao;
      import at.guigu.pojo.User;
      import org.springframework.beans.factory.Disposablebean;
      import org.springframework.beans.factory.Initializingbean;import java.util.List;
      import java.util.Map;
      import java.util.Properties;public class UserDaoImpl implements UserDao, Initializingbean, Disposablebean {public UserDaoImpl () {System.out.println("UserDaoImpl被创建...");}/*** 初始化方法* @throws Exception*/@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("Dao init...");}/*** 销毁方法* @throws Exception*/@Overridepublic void destroy() throws Exception {System.out.println("Dao destroy...");}public void save() {System.out.println("UserDao save running...");}
      }
      
    • Step2: Service业务层接口及实现类代码如下

      • 接口BookService

        package at.guigu.service;public interface BookService {public void save();
        }
        
      • 接口BookService的实现类BookServiceImpl

        该实现类除了要实现BookService接口外还要实现Initializingbean,和Disposablebean两个接口,并分别重写这两个接口中的afterPropertiesSet()方法和destroy()方法

        package at.guigu.service.impl;import at.guigu.dao.UserDao;
        import at.guigu.dao.impl.UserDaoImpl;
        import at.guigu.service.BookService;
        import org.springframework.beans.factory.Disposablebean;
        import org.springframework.beans.factory.Initializingbean;public class BookServiceImpl implements BookService, Initializingbean, Disposablebean {private UserDao userDao;/*** 属性设置* @param userDao*/public void setUserDao(UserDaoImpl userDao) {System.out.println("Service对userDao属性设置");this.userDao = userDao;}/*** 初始化方法* @throws Exception*/@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("Service init...");}/*** 销毁方法* @throws Exception*/@Overridepublic void destroy() throws Exception {System.out.println("Service destory...");}@Overridepublic void save() {System.out.println("BookService save...");userDao.save();}}
        
    • Step3: Spring配置文件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"><!--1 配置userDao  bean--><bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"/><!--2 配置bookService  bean--><bean id="bookServiceImpl" class="at.guigu.service.impl.BookServiceImpl"><!--3 绑定依赖关系--><property name="userDao" ref="userDaoImpl"></property><!--等同于<property name="userDao"><ref bean="userDaoImpl"/></property>--></bean></beans>
      
    • Step4:在测试目录下创建测试类TestThree,代码如下

      package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
      import at.guigu.service.impl.BookServiceImpl;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.AbstractApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestThree {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");// 设置关闭钩子((AbstractApplicationContext) app).registerShutdownHook();//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");System.out.println(bookService);}
      }
      

      在这里插入图片描述

  • 注意

    • 在使用实现Initializingbean,和Disposablebean两个接口来进行初始化和销毁时,其中初始化方法afterPropertiesSet()在属性设置(即setXXX方法)之后执行,可详见上述运行截图
  • 使用实现接口的方式来执行初始化和销毁时的bean生命周期

    • 初始化容器
      • 创建对象
      • 执行构造方法
      • 执行属性注入(set操作)
      • 执行bean初始化方法
    • 使用bean
      • 执行业务操作
    • 关闭/销毁容器
      • 执行bean销毁方法

bean实例化的三种方式(factory-beanfactory-method

  • factory-bean:使用指定的工厂bean实例来调用工厂方法创建指定的bean实例

  • factory-method:使用指定工厂bean的方法来指定的bean实例

  • bean实例化的三种方式

    • 无参构造方法实例化
    • 工厂静态方法实例化
    • 工厂实例方法实例化
    • 注意:
      • 默认情况下使用第一种方式时,若无参构造方法不存在则会抛出beanCreationException异常
      • 默认情况下用的都是第一种,通过配置可使用后两种实例化方法,此处主要解释后两种

工厂静态方法实例化

  • 工厂静态方法实例化步骤

    • Step1: 创建三层架构的包结构,并编写Dao/Mapper数据访问层(持久层)接口及其实现类。如图所示

      • 实现类要写对应架构包的impl包下

      在这里插入图片描述

    • Step2: 在工具类包util下创建工厂类(博主创建名为:StaticFactoryUtils),代码如下

      package at.guigu.util;import at.guigu.dao.UserDao;
      import at.guigu.dao.impl.UserDaoImpl;public class StaticFactoryUtil {//此为静态的public static UserDao getUserDao() {return new UserDaoImpl();}}
      
    • Step3: Spring配置文件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"><!--配置bean--><bean id="userDaoImpl" factory-method="getUserDao" class="at.guigu.util.StaticFactoryUtil"/></beans>
      

      注意:工厂静态方法实例化时,由于StaticFactoryUtils类中实例化的方法为静态方法,所以直接由类名调用静态方法即可创建UserDao对象

    • Step4: 创建测试类TestFour测试,代码如下

      package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestFour {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象UserDaoImpl userDao = (UserDaoImpl) app.getBean("userDaoImpl");System.out.println(userDao);}
      }
      

      在这里插入图片描述

工厂实例方法实例化

  • 工厂实例方法实例化方式一,步骤如下

    • Step1: 创建三层架构的包结构,并编写Dao/Mapper数据访问层(持久层)接口及其实现类。如图所示

      • 实现类要写对应架构包的impl包下

      在这里插入图片描述

    • Step2: 在工具类包util下创建工厂类(博主创建名为:DynamicFactoryUtils),代码如下

      package at.guigu.util;import at.guigu.dao.UserDao;
      import at.guigu.dao.impl.UserDaoImpl;public class DynamicFactoryUtils {//此为非静态的public UserDao getUserDao() {return new UserDaoImpl();}
      }
      
    • Step3: Spring配置文件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"><!--配置bean--><!--1 创建工厂对象并存入IOC容器--><bean id="dynamicFactoryUtils"  class="at.guigu.util.DynamicFactoryUtils"/><!--2 调用IOC容器中的工厂对象中的实例化方法实例化对象--><bean id="userDaoImpl" factory-bean="dynamicFactoryUtils" factory-method="getUserDao"/>
      </beans>
      

      注意:DynamicFactoryUtils类中实例化的方法为非静态方法时,必须先获取工厂类的对象再由工厂类的对象来调用getUserDao()方法

    • Step4: 创建测试类TestFive测试,代码如下

      package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestFive {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象UserDaoImpl userDao = (UserDaoImpl) app.getBean("userDaoImpl");System.out.println(userDao);}
      }
      

      在这里插入图片描述

  • 工厂实例方法实例化方式一 中有很大的缺点,如图所示,由此衍生出了第二种工厂实例方法实例化的方式

    在这里插入图片描述

    • 第二种工厂实例化方式的工具类继承自Factorybean<T>接口,其源码如下:

      public interface Factorybean<T> {T getObject() throws Exception;Class<?> getObjectType();boolean isSingleton();
      }
      
      方法解释
      T getObject() throws Exception;Factorybean 接口的核心方法。Spring 容器调用这个方法来获取这个工厂生成的 bean 实例。返回类型 T 表示工厂生成的对象类型
      Class<?> getObjectType();返回由 Factorybean 创建的对象的类型。如果在创建对象之前类型未知,则返回 null
      boolean isSingleton();返回这个由 Factorybean 创建的 bean 是否为单例,默认为ture(即单例)
  • 工厂实例方法实例化方式二,步骤如下

    • Step1: 创建三层架构的包结构,并编写Dao/Mapper数据访问层(持久层)接口及其实现类。如图所示

      • 实现类要写对应架构包的impl包下

      在这里插入图片描述

    • Step2: 在工具类包util下创建实现Factorybean接口的工厂类(博主创建名为:DynamicFactoryUtilsTwo),代码如下

      • 接口Factorybean<T>的泛型T为:想通过该工具类获取的对象的类名
      package at.guigu.util;import at.guigu.dao.UserDao;
      import at.guigu.dao.impl.UserDaoImpl;
      import org.springframework.beans.factory.Factorybean;public class DynamicFactoryUtilsTwo implements Factorybean<UserDaoImpl> {/*** 代替原始实例工厂中创建对象的方法* @return* @throws Exception*/@Overridepublic UserDaoImpl getObject() throws Exception {return new UserDaoImpl();}@Overridepublic Class<?> getObjectType() {return UserDaoImpl.class;}
      }
      
      • Step3: Spring配置文件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"><!--配置bean--><!--此时id为接口Factorybean<UserDaoImpl>的泛型,即<UserDaoImpl>--><!--此时class为实例工厂的类的全限定名--><bean id="userDaoImpl" class="at.guigu.util.DynamicFactoryUtilsTwo"/>
        </beans>
        
      • Step4: 创建测试类TestFive测试,代码如下

        package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
        import org.springframework.context.ApplicationContext;
        import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestFive {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象UserDaoImpl userDao = (UserDaoImpl) app.getBean("userDaoImpl");UserDaoImpl userDao2 = (UserDaoImpl) app.getBean("userDaoImpl");System.out.println(userDao);System.out.println(userDao2);}
        }
        

        在这里插入图片描述

  • 工厂实例方法实例化方式二 运行截图中可看出bean作用范围默认为单例,若想改为多例 则有两种方式:

    • 方式一: 利用scope属性(此处省略,可详见作用范围配置部分)

    • 方式二: 重写Factorybean接口中的isSingleton()方法,实现Factorybean接口的工厂类(博主创建名为:DynamicFactoryUtilsTwo),代码如下

      package at.guigu.util;import at.guigu.dao.UserDao;
      import at.guigu.dao.impl.UserDaoImpl;
      import org.springframework.beans.factory.Factorybean;public class DynamicFactoryUtilsTwo implements Factorybean<UserDaoImpl> {/*** 代替原始实例工厂中创建对象的方法* @return* @throws Exception*/@Overridepublic UserDaoImpl getObject() throws Exception {return new UserDaoImpl();}@Overridepublic Class<?> getObjectType() {return UserDaoImpl.class;}/*** 设置bean的作用范围* @return*/@Overridepublic boolean isSingleton() {return false;}
      }
      

      此时在运行测试类TestFive,截图如下

      在这里插入图片描述


DI(Dependency Injection:依赖注入)

  • 定义

    • 在容器中建立bean与bean之间的依赖关系的整个过程就叫做依赖注入
    • 它是Spring框架核心IOC的具体实现
  • 解释

    • 示例:

      图二中就算由外部提供对象也不可能成功运行,因为就算得到了Service对象,但由于Service接口的BookServiceImpl实现类内部需要一个Dao/Mapper对象供其使用,也就是说Service的实现类依赖于Dao/Mapper对象才能运行,因为此时ServiceDao/Mapper对象之间并没有建立依赖关系,所以程序无法运行,所以就会报错,如图三所示

      若想成功运行就需要给两者绑定依赖关系,此时只要Service实现类得到Service对象,就会连带着得到Dao/Mapper对象,此时即可成功运行

      在这里插入图片描述

  • 它是基于IOC管理bean而实现的DI ,使用DI(依赖注入)后,Spring框架会自动把Dao/Mapper数据访问层(持久层)对象传入Service业务层,而不需要我们自己去获取

  • 注意

    • Service业务层实现类BookServiceImpl中不能在使用new的形式创建Dao/Mapper数据层实现类的对象
    • Service业务层中需要的Dao/Mapper数据层对象是通过Service业务层提供的方法进入到Service业务层中的
    • Service业务层与Dao/Mapper数据层通过配置文件来进行依赖关系的绑定

Spring配置文件applicationContext.xml <bean>标签详解二

  • <bean>标签的内嵌标签

    <bean>标签中用到的内嵌标签解释
    <property>在 XML 配置文件中为 bean 的属性赋值,从而完成依赖注入和配置管理
    <constructor-arg>在 XML 配置文件中指定 bean 的构造函数参数。它允许我们在创建 bean 实例时通过构造函数注入依赖,而不是通过 setter 方法进行属性注入。
  • <property>中用到的属性

    <property>标签用到的属性解释
    name指定要设置的 bean 属性的名称
    ref用于指定一个 引用类型 的属性值,引用另一个 bean 的实例
    value用于直接设置基本数据类型或字符串数据类型的属性值
  • <constructor-arg>中用到的属性

    <constructor-arg>标签用到的属性解释
    name指定构造函数的参数名称
    type指定构造函数的参数类型。构造器参数若为对象,则属性值为对象的全类名;若为字符串类型,则为java.lang.String
    index指定构造函数的参数索引位置(以0为第一个参数索引位置)
    refIOC容器中可获取到依赖对象的bean的id值(即唯一标识)
  • <property>标签的内嵌标签

    <property>标签中用到的内嵌标签解释
    <value>设置基本数据类型、字符串类型的属性值
    <ref>引用其他 bean
    <list>配置List集合的属性值
    <map>配置Map集合的属性值
    <prop>配置Properties集合的属性值

Spring的DI(依赖注入)的三种方式

  • 依赖注入方式选择

    • setter方法注入
      • 可选依赖:即该bean对这个属性依赖不强,可有可无,不注入时也不会影响程序的运行
    • P命名空间注入
    • 有参构造方法注入
      • 强制依赖:即该bean必须依赖的属性,若为给该属性进行依赖注入,程序就无法运行
  • 注意

    • 使用有参构造方法注入时若不进行注入则配置文件就会报错,程序就无法运行
    • Spring框架倡导使用构造器注入,第三方框架内部大多采用构造器注入的形式进行数据初始化,这样相对严谨
    • 若有必要时setter方法注入和有参构造方法注入可同时使用。即使用setter方法注入完成可选依赖的注入;使用有参构造方法注入完成强制依赖的注入
    • 自己开发的模块推荐使用setter方法注入
    • 实际开发过程中还要根据实际情况分析,若受控对象未提供setter方法时就必须使用构造器注入

Spring的DI快速入门——setter方法注入

  • <property>标签:在 XML 配置文件中为 bean 的属性赋值,从而完成依赖注入和配置管理
<property>标签用到的属性解释
name指定要设置的 bean 属性的名称
ref用于指定一个引用类型的属性值,引用另一个 bean 的实例
  • set方法注入步骤如下:

    • Step1: Service业务层创建接口BookService及其实现类BookServiceImpl

      • 接口BookService
      package at.guigu.service;public interface BookService {public void save();
      }
      
    • Step2: 给所依赖的对象提供对应的setter方法:即在 Service业务层BookServiceImpl类中创建一个SetXXX方法,将BookDaoImpl对象给到我们定义的bookDao

      package at.guigu.service.impl;import at.guigu.dao.UserDao;
      import at.guigu.service.BookService;public class BookServiceImpl implements BookService {private UserDao userDao;@Overridepublic void save() {System.out.println("BookService save...");userDao.save();}// 给所依赖的对象提供对应的setter方法public void setUserDao(UserDao userDao) {this.this.userDao = userDao;}
      }
      
    • Step3: 配置依赖关系:在Spring容器中将BookDaoImpl绑定到BookServiceImpl内部,Spring配置文件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"><!--1 配置userDao  bean--><bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"/><!--2 配置bookService  bean--><bean id="bookServiceImpl" class="at.guigu.service.impl.BookServiceImpl"><!--3 绑定依赖关系--><property name="userDao" ref="userDaoImpl"></property><!--等同于<property name="userDao"><ref bean="userDaoImpl"/></property>--></bean>
      </beans>
      

      注意:

      name属性值:Service业务层中给所依赖的对象提供对应的setXXX方法中的XXX,开头字母变小写即可,比如setUserDao(),此时name=userDao

      ref属性值:IOC容器中可获取到依赖对象的bean的id值(即唯一标识)

    • 创建测试类TestSix,代码如下:

      package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
      import at.guigu.service.BookService;
      import at.guigu.service.impl.BookServiceImpl;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestSix {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");bookService.save();}
      }
      

      在这里插入图片描述

Spring的DI快速入门——P命名空间注入

  • 该方式本质上也是setter方法注入,但要比setter方法更方便

  • 注意:

    • 由于其本质也是setter方法注入,所以也要给所依赖的对象提供对应的setter方法 ,所BookServiceImpl类代码与 setter方法注入 中的一样
    • P命名空间注入只能用于基本数据类型、字符串类型和引用类型,不支持集合类型(如 ListSetMap)的配置。对于集合类型,仍需要使用传统的 <property> 标签及相关子元素(如 <list><set><map>)进行配置。
  • P命名空间注入步骤如下

    • Step1: 在Spring配置文件applicationContext.xml 中引入P命名空间,即xmlns:p="http://www.springframework.org/schema/p"

      <?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"></beans>
      
    • Step2: 引入P命名空间后Spring配置文件applicationContext.xml 代码如下

      <?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"><!--配置bean--><bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"/><bean id="bookServiceImpl" p:userDao-ref="userDaoImpl" class="at.guigu.service.impl.BookServiceImpl"/></beans>
      
    • 测试类TestSix代码如下:

      package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
      import at.guigu.service.BookService;
      import at.guigu.service.impl.BookServiceImpl;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestSix {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");bookService.save();}
      }
      

      在这里插入图片描述

Spring的DI快速入门——有参构造方法注入

  • 注意

    • 有参构造方法注入不需要BookServiceImpl类中的setter方法
  • 有参构造方法注入步骤如下

    • Step1: Service业务层BookServiceImpl类代码如下

      package at.guigu.service.impl;import at.guigu.dao.UserDao;
      import at.guigu.dao.impl.UserDaoImpl;
      import at.guigu.service.BookService;public class BookServiceImpl implements BookService {private UserDao userDao;public BookServiceImpl() {}public BookServiceImpl(UserDaoImpl userDao) {this.userDao = userDao;}@Overridepublic void save() {System.out.println("BookService save...");userDao.save();}}
      
    • **Step2: ** Spring配置文件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"><!--配置bean--><bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"/><bean id="bookServiceImpl" class="at.guigu.service.impl.BookServiceImpl"><!--name属性值为:有参构造器的参数名--><!--ref属性值为:IOC容器中可获取到依赖对象的bean的id值(即唯一标识)--><constructor-arg name="userDao" ref="userDaoImpl"></constructor-arg></bean></beans>
      

      注意:

      name属性值:为BookServiceImpl类中有参构造器的参数名

      ref属性值:IOC容器中可获取到依赖对象的bean的id值(即唯一标识)

    • 测试类TestSix代码如下:

      package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
      import at.guigu.service.BookService;
      import at.guigu.service.impl.BookServiceImpl;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestSix {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");bookService.save();}
      }
      

      在这里插入图片描述

有参构造方法注入弊端

  • 若构造器参数名改变 ,对应配置文件中<constructor-arg>标签的name属性值就需要随之改变,则解决办法如下

    • type标签代替name标签 ,此时配置文件中代码如下:

      <?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"><!--配置bean--><bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"/><bean id="bookServiceImpl" class="at.guigu.service.impl.BookServiceImpl"><!--type属性值为:有参构造器的参数对象对应的全限定名--><!--ref属性值为:IOC容器中可获取到依赖对象的bean的id值(即唯一标识)--><constructor-arg type="at.guigu.dao.impl.UserDaoImpl" ref="userDaoImpl"></constructor-arg></bean></beans>
      
    • index标签代替name标签

      <?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"><!--配置bean--><bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"/><bean id="bookServiceImpl" class="at.guigu.service.impl.BookServiceImplTwo"><!--index属性值为:有参构造器参数的索引位置--><!--ref属性值为:IOC容器中可获取到依赖对象的bean的id值(即唯一标识)--><constructor-arg index="0" ref="userDaoImpl"></constructor-arg></bean></beans>
      
  • 若构造器参数为基本数据类型和字符串类型

    • BookServiceImpl代码如下

      package at.guigu.service.impl;import at.guigu.dao.UserDao;
      import at.guigu.dao.impl.UserDaoImpl;
      import at.guigu.service.BookService;public class BookServiceImpl implements BookService {private String aaa;private int bbb;private boolean ccc;public BookServiceImpl() {}public BookServiceImpl(String aaa, int bbb, boolean ccc) {this.aaa = aaa;this.bbb = bbb;this.ccc = ccc;}@Overridepublic void save() {System.out.println(aaa + "===" + bbb + "===" + ccc);}}
      
    • 此时配置文件中代码如下:

      • 采用name属性配置

        <?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"><bean id="bookServiceImpl" class="at.guigu.service.impl.BookServiceImplTwo"><!--name属性值为:有参构造器的参数名--><!--ref属性值为:IOC容器中可获取到依赖对象的bean的id值(即唯一标识)--><constructor-arg name="aaa" value="zhangsan"></constructor-arg><constructor-arg name="bbb" value="2"></constructor-arg><constructor-arg name="ccc" value="false"></constructor-arg></bean></beans>
        
      • 采用type属性配置

        <?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"><bean id="bookServiceImpl" class="at.guigu.service.impl.BookServiceImplTwo"><!--type属性值为:构造函数的参数类型--><!--ref属性值为:IOC容器中可获取到依赖对象的bean的id值(即唯一标识)--><constructor-arg type="java.lang.String" value="zhangsan"></constructor-arg><constructor-arg type="int" value="2"></constructor-arg><constructor-arg type="boolean" value="false"></constructor-arg></bean></beans>
        
      • 采用index属性配置

        <?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"><bean id="bookServiceImpl" class="at.guigu.service.impl.BookServiceImplTwo"><!--index属性值为:有参构造器参数的索引位置--><!--ref属性值为:IOC容器中可获取到依赖对象的bean的id值(即唯一标识)--><constructor-arg index="0" value="zhangsan"></constructor-arg><constructor-arg index="1" value="2"></constructor-arg><constructor-arg index="2" value="false"></constructor-arg></bean></beans>
        
  • 注意

    • 当有参构造器的参数中有多个引用型参数时,nametypeindex三个属性均可使用,自行选择(尽量选择低耦合的方式)
    • 当有参构造器的参数中有多个基本数据类型及字符串类型时
      • 若基本数据类型无重复且只有一个字符串类型时,以上三种属性均可使用,自行选择(尽量选择低耦合的方式)
      • 若基本数据类型中存在重复情况且字符串类型也有重复,则此时type属性就无法使用,只能从nameindex两个属性中自行选择(尽量选择低耦合的方式)

依赖自动装配

  • 定义
    • IOC容器根据bean所依赖的资源在容器中自动查找并注入到bean的过程即为自动装配
  • 自动装配的方式有三种
    • 按类型autowire="byType":通过属性的类型进行自动装配
    • 按名称autowire="byName":通过属性名称进行自动装配
    • 按构造方法autowire="constructor":通过构造函数进行自动装配
    • 默认情况下autowire="no":即不适用自动装配
  • 注意
    • 依赖自动装配只能用于引用类型的依赖注入,不能对基本数据类型以及字符串类型进行操作
    • 按类型或名称自动装配时必须有setter方法存在,且只能通过setter方法进行自动装配
    • 按构造方法自动装配时必须有有参构造器的存在,且只能通过有参构造器进行自动装配
    • 使用按类型自动装配时,必须保障IOC容器中相同类型的bean唯一
    • 使用按名称自动装配时,必须保障容器中具有指定名称的bean
      • 不推荐使用按名称自动装配,因为变量名与配置完全耦合
    • 依赖自动装配优先级低于依赖注入的三种方式 ,若同时出现则依赖自动装配会自动失效

按类型自动装配

  • 注意

    • 按类型自动装配 必须setter方法的存在,且只能通过setter方法进行自动装配
    • 使用按类型进行自动装配时,对应bean的id唯一标识或name别名可以不存在
      • 因为按类型进行自动装配依赖于 Spring 容器中 bean 的类型匹配,而不是依赖于 bean 的 idname
    • 按类型自动装配时,必须保障IOC容器中相同类型的bean唯一
      • Spring 容器会查找与属性类型匹配的 bean。如果有多个相同类型的 bean,Spring 会抛出NoUniquebeanDefinitionException异常,因为它无法确定应该注入哪个 bean。
  • 属性类型对应IOC容器中的bean唯一

    • Dao/Mapper数据访问层(持久层)、Service业务层的接口及实现类如下

      在这里插入图片描述

    • 配置文件代码如下

      <?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"><bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"/><bean id="bookServiceImpl" class="at.guigu.service.impl.BookServiceImpl" autowire="byType"/></beans>
      
    • 测试代码如下

      package at.guigu.service;import at.guigu.service.impl.BookServiceImpl;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestOne {@Testpublic void test1() {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");bookService.save();}
      }
      

      运行结果如下

      在这里插入图片描述

  • 属性类型对应IOC容器中的bean不唯一

    • Dao/Mapper数据访问层(持久层)、Service业务层的实现类及配置文件代码如下

      在这里插入图片描述

    • 测试代码如下

      package at.guigu.service;import at.guigu.service.impl.BookServiceImpl;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestOne {@Testpublic void test1() {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");bookService.save();}
      }
      

      运行结果如下

      在这里插入图片描述

  • 属性类型对应IOC容器中的bean不唯一的解决方式

    • 可以使用autowire-candidate=falser将对应的bean设置成不可作为其它bean自动装配的候选者
    • 可以使用按名称自动装配

按名称自动装配

  • 注意

    • 按名称自动装配必须有setter方法的存在,且只能通过setter方法进行自动装配
    • 使用按名称自动装配时,必须保障容器中具有指定名称的bean
      • 即要进行自动装配的属性名必须与对应bean的id唯一标识或name别名完全一致
  • 未使用别名方式

    • Dao/Mapper数据访问层(持久层)、Service业务层的实现类及配置文件代码如下

      在这里插入图片描述

      测试代码如下

      package at.guigu.service;import at.guigu.service.impl.BookServiceImpl;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestOne {@Testpublic void test1() {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");bookService.save();}
      }
      

      运行结果如下

      在这里插入图片描述

  • 使用别名方式

    • Dao/Mapper数据访问层(持久层)、Service业务层的实现类及配置文件代码如下

      在这里插入图片描述

    • 测试代码如下

      package at.guigu.service;import at.guigu.service.impl.BookServiceImpl;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestOne {@Testpublic void test1() {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");bookService.save();}
      }
      

      运行结果如下

      在这里插入图片描述

按构造方法自动装配

  • 注意

    • 按构造方法自动装配时必须有有参构造器的存在,且只能通过有参构造器进行自动装配
    • Spring 的IOC容器会根据构造函数的参数类型来自动装配相应的 bean。
    • 确保构造函数参数的类型在容器中有且只有一个匹配的 bean。如果有多个匹配的 bean,Spring 会抛出 NoUniquebeanDefinitionException 异常。
  • 构造器参数对象对应IOC容器中的bean唯一

    • Dao/Mapper数据访问层(持久层)、Service业务层的实现类及配置文件代码如下

      在这里插入图片描述

    • 测试代码如下

      package at.guigu.service;import at.guigu.service.impl.BookServiceImpl;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestOne {@Testpublic void test1() {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");bookService.save();}
      }
      

      运行结果如下

      在这里插入图片描述

  • 构造器参数对象对应IOC容器中的bean不唯一

    • Dao/Mapper数据访问层(持久层)、Service业务层的实现类及配置文件代码如下
      在这里插入图片描述

    • 测试代码如下

      package at.guigu.service;import at.guigu.service.impl.BookServiceImpl;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestOne {@Testpublic void test1() {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");bookService.save();}
      }
      

      运行结果如下

      在这里插入图片描述

  • 构造器参数类型对应IOC容器中的bean不唯一的解决方式

    • 可以使用autowire-candidate=falser将对应的bean设置成不可作为其它bean自动装配的候选者
    • 可以使用按名称自动装配

bean的依赖注入的数据类型

  • 在之前的学习中都是注入的引用bean、除了对象的引用可以注入,普通数据类型的注入以及集合等都可以在容器中进行注入

  • 注入数据的三种数据类型

    • 普通数据类型(即基本数据类型与字符串类型)
    • 引用数据类型(此处不在举例,之前均为对象的引用注入,可详见依赖注入的三种方式的示例)
    • 集合数据类型

普通数据类型注入

  • setter方法进行注入 ——其它两种绑定依赖注入的方式可自行练习

    • Step1: 重新编写Dao/Mapper数据访问层(持久层)接口及其实现类,并在Dao/Mapper数据访问层(持久层)的UserDaoImpl实现类中添加普通数据类型的setter方法,如图所示

      在这里插入图片描述

    • Step2: Spring配置文件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"><!--配置bean--><bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"><property name="name" value="zhangsan"/><property name="age" value="18"/><!--等同于<property name="name"><value>zhangsan</value></property>--></bean></beans>
      
    • Step3: 创建测试用例TestSeven,代码如下

      package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
      import at.guigu.service.impl.BookServiceImpl;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestSeven {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象UserDaoImpl userDaoImpl = (UserDaoImpl) app.getBean("userDaoImpl");userDaoImpl.save();}
      }
      

      在这里插入图片描述

数组类型注入

  • setter方法进行注入 ——其它两种绑定依赖注入的方式可自行练习

    • Step1: 重新编写Dao/Mapper数据访问层(持久层)接口及其实现类,并在Dao/Mapper数据访问层(持久层)的UserDaoImpl实现类中添加数组数据类型的setter方法,如图所示

      在这里插入图片描述

    • Step2: Spring配置文件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"><bean id="bookServiceImpl" class="at.guigu.service.impl.BookServiceImpl"><property name="array"><array><value>100</value><value>200</value><value>300</value></array></property></bean>
      </beans>
      
    • Step3:测试代码如下

      package at.guigu.service;import at.guigu.service.impl.BookServiceImpl;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestOne {@Testpublic void test1() {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象BookServiceImpl bookService = (BookServiceImpl) app.getBean("bookServiceImpl");bookService.save();}
      }
      

      在这里插入图片描述

集合数据类型注入

  • setter方法进行注入 ——其它两种绑定依赖注入的方式可自行练习

    • Step1: 重新编写Dao/Mapper数据访问层(持久层)接口及其实现类,并在Dao/Mapper数据访问层(持久层)的UserDaoImpl实现类中添加集合数据类型的setter方法,如图所示

      • 注意:Map集合传入了User对象,所以此处需要一个User实体类

      在这里插入图片描述

    • Step2: Spring配置文件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"><!--配置bean--><bean id="user1" class="at.guigu.pojo.User"><property name="name" value="Tom"/><property name="addr" value="美国"/></bean><bean id="user2" class="at.guigu.pojo.User"><property name="name" value="Jerry"/><property name="addr" value="英国"/></bean><bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"><property name="strList"><list><value>aaa</value><value>bbb</value><value>ccc</value></list></property><property name="userMap"><map><entry key="userr1" value-ref="user1"></entry><entry key="userr2" value-ref="user2"></entry></map></property><property name="properties"><props><prop key="p1">ppp1</prop><prop key="p2">ppp2</prop></props></property></bean></beans>
      
    • Step4: 创建测试用例TestEight,代码如下

      package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestEight {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象UserDaoImpl userDaoImpl = (UserDaoImpl) app.getBean("userDaoImpl");userDaoImpl.save();}
      }
      

      在这里插入图片描述

  • P命名空间注入步骤

  • 有参构造方法注入步骤

Spring配置文件中引入其它配置文件

引入Spring拆分配置文件applicationContext-xxx.xml

  • 在实际开发中,Spring的配置内容很多,这会导致Spring配置很繁琐且体积偏大。所以我们可以将部分配置拆解到其它配置文件中,然后在Spring主配置文件中通过<import>标签进行加载

  • 拆解方式

    • 可根据三层架构进行拆解:比如拆解为ServiceDao/MapperWeb
    • 也可根据不同类型进行拆解:比如拆解为用户和商品
  • 引入其它配置文件的代码格式:<import resource="applicationContext-xxx.xml"/>

  • 示例:此处以集合数据类型注入 中的配置文件为例

    • 原Spring主配置文件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"><!--配置bean--><bean id="user1" class="at.guigu.pojo.User"><property name="name" value="Tom"/><property name="addr" value="美国"/></bean><bean id="user2" class="at.guigu.pojo.User"><property name="name" value="Jerry"/><property name="addr" value="英国"/></bean><bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"><property name="strList"><list><value>aaa</value><value>bbb</value><value>ccc</value></list></property><property name="userMap"><map><entry key="userr1" value-ref="user1"></entry><entry key="userr2" value-ref="user2"></entry></map></property><property name="properties"><props><prop key="p1">ppp1</prop><prop key="p2">ppp2</prop></props></property></bean></beans>
      
    • 将User拆解出来以后,分配置文件名为applicationContext-user.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"><!--配置bean--><bean id="user1" class="at.guigu.pojo.User"><property name="name" value="Tom"/><property name="addr" value="美国"/></bean><bean id="user2" class="at.guigu.pojo.User"><property name="name" value="Jerry"/><property name="addr" value="英国"/></bean></beans>
      
    • Spring主配置文件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"><!--引入拆解后的分配置文件--><import resource="applicationContext-user.xml"/><!--配置bean--><bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"><property name="strList"><list><value>aaa</value><value>bbb</value><value>ccc</value></list></property><property name="userMap"><map><entry key="userr1" value-ref="user1"></entry><entry key="userr2" value-ref="user2"></entry></map></property><property name="properties"><props><prop key="p1">ppp1</prop><prop key="p2">ppp2</prop></props></property></bean></beans>
      

引入properties配置文件

  • 详见Spring通过配置文件配置数据源(连接池)

引入多个配置文件(以properties配置文件为例)

  • 加载一个properties配置文件:<context:property-placeholder location="jdbc1.properties"/>

  • 加载多个properties配置文件(只能读取当前工程目录下的配置文件),如图所示

    在这里插入图片描述

    • 方式一:<context:property-placeholder location="jdbc1.properties, jdbc2.properties, ..."/>
    • 方式二:<context:property-placeholder location="*.properties"/>
    • 方式三(标准格式)<context:property-placeholder location="classpath:*.properties"/>
  • 加载多个properties配置文件(读取所有的配置文件):<context:property-placeholder location="classpath*:*.properties"/>

  • 注意:加载配置文件时可根据需要选择使用classpath:还是classpath*:

Spring相应API

ApplicationContext的实现类

ApplicationContext接口的实现类使用情形
ClassPathXmlApplicationContext从类的根路径下加载配置文件(即)
FileSystemXmlApplicationContext从磁盘路径上加载配置文件
AnnotationConfigApplicationContext当使用注解配置容器对象时,为了能够读取注解,就需要使用该类来创建Spring容器。
  • 前两种使用方式如下,第三种实现类后续会详细讲解

    package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.context.support.FileSystemXmlApplicationContext;public class TestEight {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");// 等同于FileSystemXmlApplicationContext app2 = new FileSystemXmlApplicationContext("F:\\node\\idea\\ssm\\SpringDemo\\src\\main\\resources\\applicationContext.xml");}
    }
    

getBean()方法的使用

getBean()方法解释
public Object getBean(String name) throws beansException从 Spring 容器中获取 bean 实例,传入的参数为Spring配置文件中对应bean的id(即唯一标识)
public <T> T getBean(Class<T> requiredType) throws beansException从 Spring 容器中获取 bean 实例,传入的参数为对应bean的类类对象即bean.Class
  • 第一种getBean方法需要类型强制转换,而第二种不需要,如下所示
package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;public class TestEight {public static void main(String[] args) {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");// 等同于FileSystemXmlApplicationContext app2 = new FileSystemXmlApplicationContext("F:\\node\\idea\\ssm\\SpringDemo\\src\\main\\resources\\applicationContext.xml");//2 从IOC容器中获取bean对应的对象UserDaoImpl userDaoImpl = (UserDaoImpl) app.getBean("userDaoImpl");// 等同于UserDaoImpl userDaoImpl2 = app.getBean(UserDaoImpl.class);}
}
  • 若对应的bean在Spring配置文件中为单例(即只有一个)时,则以上两种getBean方法都可使用(建议使用第二种);若在Spring配置文件中有多个时,则使用第一个getBean方法

    • 最好不同情况用不同的getBean方法,这样更能区分开

    • 对应的bean在Spring配置文件中只有一个的代码示例如下

      <?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"><!--配置bean--><bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"/><!--等同于<bean id="userDaoImpl" class="at.guigu.dao.impl.UserDaoImpl"></bean>-->
      </beans>
      
    • 对应的bean在Spring配置文件中有多个的代码示例如下

      <?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"><!--配置bean--><bean id="userDaoImpl1" class="at.guigu.dao.impl.UserDaoImpl"/><bean id="userDaoImpl2" class="at.guigu.dao.impl.UserDaoImpl"></bean></beans>
      
  • 注意:使用第一种方法来获取对应bean的对象时,若无法获取到将会抛出NoSuchbeanDefinitionException异常,即NoSuchbeanDefinitionException: No bean named 'userDaoImpll' available

    • 抛出该异常的原因:getBean方法参数与id(即唯一标识)或name(即别名)不一致

    • 代码示例

      package at.guigu.dao;import at.guigu.dao.impl.UserDaoImpl;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestTwo {/*** 测试NoSuchbeanDefinitionException异常*/@Testpublic void Test3() {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象UserDaoImpl userDao1 = (UserDaoImpl) app.getBean("userDaoImpll");System.out.println(userDao1);}
      }
      

      在这里插入图片描述

数据源(连接池)

  • 定义

    • 数据源(DataSource)是一个抽象的概念,主要用于提供对数据库的连接(可详见JDBC部分内容)
  • 作用

    • 提高程序性能
    • 事先实例化数据源,初始化部分连接资源
    • 使用连接资源时可从数据源中获取,使用完毕后将连接资源归还给数据源
  • 常见的数据源(连接池):DBCP、C3P0、BoneCP、Druid等

数据源(连接池)配置步骤

  • 数据源(连接池)的配置步骤

    • 在pom.xml文件中导入数据源(连接池)的坐标和数据库驱动坐标
    • 创建数据源对象并设置数据源的基本连接数据
    • 使用数据源获取连接资源和归还资源
  • 完整代码示例

    • Step1: 在pom.xml文件中导入数据源(连接池)的坐标和数据库mysql驱动坐标,代码如下

      • 博主测试C3P0、Druid两个数据库连接池,所以它俩的坐标均会导入
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>SpringDemoo</artifactId><packaging>war</packaging><version>1.0-SNAPSHOT</version><name>SpringDemoo Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!--mysql坐标--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!--druid坐标--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.18</version></dependency><!--c3p0坐标--><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version></dependency><!--spring坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.6</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies><build><finalName>SpringDemoo</finalName><plugins><!-- Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version></plugin></plugins></build>
      </project>
      
    • Step2: 创建数据源对象并设置数据源的基本连接数据。然后使用数据源获取连接资源和归还资源

      package at.guigu.datasource;import com.alibaba.druid.pool.DruidDataSource;
      import com.mchange.v2.c3p0.ComboPooledDataSource;
      import org.junit.Test;import java.sql.Connection;public class TestOne {/*** 测试CP30数据源对象*/@Testpublic void test1() throws Exception {// 创建数据源对象ComboPooledDataSource dataSource = new ComboPooledDataSource();// 设置数据源基本连接数据dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mybatis");dataSource.setUser("root");dataSource.setPassword("123456");// 使用数据源获取数据库连接资源Connection connection = dataSource.getConnection();System.out.println(connection);// 使用数据库资源,代码省略//归还数据库连接资源connection.close();}/*** 测试Druid数据源对象*/@Testpublic void test2() throws Exception {// 创建数据源对象DruidDataSource dataSource = new DruidDataSource();// 设置数据源基本连接数据dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/mybatis");dataSource.setUsername("root");dataSource.setPassword("123456");// 使用数据源获取数据库连接资源Connection connection = dataSource.getConnection();System.out.println(connection);// 使用数据库资源,代码省略//归还数据库连接资源connection.close();}
      }
      

      在这里插入图片描述

通过加载配置文件配置数据源(连接池)

  • 若使用 数据源开发步骤 中的代码来获取数据库连接资源的话则会造成高耦合问题,为了降低耦合度我们也利用properties配置文件进行数据源(连接池)的配置

  • 步骤如下

    • Step1: 在pom.xml文件中导入数据源(连接池)的坐标和数据库mysql驱动坐标,代码省略

      • 博主测试C3P0、Druid两个数据库连接池,所以它俩的坐标均会导入
    • Step2: 右键源代码配置文件目录(即资源文件resources)→NewFile,创建properties配置文件,博主文件名为jdbc.properties,该配置文件代码如下

      • properties配置文件中配置的各个属性前最好添加个id.(即id.属性,比如:属性url就设置为id.url,博主设置的为jdbc.url),防止系统中有与properties文件中的属性名一致的情况
      #driverClassName代表数据库驱动,后跟驱动全类名(在MySQL驱动jar包下的META-INF下的services文件夹下的java.sql.Driver文件内)
      jdbc.driverClassName=com.mysql.cj.jdbc.Driver
      # 数据库连接URL
      jdbc.url=jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
      # 数据库用户名
      jdbc.username=root
      # 数据库密码
      jdbc.password=123456
      # 初始化连接数量---即容器中初始的数据库连接数量
      jdbc.initialSize=5
      # 最大活跃连接数量---容器中初始为5个,但若5个用完了,此时可以在申请5个数据库连接数量
      #也就是说容器中最多存放10个数据库连接
      jdbc.maxActive=10
      # 获取连接时的最大等待时间,单位:毫秒。---与数据库进行连接时若超过3s仍未连接成功,则会报错
      jdbc.maxWait=3000
      #最小空闲连接数量---minIdle=5
      # 配置检测连接是否有效的SQL,可以是一个查询语句,如果不指定则默认为"SELECT 1"---validationQuery=SELECT 1
      # 是否开启自动提交事务---defaultAutoCommit=true
      
    • Step3: 读取properties配置文件并创建数据源对象,设置数据源的基本连接数据。然后使用数据源获取连接资源和归还资源

      package at.guigu.datasource;import com.alibaba.druid.pool.DruidDataSource;
      import com.mchange.v2.c3p0.ComboPooledDataSource;
      import org.junit.Test;import java.sql.Connection;
      import java.util.ResourceBundle;public class TestTwo {/*** 测试CP30数据源对象 (通过加载properties配置文件形式)*/@Testpublic void test1() throws Exception {// 读取配置文件ResourceBundle rb = ResourceBundle.getBundle("jdbc");String driverClassName = rb.getString("jdbc.driverClassName");String url = rb.getString("jdbc.url");String username = rb.getString("jdbc.username");String password = rb.getString("jdbc.password");// 创建数据源对象ComboPooledDataSource dataSource = new ComboPooledDataSource();dataSource.setDriverClass(driverClassName);dataSource.setJdbcUrl(url);dataSource.setUser(username);dataSource.setPassword(password);// 使用数据源获取数据库连接资源Connection connection = dataSource.getConnection();System.out.println(connection);// 使用数据库资源,代码省略//归还数据库连接资源connection.close();}/*** 测试Druid数据源对象 (通过加载properties配置文件形式)*/@Testpublic void test2() throws Exception {// 读取配置文件ResourceBundle rb = ResourceBundle.getBundle("jdbc");String driverClassName = rb.getString("jdbc.driverClassName");String url = rb.getString("jdbc.url");String username = rb.getString("jdbc.username");String password = rb.getString("jdbc.password");// 创建数据源对象DruidDataSource dataSource = new DruidDataSource();// 设置数据源基本连接数据dataSource.setDriverClassName(driverClassName);dataSource.setUrl(url);dataSource.setUsername(username);dataSource.setPassword(password);// 使用数据源获取数据库连接资源Connection connection = dataSource.getConnection();System.out.println(connection);// 使用数据库资源,代码省略//归还数据库连接资源connection.close();}
      }
      

      在这里插入图片描述

  • ResourceBundle类是专门用来通过键值对的形式存储和检索本地化的资源(如消息、标签等)。它的主要作用是根据不同的语言和区域设置加载相应的资源文件,从而实现应用程序的多语言支持。

    • 它所能加载的资源文件只有两种:即以.class.properties结尾的文件
    • 利用ResourceBundle类中的静态方法getBundle()加载配置文件时,它会自动在源代码配置文件目录(即资源文件resources)下查找所需的配置文件
      • 注意:使用该方法时,其参数只需给出配置文件的基名即可,它会自动匹配对应的后缀

Spring配置数据源(连接池)

  • 以上两种数据源配置方法耦合度还是很高,所以引入了Spring配置数据源(连接池)

  • 步骤如下

    • Step1: 在pom.xml文件中导入Spring、数据源(连接池)的坐标和数据库mysql驱动坐标。pom.xml文件完整代码如下

      • 博主测试C3P0、Druid两个数据库连接池,所以它俩的坐标均会导入
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>SpringDemoo</artifactId><packaging>war</packaging><version>1.0-SNAPSHOT</version><name>SpringDemoo Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!--mysql坐标--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!--druid坐标--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.18</version></dependency><!--c3p0坐标--><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version></dependency><!--spring坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.6</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies><build><finalName>SpringDemoo</finalName><plugins><!-- Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version></plugin></plugins></build>
      </project>
      
    • Step2: 右键源代码配置文件目录(即资源文件resources)→NewXML Configuration FileSpring Config,文件名为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"></beans>
      
    • Step3: 配置数据源(连接池)的bean,Spring配置文件代码如下

      <?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"><!--Cp30对应的bean--><bean id="dataSourceCp30" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.cj.jdbc.Driver"/><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mybatis"/><property name="user" value="root"/><property name="password" value="123456"/></bean><!--Druid对应的bean--><bean id="dataSourceDruid" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis"/><property name="username" value="root"/><property name="password" value="123456"/></bean>
      </beans>
      
    • Step4: 测试代码如下

      package at.guigu.datasource;import at.guigu.service.impl.BookServiceImpl;
      import com.alibaba.druid.pool.DruidDataSource;
      import com.mchange.v2.c3p0.ComboPooledDataSource;
      import org.junit.Test;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;import javax.sql.DataSource;
      import java.sql.Connection;public class TestThree {/*** 测试CP30数据源对象(通过Spring容器的方式)*/@Testpublic void test1() throws Exception {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象(即数据源对象)DataSource dataSourceCp30 = (DataSource) app.getBean("dataSourceCp30");//等同于ComboPooledDataSource bean = app.getBean(ComboPooledDataSource.class);// 使用数据源获取数据库连接资源Connection connection = dataSourceCp30.getConnection();System.out.println(connection);// 使用数据库资源,代码省略//归还数据库连接资源connection.close();}/*** 测试Druid数据源对象(通过Spring容器的方式)*/@Testpublic void test2() throws Exception {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象(即数据源对象)DataSource dataSourceDruid = (DataSource) app.getBean("dataSourceDruid");//等同于ComboPooledDataSource bean = app.getBean(DruidDataSource.class);// 使用数据源获取数据库连接资源Connection connection = dataSourceDruid.getConnection();System.out.println(connection);// 使用数据库资源,代码省略//归还数据库连接资源connection.close();}
      }
      

      在这里插入图片描述

Spring通过配置文件配置数据源(连接池)

  • 利用以上三种方式配置数据源(连接池)时耦合度仍然较高,所以就有了最优方案

  • 步骤如下所示

    • Step1: 在pom.xml文件中导入Spring、数据源(连接池)的坐标和数据库mysql驱动坐标。pom.xml文件完整代码如下

      • 博主测试C3P0、Druid两个数据库连接池,所以它俩的坐标均会导入
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>SpringDemoo</artifactId><packaging>war</packaging><version>1.0-SNAPSHOT</version><name>SpringDemoo Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!--mysql坐标--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!--druid坐标--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.18</version></dependency><!--c3p0坐标--><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version></dependency><!--spring坐标--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.1.6</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies><build><finalName>SpringDemoo</finalName><plugins><!-- Tomcat插件 --><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version></plugin></plugins></build>
      </project>
      
    • Step2: 右键源代码配置文件目录(即资源文件resources)→NewFile,创建properties配置文件,博主文件名为jdbc.properties,该配置文件代码如下

      • 注意: properties配置文件中配置的各个属性前必须添加个id.(即id.属性,比如:属性url就设置为id.url,博主设置的为jdbc.url)的原因
        • 配置数据库连接池的规定变量名与系统变量名冲突,若不加id.时:Spring配置文件利用属性占位符${} 调用来的就会默认为系统变量的值
    #driverClassName代表数据库驱动,后跟驱动全类名(在MySQL驱动jar包下的META-INF下的services文件夹下的java.sql.Driver文件内)
    jdbc.driverClassName=com.mysql.cj.jdbc.Driver
    # 数据库连接URL
    jdbc.url=jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    # 数据库用户名
    jdbc.username=root
    # 数据库密码
    jdbc.password=123456
    # 初始化连接数量---即容器中初始的数据库连接数量
    jdbc.initialSize=5
    # 最大活跃连接数量---容器中初始为5个,但若5个用完了,此时可以在申请5个数据库连接数量
    #也就是说容器中最多存放10个数据库连接
    jdbc.maxActive=10
    # 获取连接时的最大等待时间,单位:毫秒。---与数据库进行连接时若超过3s仍未连接成功,则会报错
    jdbc.maxWait=3000
    #最小空闲连接数量---minIdle=5
    # 配置检测连接是否有效的SQL,可以是一个查询语句,如果不指定则默认为"SELECT 1"---validationQuery=SELECT 1
    # 是否开启自动提交事务---defaultAutoCommit=true
    
    • Step3: 右键源代码配置文件目录(即资源文件resources)→NewXML Configuration FileSpring Config,文件名为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"></beans>
      
      • Step4: 在Spring配置文件中引入context命名空间和context约束路径然后使用context命名空间加载 properties 文件(加载 properties 文件成功后,Spring配置文件就可以使用属性占位符${} 语法来引用这些属性了)。Spring配置文件代码如下

        • 命名空间:xmlns:context="http://www.springframework.org/schema/context"
        • 约束路径:http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd
        <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--使用`context`命名空间加载 `properties` 文件--><context:property-placeholder location="classpath:jdbc.properties"/><!--若properties配置文件中没有加`id.`,则需变为如下形式使其系统属性失效<context:property-placeholder location="classpath:jdbc.properties" system-properties-mode="NEVER"/>--></beans>
        
      • Step5: 引入properties配置文件后配置数据源(连接池)的bean,Spring配置文件代码如下

        <?xml version="1.0" encoding="UTF-8"?>
        <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--使用`context`命名空间加载 `properties` 文件--><context:property-placeholder location="classpath:jdbc.properties"/><!--Cp30对应的bean--><bean id="dataSourceCp30" class="com.mchange.v2.c3p0.ComboPooledDataSource"><!--使用属性占位符`${}`语法引用properties文件中的属性--><property name="driverClass" value="${jdbc.driverClassName}"/><property name="jdbcUrl" value="${jdbc.url}"/><property name="user" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--Druid对应的bean--><bean id="dataSourceDruid" class="com.alibaba.druid.pool.DruidDataSource"><!--使用属性占位符`${}`语法引用properties文件中的属性--><property name="driverClassName" value="${jdbc.driverClassName}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean></beans>
        
      • Step6: 测试代码如下

        package at.guigu.datasource;import at.guigu.service.impl.BookServiceImpl;
        import com.alibaba.druid.pool.DruidDataSource;
        import com.mchange.v2.c3p0.ComboPooledDataSource;
        import org.junit.Test;
        import org.springframework.context.ApplicationContext;
        import org.springframework.context.support.ClassPathXmlApplicationContext;import javax.sql.DataSource;
        import java.sql.Connection;public class TestThree {/*** 测试CP30数据源对象(通过Spring容器的方式)*/@Testpublic void test1() throws Exception {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象(即数据源对象)DataSource dataSourceCp30 = (DataSource) app.getBean("dataSourceCp30");//等同于ComboPooledDataSource bean = app.getBean(ComboPooledDataSource.class);// 使用数据源获取数据库连接资源Connection connection = dataSourceCp30.getConnection();System.out.println(connection);// 使用数据库资源,代码省略//归还数据库连接资源connection.close();}/*** 测试Druid数据源对象(通过Spring容器的方式)*/@Testpublic void test2() throws Exception {//1 获取IOC容器ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");//2 从IOC容器中获取bean对应的对象(即数据源对象)DataSource dataSourceDruid = (DataSource) app.getBean("dataSourceDruid");//等同于ComboPooledDataSource bean = app.getBean(DruidDataSource.class);// 使用数据源获取数据库连接资源Connection connection = dataSourceDruid.getConnection();System.out.println(connection);// 使用数据库资源,代码省略//归还数据库连接资源connection.close();}
        }
        

        在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com