简介

Spring框架是一个容器,是整合其他框架的框架

他的核心是IOC(控制反转)和AOP(面向切面编程),由20多个模块构成,在很多领域都提供了优秀的问题解决方案

特点

  • 轻量级:由20多个模块构成,每个jar包都很小,小于1M,核心包也就3M左右

  • 代码污染小:Spring框架对程序员开发时的条条框框的约束较少,对代码的污染小

  • 面向接口编程:面向接口编程,灵活性高,项目的可扩展性和可维护性都较高

  • AOP:面向切面编程,将公共的,通用的,重复的代码单独开发,在需要时反织回去

  • 示例:

示例分析:在开发中普遍需要使用到日志输出功能,会将日志输出功能大量耦合到项目的不同位置,如上图左侧所示。

而日志输出功能与项目本身的核心业务逻辑无关,我们只是为了不时的查看程序的运行状态。则可以将日志功能单独提出去开发,在需要的地方将日志输出功能(所谓:切面)反织回去即可,如上图右侧所示。

  • 整合其他框架:使其他框架也更加易用

IOC

  • IOC(Inversion of Control):是一个概念,也是一种思想,由Spring容器进行对象的创建和依赖注入,程序员在使用时直接取用即可
  • 正转示例
//程序员创建对象
Student stu = new Student();
//程序员进行赋值
stu.setName("荷包蛋");
stu.setAge(20);
  • 反转示例
<!-- Spring容器负责对象的创建 -->
<bean id="stu" class="com.example.pojo.Student">
<!-- Spring容器负责为属性赋值 -->
<property name="name" value="荷包蛋" />
<property name="age" value="20" />
</bean>

创建Spring项目

  • 创建maven的java项目:模板类型 + 项目目录结构 + 修改pom.xml文件添加基本配置的操作不再赘述,可以参考mybatis博客集里对maven项目的配置
  • 在pom.xml里添加Spring依赖
    <!-- 添加spring依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.22</version>
</dependency>
  • 在src/main/resources目录下添加Spring配置文件:applicationContext.xml,正常情况下,文件头自动补全(在下图状态下,无法截图,手机拍摄,包涵包涵)

创建实例对象

  • 容器创建实例对象和传统方式下手动创建实例对象的对比
//实体类
package com.example.pojo; public class Student {
private String name;
private int age; public Student() {
System.out.println("无参方法被调用,Student实例被创建.....");
} @Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
<!-- 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="stu" class="com.example.pojo.Student"/>
</beans>
//两种创建实例对象的对比

package com.example.test;

import com.example.pojo.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestStudent { //测试程序员手动创建实例对象
@Test
public void testStudent(){
Student stu = new Student();
System.out.println(stu);
} //测试Spring容器创建实例对象
@Test
public void testStudentSpring(){
//创建Spring容器,并启动
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//从容器中获取对象
Student stu = (Student) applicationContext.getBean("stu");
System.out.println(stu);
}
}
    //两次测试的输出结果均为

    无参方法被调用,Student实例被创建.....
Student{name='null', age=0} Process finished with exit code 0
  • 当Spring容器创建时,对应的应用域中注册的对象就会被创建
    @Test
public void testStudentSpring(){
//创建Spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("source01/applicationContext.xml");
}
    //测试输出结果

    无参方法被调用,Student实例被创建.....

    Process finished with exit code 0

基于xml的IOC(控制反转)

setter注入

  • 简单类型(8 + 1)注入

    • 使用value属性
    //添加两个属性的set方法
public void setName(String name) {
this.name = name;
} public void setAge(int age) {
this.age = age;
}
    <bean id="stu" class="com.example.pojo.Student">
<!-- 使用setter注入法为实例对象的属性赋值 -->
<property name="name" value="荷包蛋"/>
<property name="age" value="20"/>
</bean>
    //测试Spring容器创建实例对象
@Test
public void testStudentSpring(){
//创建Spring容器,并启动
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("source01/applicationContext.xml");
//从容器中获取对象
Student stu = (Student) applicationContext.getBean("stu");
System.out.println(stu);
}
    //测试输出:
无参方法被调用,Student实例被创建.....
Student{name='荷包蛋', age=20} Process finished with exit code 0
  • 引用类型注入

    • 使用ref属性
        //School类
    private String name;
    private String address; public void setName(String name) {
    this.name = name;
    } public void setAddress(String address) {
    this.address = address;
    } public School() {
    System.out.println("School类的构造方法被执行,实体对象被创建.....");
    } @Override
    public String toString() {
    return "School{" +
    "name='" + name + '\'' +
    ", address='" + address + '\'' +
    '}';
    }
        //Student类
    private String name;
    private int age;
    private School school; public Student() {
    System.out.println("Student类的构造方法执行,实体对象被创建....");
    } public void setName(String name) {
    this.name = name;
    } public void setAge(int age) {
    this.age = age;
    } public void setSchool(School school) {
    this.school = school;
    } @Override
    public String toString() {
    return "Student{" +
    "name='" + name + '\'' +
    ", age=" + age +
    ", school=" + school +
    '}';
    }
        <!-- applicationContext.xml文件 --> 
    
       <!-- 定义School实体类的实例对象-->
    <bean id="school" class="com.example.pojo02.School">
    <property name="name" value="nefu"/>
    <property name="address" value="哈尔滨"/>
    </bean> <!-- 定义Student实体类的实例对象 -->
    <bean id="stu" class="com.example.pojo02.Student">
    <property name="name" value="荷包蛋"/>
    <property name="age" value="20"/>
    <!-- 根据bean工厂中注册过的对象,进行依赖注入 -->
    <property name="school" ref="school"/>
    </bean>
        //测试setter注入法的ref属性
    @Test
    public void testStudent(){
    //创建Spring容器,同时生成bean工厂中注册的对象
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("source02/applicationContext.xml");
    //获取对象
    Student stu = (Student) applicationContext.getBean("stu");
    System.out.println(stu);
    }
        //测试输出结果
    School类的构造方法被执行,实体对象被创建.....
    Student类的构造方法执行,实体对象被创建....
    Student{name='荷包蛋', age=20, school=School{name='nefu', address='哈尔滨'}} Process finished with exit code 0
  • 使用setter注入法必须提供无参构造方法,必须提供待注入属性的setXXX()方法

    • 无参构造方法用于创建实例对象,此时实例对象的属性是一张白纸,未被赋值和其他数据污染
    • 对应属性的set方法是为了在底层调用时给目标属性赋值用,框架再封装,底层的执行代码该有的还要有,框架也不知道你在set方法中都想干些什么(毕竟set方法应该被用来赋值,但是不仅仅只能做赋值用)
    • 有了前两步,你便可以得到需要的对象,而且只有指定的属性被赋值,其他属性一尘不染
    • 但是,如果提供了有参构造方法,或者没有set方法,setter注入将会遇到无限多的麻烦
      • 无set方法,底层无法调用对应set方法完成属性赋值
      • 有参构造方法的参数会扰乱我们对指定属性的赋值计划
      • 例如,有参构造包括name和age两个属性,而set又要对name属性注入值,就会导致name属性被两次赋值,在创建对象时就这样做显然不合理
    • 所以:我们要做的就是,先创建一个干净的对象(无参构造,先不涉及属性值的问题),再用对应属性的set方法给属性赋值,做到精准赋值,按需操作

Spring 01: Spring配置 + IOC控制反转 + Setter注入的更多相关文章

  1. Spring专题2: DI,IOC 控制反转和依赖注入

    合集目录 Spring专题2: DI,IOC 控制反转和依赖注入 https://docs.spring.io/spring/docs/2.5.x/reference/aop.html https:/ ...

  2. Spring IOC - 控制反转(依赖注入) - 入门案例 - 获取对象的方式 - 别名标签

    1. IOC - 控制反转(依赖注入) 所谓的IOC称之为控制反转,简单来说就是将对象的创建的权利及对象的生命周期的管理过程交 由Spring框架来处理,从此在开发过程中不再需要关注对象的创建和生命周 ...

  3. spring(一) IOC 控制反转 、DI 依赖注入

    IOC 控制反转:创建对象的方式  变成了由Spring来主导 IOC底层原理:对象工厂 1.导入jar包:4个核心jar和1个依赖jar spring-beans-4.3.9.RELEASE.jar ...

  4. spring最核心思想--ioc控制反转

    一核心概念 控制反转:将bean的生成交给容器,程序可以从容器中获取指定的bean. 个人理解:此优势也是spring能够流行并成为java主流框架的主要原因,java是帮助java程序员以对象的方式 ...

  5. Spring IOC - 控制反转(依赖注入) - 配置初始化和销毁的方法

    在Spring中如果某个bean在初始化之后,或销毁之前要做一些额外操作可以为该bean配置初始化和销毁的我方法,在这些方法中完成需要的功能. 实验: 通过断点调试模式,测试初始化方法和销毁方法的执行 ...

  6. Spring框架系列(四)--IOC控制反转和DI依赖注入

    背景: 如果对象的引用或者依赖关系的管理由具体对象完成,代码的耦合性就会很高,代码测试也变得困难.而IOC可以很好的解决这个问题,把这 些依赖关系交给框架或者IOC容器进行管理,简化了开发. IOC是 ...

  7. Spring IOC - 控制反转(依赖注入) - 懒加载机制

    懒加载机制 Spring默认会在容器初始化的过程中,解析xml,并将单例的bean创建并保存到map中,这样的机制在bean比较少的时间问题不大,但一旦bean非常多时,Spring需要在启动的过程中 ...

  8. Spring IOC - 控制反转(依赖注入) - 单例和多例

    Spring容器管理的bean在默认情况下是单例的,即一个bean只会创建一个对象,存在map中,之后无论获取多少次该bean,都返回同一个对象. Spring默认采用单例方式,减少了对象的创建,从而 ...

  9. Spring IOC - 控制反转(依赖注入) - 创建对象的方式

    a.通过类的无参构造方法创建对象 在入门案例中就是这种方式.当用最普通的方式配饰一个<bean>时,默认就是采用类的 无参构造创建对象.在Spring容器初始化时,通过<bean&g ...

随机推荐

  1. 意味着JNPF迈入新时代的3.4版本,与3.3.3版本有着哪些功能区别呢?

    在线开发‍ 3.3.3版本 同一个功能分功能设计和移动设计 功能设计没有更换模式 功能设计没有同步菜单 功能设计和移动设计无表模式 3.4.1版本 同一个功能可以在功能设计里面设计,根据客户需求自己选 ...

  2. React简单教程-4.1-hook

    前言 虽然我们简单感受了一下 useState 的用法,但我想你还是对 React 里的 hook 迷迷糊糊的.本文我们将明确下 React 的概念. HOOK 前生今世 在我示例中,写的 React ...

  3. QT 基于QScrollArea的界面嵌套移动

    在实际的应用场景中,经常会出现软件界面战场图大于实际窗体大小,利用QScrollArea可以为widget窗体添加滚动条,可以实现小窗体利用滚动条显示大界面需求.实现如下: QT创建一个qWidget ...

  4. LoRa模块无线收发通信技术详解

    LoRa是一种LPWAN通信技术,它基于扩频技术而广泛应用于超长距离的无线传输场景中.现在,LoRa主要在全世界433.868.915MHz等自由频带工作.其最大特征是灵敏度高,传输距离长,工作功耗低 ...

  5. .NET中检测文件是否被其他进程占用

    更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月2日. 一.检测文件是否被进程占用的几种方式 在.NET中主要有以下方式进行检测文件是否被进程占用的几种方式: 通过直接打开文件等 ...

  6. [安洵杯 2019]easy_web-1

    1.首先打开题目如下: 2.观察访问的地址信息,发现img信息应该是加密字符串,进行尝试解密,最终得到img名称:555.png,如下: 3.获得文件名称之后,应该想到此处会存在文件包含漏洞,因为传输 ...

  7. SAP SD-Invoice 销售发票

    针对销售订单的发票流程: 1. 事务码:VF01(个别生成系统发票) 创建开票凭证(发票)/  VF04 开具系统发票(可把多个item 合并成一张系统发票) 2. 事务码:VF02 修改发票, 释放 ...

  8. SAP -SE30 程序运行时间分析

    运行SE30 选中Program,点击Excute 点击运行 分析结果

  9. ppt/word公式LaTeX环境配置

    PPT使用Latex说明 一.下载IguanaTex_v1_57 http://www.jonathanleroux.org/software/iguanatex/download.html Inst ...

  10. 零基础学Java(1)初识Java程序

    前言 就国内来说,Java毫无疑问是后端语言中的No.1没有之一,所以今天我们也来0基础学习Java!!! Java的好处(针对测试工程师) 面试加分->涨薪 大多数公司服务端用的都是Java, ...