Spring框架的概述以及Spring中基于XML的IOC配置

Spring的概述

Spring是什么
Spring是分层的Java SE/EE应用 full-stack 轻量级开源框架,以 IoC(Inverse of Control:反转控制)和 AOP(Aspect Oriented Programing:面向切片编程)为内核,提供了展现层SpringMVC和持久层 Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的JavaEE企业应用开源框架。
Spring的两大核心
IoC(Inverse of Control:反转控制)
AOP(Aspect Oriented Programing:面向切片编程)
Spring的发展历程和优势
Spring的优势
方便解耦,简化开发
AOP编程的支持
声明式事务的支持
方便程序的测试
方便集成各种优秀的框架
降低JavaEE API的使用难度
Java源码是经典学习案例
Spring体系结构
spring-overview.png

程序的耦合和解耦

  • 曾经案例中的问题
    • 程序的耦合
      • 耦合:程序间的依赖关系
        • 包括
          • 类之间的依赖
          • 方法之间的依赖
      • 解耦:降低程序间的依赖关系
      • 实际开发中:
        • 应该做到:编译器不依赖,运行时才依赖。
      • 解耦的思路:
        • 第一步:使用反射来创建对象,而避免使用new关键字
        • 第二步:通过读取配置文件来获取要创建的对象的全限定类名
  • 工厂模式解耦

在实际开发中我们可以把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的 方法通过读取配置文件,把这些对象创建出来并存起来。在接下来的使用的时候,直接拿过来用就好了。 那么,这个读取配置文件,创建和获取三层对象的类就是工厂。

  1. package cn.kxwahn.factory;
  2. import java.io.InputStream;
  3. import java.util.Enumeration;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6. import java.util.Properties;
  7. /**
  8. * 一个创建Bean对象的工厂
  9. * Bean:在计算机英语中,有可重用组件的含义。
  10. * JavaBean:用java语言编写的可重用组件。
  11. * javabean > 实体类
  12. * 它就是创建service和dao对象的
  13. * 第一个:需要一个配置文件来配置service和dao
  14. * 配置的内容:唯一标识 = 全限定类名(key = value)
  15. * 第二个:通过读取配置文件中配置文件的内容,反射创建对象
  16. * 配置文件可以是xml也可以是properties
  17. */
  18. public class BeanFactory {
  19. // 定义一个Properties对象
  20. private static Properties props;
  21. // 定义一个Map,用于存放我们要创建的对象,我们把它称之为容器。
  22. private static Map<String, Object> beans;
  23. // 使用静态代码块为Properties对象赋值
  24. static {
  25. try {
  26. // 实例化对象
  27. props = new Properties();
  28. // 获取Properties文件的流对象
  29. InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
  30. props.load(is);
  31. // 实例化容器
  32. beans = new HashMap<String, Object>();
  33. // 取出配置文件中所有的key
  34. Enumeration keys = props.keys();
  35. // 遍历枚举
  36. while (keys.hasMoreElements()) {
  37. // 取出每个key
  38. String key = keys.nextElement().toString();
  39. // 根据key获取value
  40. String beanPath = props.getProperty(key);
  41. // 反射创建对象
  42. Object value = Class.forName(beanPath).newInstance();
  43. // 把key和value存入容器中
  44. beans.put(key, value);
  45. }
  46. } catch (Exception e) {
  47. throw new ExceptionInInitializerError("初始化properties失败!");
  48. }
  49. }
  50. /**
  51. * 根据Bean的名称获取Bean对象
  52. * @param beanName
  53. * @return
  54. */
  55. public static Object getBean(String beanName){
  56. return beans.get(beanName);
  57. }
  58. }

无标题.png

IOC概念和Spring中的IOC

Spring中基于XML的IOC环境ioc.png
原来: 我们在获取对象时,都是采用 new 的方式。是主动的。
现在: 我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。
这种被动接收的方式获取对象的思想就是控制反转,它是 spring 框架的核心之一。
明确 ioc 的作用削减计算机程序的耦合(解除我们代码中的依赖关系)。

DI.jpg

依赖注入(Dependency Injection)

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. https://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <!--spring中的依赖注入
  7. 依赖注入:
  8. Dependency Injection
  9. IoC的作用:
  10. 降低程序间的耦合(依赖关系)
  11. 依赖关系的管理:
  12. 以后都交给了spring来维护
  13. 在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明
  14. 依赖关系的维护:
  15. 就称之为依赖注入。
  16. 依赖注入:
  17. 能注入的数据:有三类:
  18. 基本类型和String
  19. 其他bean类型(在配置文件中或者注解配置过的bean)
  20. 复杂类型/集合类型
  21. 注入的方式:有三种
  22. 第一种:使用构造函数提供
  23. 第二种:使用set方法提供
  24. 第三种:使用注解提供
  25. -->
  26. <!--构造函数注入:
  27. 使用的标签:constructor-arg
  28. 标签出现的位置:bean标签的内部
  29. 标签中的属性
  30. type:用于指定要注入的数据的数据类型,该数据也是构造函数中某个或某些参数的类型
  31. index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
  32. name:用于指定给构造函数中指定名称的参数赋值
  33. =================以上三个用于指定给构造函数中哪个参数赋值=================
  34. value:用于提供基本类型和String类型的数据
  35. ref:用于指定其他的bean类型数据。它指的是在spring的IoC核心容器中出现过的bean对象
  36. 优势:
  37. 在获取bean对象时,注入数据时必须的操作,否则对象无法创建成功。
  38. 弊端:
  39. 改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
  40. -->
  41. <bean id="accountService" class="cn.kxwahn.service.impl.AccountServiceImpl">
  42. <constructor-arg name="name" value="可惜我爱怀念"></constructor-arg>
  43. <constructor-arg name="age" value="18"></constructor-arg>
  44. <constructor-arg name="birthday" ref="now"></constructor-arg>
  45. </bean>
  46. <!--配置一个日期对象-->
  47. <bean id="now" class="java.util.Date"></bean>
  48. <!--set方法注入 更常用的方式
  49. 涉及的标签:property
  50. 出现的位置:bean标签的内部
  51. 标签中的属性
  52. name:用于指定注入时所调用的set方法名称
  53. value:用于提供基本类型和String类型的数据
  54. ref:用于指定其他的bean类型数据。它指的是在spring的IoC核心容器中出现过的bean对象
  55. 优势:
  56. 创建对象时没有明确的限制,可以直接使用默认构造函数
  57. 弊端:
  58. 如果有某个成员必须有值,则获取对象是有可能set方法没有执行。
  59. -->
  60. <bean id="accountService2" class="cn.kxwahn.service.impl.AccountServiceImpl2">
  61. <property name="name" value="test"></property>
  62. <property name="age" value="21"></property>
  63. <property name="birthday" ref="now"></property>
  64. </bean>
  65. <!--复杂类型的注入/集合类型的注入
  66. 用于给List结构集合注入的标签:
  67. list array set
  68. 用于给Map结构集合注入的标签:
  69. map props
  70. 结构相同,标签可以互换
  71. -->
  72. <bean id="accountService3" class="cn.kxwahn.service.impl.AccountServiceImpl3">
  73. <property name="myStrs">
  74. <array>
  75. <value>AAA</value>
  76. <value>BBB</value>
  77. <value>CCC</value>
  78. </array>
  79. </property>
  80. <property name="myList">
  81. <list>
  82. <value>AAA</value>
  83. <value>BBB</value>
  84. <value>CCC</value>
  85. </list>
  86. </property>
  87. <property name="mySet">
  88. <list>
  89. <value>AAA</value>
  90. <value>BBB</value>
  91. <value>CCC</value>
  92. </list>
  93. </property>
  94. <property name="myMap">
  95. <map>
  96. <entry key="testA" value="aaa"></entry>
  97. <entry key="testB">
  98. <value>BBB</value>
  99. </entry>
  100. </map>
  101. </property>
  102. <property name="myProps">
  103. <props>
  104. <prop key="testC">ccc</prop>
  105. <prop key="testD">ddd</prop>
  106. </props>
  107. </property>
  108. </bean>
  109. </beans>

Spring中的基本注解的IOC和IOC的案例

Spring中IoC的常用注解

案例使用xml方式和注解方式实现单表的CRUD操作

持久层技术选择:DBUtils

改造基于注解的IoC案例,使用纯注解的方式实现

Spring的一些新注解使用

Spring和Junit整合

  1. 应用程序的入口
    1. main方法
  2. junit单元测试中,没有main方法也能执行
    1. junit集成了一个main方法
    2. 该方法就会判断当前的测试类中有哪些方法有@Test注解
    3. junit就会让有Test注解的方法执行
  3. junit不会管我们是否采用spring框架
    1. 在执行测试方法时,junit根本不知道我们是不是使用了spring框架
    2. 所以也就不会为我们读取配置文件/配置类创建spring核心容器
  4. 由以上三点可知
    1. 当测试方法执行时,没有IoC容器,就算写了Autowired注解,也无法实现注入

      Spring中的AOP和基于XML以及注解的AOP配置

      完善account案例

      分析案例中的问题

      回顾之前讲过的一个技术:动态代理

      动态代理的另一种实现方式

      解决案例中的问题

      AOP的概念

      spring中的AOP相关术语

      spring中基于XML和注解的AOP配置

      Spring中的JdbcTemplate以及Spring事务控制

      Spring中的JdbcTemplate

      持久层总图.jpg
  • JdbcTemplate的作用:
    • 它就是用于和数据库交互的,实现对表的CRUD操作
  • 如何创建该对象:
  • 对象中的常用方法:

    Spring基于AOP的事务控制

    Spring中的事务控制

    基于XML
    基于注解