JAVA-Spring

Spring框架

1. 了解Spring

1.1 spring是什么?

• Spring官网:https://spring.io/
• 容器框架
• Spring 是分层的javaee/javase应用,轻量级开源框架,以IOC(控制反转)和AOP(面向切面编程)为内核

1. 怎么使用spring

• spring也是一个容器,里面存放java对象
• 让容器完成对象的创建,对象之间关系的管理(属性赋值)
• 我们在程序中从容器中获取要使用的对象

2. 什么样的对象放到容器中

• dao类,service类,controller类,工具类e
• spring对象默认都是单例的(在容器中叫这个名称的对象就只有一个)

3. 不放入到spring容器中的对象

• 实体类对象,servlet、监听器、过滤器……

4. Spring的优势

• 方便解耦合,简化开发
• AOP编程的支持
• 声明式事务的支持
• 方便程序的测试
• 方便集成各种优秀的框架
• 降低javaee api的使用难度
• spring源码是经典的学习范例

1.2 Spring Maven依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.5.RELEASE</version>
</dependency>

spring核心技术

• IOC   AOP   这两个能实现模块之间,类之间的解耦合

1.3 Spring对”依赖”的理解

• 在spring中有一个词叫做依赖:
• Class A 中使用了Class B的属性或者方法,叫做Class A 依赖 Class B

1.4 耦合

• 什么是耦合?
    • 简单的来说就是程序之间的依赖性
• 都有什么耦合?
    • 类之间的依赖
    • 方法之间的依赖
• 解耦合
    • 将低的程序间的依赖关系
• 解耦的思路
    • 第一步:使用反射机制创建对象,而不是new关键字
    • 第二步:通过读取配置文件来获取要创建的对象的全限定类名

2. IOC控制反转

2.1 IOC是什么?

• 英文:Inversion of control
• 描述的是:把对象的创建,赋值,管理工作都交给代码之外的容器实现,也就是对象的创建是有其他的外部资源来完成的
• 控制: 创建对象,对象属性赋值,对象之间的关系管理
• 反转:把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现,由容器代替开发人员管理、创建、赋值。
• 正转:由开发人员在代码中使用new构造方法创建对象,开发人员主动管理对象
• 控制反转:在这个容器里面,这个容器代替了开发人员创建对象,赋值,管理的工作
• 容器:spring       管理所有的组件,主动的new  变成被动的 获取

2.2 为什么使用IOC?

• 对象的管理更加松散
• 解耦合
• 减少对代码的改动,也能实现不同的功能

2.3 在之前的学习中IOC的体现

servlet中体现出来了
所有的对象不需要你去创建,直接在web.xml中配置一下tomcat自动就会帮你创建
tomcat作为容器:里面它存放了 Listener对象,Filter对象,Servlet对象

2.4 IOC的技术实现DI

• DI是IOC的技术实现
• DI翻译过来是     依赖注入
    • Dependency Injection
• 我们只需要在程序中提供要使用的对象的名称就可以了,对象如何在容器中创建,赋值,查找都由容器内部实现。
• spring是使用了DI实现了IOC的功能,spring底层创建对象使用的是反射。
• spring是一个容器,管理对象,给属性赋值,底层是反射机制创建对象

3. Spring第一个程序

1. 使用maven快速创建一个java项目

2. 添加maven依赖

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.2.5.RELEASE</version>
</dependency>

3. 创建类 (接口和他的实现类 随意创建)

4. 创建spring需要的配置文件

大家公认的配置文件的名字为 application.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">
    <!--告诉spring创建对象
        声明bean,告诉spring要创建哪个类的对象
        id:对象的自定义名称,自己给对象起个名
        class:类的全限定名称(不能是接口)
    -->
        <!-- 一个Bean 声明一个对象 -->
    <bean id="test" class="com.yixuexi.service.impl.DoServiceImpl"></bean>
    <bean id="myDate" class="java.util.Date"></bean>
    <bean id="myString" class="java.lang.String"></bean>
</beans>

5. 使用Spring容器

创建ClassPathXmlApplicationContext 对象

@Test
public void doSomeSpringTest(){
    //使用spring容器创建的对象
    //1.指定spring配置文件
    String config = "Test.xml";
    //2.创建表示spring容器的对象,ApplicationContext(是个接口)
    //ApplicationContext就是表示Spring的容器,通过容器能获取到对象
    //ClassPathXmlApplicationContext表示从类路径中加载配置文件
    ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(config);
    //得到对象 通过之前在配置文件中写的id得到,通过key得到value
    //在进行强转一下,向下转型
    DoService do1 = (DoService)ac.getBean("test"); 
}

3.1 spring 创建对象的时机

• 通过测试,发现在spring读取配置文件之后会立马创建出配置文件中已经配置了的对象信息
• 也就是说,在这行代码执行时 new ClassPathXmlApplicationContext(config); 所有以配置的对象都创建完毕
• 默认创建对象的时间是 在创建spring容器时,会创建配置文件中所有的对象
• spring创建对象默认调用的是对象的无参构造

1. 获取容器中定义好的对象的数量 容器就是ApplicationContext

int count = ac.getBeanDefinitionCount();

2. 获取容器中每个定义的对象的名称 也就是id 【key是什么】

// 返回一个String数组
String[] names = ac.getBeanDefinitionNames();
// 遍历数组
for (String name : names) {
    System.out.println(name);
}

3. 创建一个非自定义类的对象,也就是说创建一个 Date类 String 类….

<bean id="myDate" class="java.util.Date"></bean>
<bean id="myString" class="java.lang.String"></bean>

4. XML注入/${}

4.1. 在spring配置文件中给java对象赋值

DI:依赖注入(创建对象,并给属性赋值 注入就是赋值的意思)

1. DI的实现方式有两种

1. 在spring的配置文件中,使用标签和属性完成,叫做基于xml的DI实现
2. 使用spring中的注解,完成属性赋值,叫做基于注解的DI实现

2. DI的语法分类

• set注入(设值注入) :spring调用类的set方法,在set方法可以实现属性的赋值【很多人用 80%】
• 构造注入:spring调用类的有参构造方法,创建对象,在构造中完成赋值	 

3. spring中对数据类型的定义

• 简单数据类型:spring中规定了java中的基本数据类型和String都是简单类型(包装类也是简单类)
• 引用数据类型:Object及子类

4.2 set注入

set注入 【xml方式】:通过set注入进行对里面属性的赋值(也叫设值注入)
简单数据类型的set注入(本质上是调用的是set方法)

<bean id="自己起一个id名" class="全限定类名">
  <properties name="属性名" value="此属性的值" />
  <properties name="属性名" value="此属性的值" />
</bean>

引用数据类型的set注入:

<bean id="school02" class="com.yixuexi.test02.School">
  <property name="name" value="北京市第一小学"></property>
  <property name="id" value="2222"></property>
</bean>
<bean id="student02" class="com.yixuexi.test02.Student">
  <property name="id" value="999"></property>
  <property name="name" value="张三"></property>
  <!-- value改ref 写school的id -->
  <property name="school" ref="school02"></property>
</bean>

把value换成ref,然后后面跟 对应类型对象的id(也就是bean的id)

1. set注入注意事项:

• 类中必须要有set方法
• 不管是什么值 在value="都必须在引号内"
• 比如student类中有一个 setAddress()方法,但是并没有这个address属性,那么在配置文件中这么写<properties      name="address" value="北京市"> 他也会执行,并不会报错,spring找的就是类中的方法,他根据address判断出setAddress() 然后根据他的判断,他去找setAddress()这个方法,然后执行,不管有没有address属性。(只要有set方法 他就能用)

4.3 构造注入

spring调用类的有参数构造方法,在创建对象的同时,在构造方法中给属性赋值
使用 标签 :一个constructor-arg标签表示构造方法中的一个参数

• name:构造方法的形参名(切记 这是是形参名,一般的形参名都和属性名一致)
• index:构造方法参数的位置,参数从左往右  , 0   1   2   3
• value:简单类型的使用value
• ref:构造方法中的形参类型是引用类型的  放引用数据类型的id名

<!--通过构造方式注入来给对象属性赋值-->
<bean id="student03" class="com.yixuexi.test03.Student">
  <constructor-arg name="id" value="10"></constructor-arg>
  <constructor-arg name="name" value="张三"></constructor-arg>
  <constructor-arg name="school" ref="school02"></constructor-arg>
</bean>

4.4 在配置文件中也支持${}写法

1. 在类路径下添加一个properties的配置文件
2. 然后在里面写好值 key=value
3. 然后在xml文件中写
<context:property-placeholder location="classpath:bean.properties"/>
4. 然后在对象value的地方进行 ${}

5. 自动注入

5.1 引用类型的自动注入

• 引用类型的自动注入:spring框架根据某些规则可以给引用类型赋值
• 只针对引用类型的赋值,简单类型做不了

1. byName

• byName: (按名称注入) java类中引用类型的属性名和spring容器中(配置文件中)<bean>的id一样
• 并且数据类型是一致的,这样的容器中的bean  spring能够赋值给引用类型

<bean id="school" class="com.yixuexi.test.School">
  <property name="id" value="666"></property>
  <property name="name" value="北京市第一中学"></property>
</bean>
<bean id="student01" class="com.yixuexi.test.Student" autowire="byName">
  <property name="name" value="张三"></property>
  <property name="id" value="999"></property>
</bean>

设置 autowire=”byName”
并且 在student这个类中的school属性名 和 上面这个school bean的id一致 才行

2. byType

byType:(按类型注入,了解即可) java类中引用类型的数据类型和spring容器中(配置文件中) 的class属性是同源关系的,这样的bean能够赋值给引用类型

同源:

1. java类中的引用类型的数据类型和bean的class值是一样的
2. java类中引用类型的数据类型和bean是class的值父子类关系的
3. java类中引用类型的数据类型和bean的class的值是接口或者实现类关系的

设置 autowire=”byType”
• 注意:在byType中,在xml配置文件中声明bean 只能有一个符合条件的,多余一个是错误的
• 下图表示的是byType注入,其中两个类都在同一个包下,所以符合同源的第一条,所以可以自动注入成功

6. 使用使用多个配置文件的优势

1. 分担了一个文件的大小
2. 避免多人编写带来的冲突

• 多文件的分配方式
• 按功能模块分类,一个模块一个配置文件(学生成绩,学生选课)
• 按类的功能,数据库相关的配置一个配置文件,事务的功能一个配置文件

6.1 包含关系的配置文件

• 有三个配置文件,分别是spring-student.xml ,spring-school.xml,
• 还有一个主配置文件spring-total.xml
• 主配置文件一般都不定义对象,而是用来包含其他配置文件

语法:

<import resource="其他配置文件的路径"/>
关键字 "classpath:"  表示类路径的(class文件所在的目录)
在spring中如果需要指定别的文件的话 需要classpath:
【idea中指的是 tagert目录下的路径】
<import resource="classpath:spring-student.xml"/>
<import resource="classpath:spring-school.xml"/>

• 当在spring-total.xml文件中集成了这些文件之后,当读取这一个文件的时候这里面的被继承文件也都读取到了
• 并且也可以支持引用类型的注入
• Spring-student.xml里面需要一个school类型的属性而spring-school.xml里面有,这样的话,就算隔着一个文件也可以引用注入
• Spring-total.xml叫包含关系的配置文件

6.2 统配符方式

<import resource="classpath:spring-*.xml"/>

这样的话 最终的包含配置文件不能叫spring-total.xml 改名为total.xml

• 主配置文件不能包含在通配符的范围内
• 最好是放在同一级目录中
Contents
  1. 1. Spring框架
    1. 1.1. 1. 了解Spring
      1. 1.1.1. 1.1 spring是什么?
        1. 1.1.1.1. 1. 怎么使用spring
        2. 1.1.1.2. 2. 什么样的对象放到容器中
        3. 1.1.1.3. 3. 不放入到spring容器中的对象
        4. 1.1.1.4. 4. Spring的优势
      2. 1.1.2. 1.2 Spring Maven依赖
      3. 1.1.3. 1.3 Spring对”依赖”的理解
      4. 1.1.4. 1.4 耦合
    2. 1.2. 2. IOC控制反转
      1. 1.2.0.1. 2.1 IOC是什么?
      2. 1.2.0.2. 2.2 为什么使用IOC?
      3. 1.2.0.3. 2.3 在之前的学习中IOC的体现
      4. 1.2.0.4. 2.4 IOC的技术实现DI
  2. 1.3. 3. Spring第一个程序
    1. 1.3.0.1. 1. 使用maven快速创建一个java项目
    2. 1.3.0.2. 2. 添加maven依赖
    3. 1.3.0.3. 3. 创建类 (接口和他的实现类 随意创建)
    4. 1.3.0.4. 4. 创建spring需要的配置文件
    5. 1.3.0.5. 5. 使用Spring容器
  3. 1.3.1. 3.1 spring 创建对象的时机
    1. 1.3.1.1. 1. 获取容器中定义好的对象的数量 容器就是ApplicationContext
    2. 1.3.1.2. 2. 获取容器中每个定义的对象的名称 也就是id 【key是什么】
    3. 1.3.1.3. 3. 创建一个非自定义类的对象,也就是说创建一个 Date类 String 类….
  • 1.4. 4. XML注入/${}
    1. 1.4.1. 4.1. 在spring配置文件中给java对象赋值
      1. 1.4.1.1. 1. DI的实现方式有两种
      2. 1.4.1.2. 2. DI的语法分类
      3. 1.4.1.3. 3. spring中对数据类型的定义
    2. 1.4.2. 4.2 set注入
      1. 1.4.2.1. 1. set注入注意事项:
    3. 1.4.3. 4.3 构造注入
    4. 1.4.4. 4.4 在配置文件中也支持${}写法
      1. 1.4.4.0.1. 1. 在类路径下添加一个properties的配置文件
      2. 1.4.4.0.2. 2. 然后在里面写好值 key=value
      3. 1.4.4.0.3. 3. 然后在xml文件中写
      4. 1.4.4.0.4. 4. 然后在对象value的地方进行 ${}
  • 1.5. 5. 自动注入
    1. 1.5.1. 5.1 引用类型的自动注入
      1. 1.5.1.1. 1. byName
      2. 1.5.1.2. 2. byType
  • 1.6. 6. 使用使用多个配置文件的优势
    1. 1.6.1. 6.1 包含关系的配置文件
    2. 1.6.2. 6.2 统配符方式
  • |