Spring 学习笔记

目录

什么是Spring

  • Spring是企业级开发框架,是软件设计层面的框架,优势在于可以将应用程序分层,开发者可以自助选择组件
  • Spring已经成为Java领域行业标准
  • Spring提供了各个层面的解决方案:
    MVC:struts2、Spring MVC
    ORMapping:Hibernate、MyBatis、Spring Date
  • Spring两大核心机制:IoC(控制反转)和AOP(面向切面)

Spring框架两大核心机制(IoC和AOP)

  • Ioc(控制反转)/DI(依赖注入)
  • AOP(面向切面编程)

什么是IoC(控制反转)

传统程序开发中,需要调用对象时,通常由调用者来创建被调用者的实例,即对象是由嗲用着主动new出来的
但在Spring框架中,创建对象的工作不再是由调用者来完成,而是交给IoC容器创建,再推送给调用者,整个流程完成反转,所以说控制反转

如何使用IoC

新建一个maven工程
Spring 学习笔记
在pom.xml中添加依赖
Spring 学习笔记

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>aispringioc</artifactId>
    <version>1.0-SNAPSHOT</version>


    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.0.11.RELEASE</version>
        </dependency>
    </dependencies>
</project>

创建实体类
Spring 学习笔记
此时可以在xml文件中添加lombok依赖,这样实体类可以不用写get/set方法
Spring 学习笔记
实体类中添加此注解Spring 学习笔记
传统开发方式是手动new对象,并且对其进行操作
Spring 学习笔记
通过IoC创建对象,在配置文件中添加需要管理的对象,XML格式的配置文件,文件名可以自定义
新建xml文件于resources目录下
Spring 学习笔记

Spring 学习笔记

其会自动生成这些配置信息
Spring 学习笔记

给对象写如下内容,id就是类的别名,class关联的是创建对象所对应的类地址

<bean id="student" class="com.makerjack.entity.Student">
    <property name="id" value="1"></property>
    <property name="name" value="张三"></property>
    <property name="age" value="22"></property>
</bean>

这也称为属性注入
Spring 学习笔记

然后在测试中如下获取对象信息
Spring 学习笔记

配置文件

通过配置bean标签来完成对象的管理

  • id:对象名
  • class:对象的模板类。(所有交给IoC容器来管理的类,必须有无参构造函数,因为Spring底层通过反射机制来创建对象,调用的是无参构造)

对象的成员变量通过property标签完成赋值

  • name:成员变量名
  • value:成员变量值(基本数据类型,String可以直接赋值,如果是其它引用类型,不能通过value赋值)
  • ref:将IoC的另一个bean赋给当前的成员变量(DI)
    例如给Student对象加一个对象成员变量score
    Spring 学习笔记
    Spring 学习笔记
    Spring 学习笔记

通过有参构造创建bean

以上是通过无参构造来创建对象,其本质是先创建后赋值
以下为通过有参构造函数创建对象,本质是一边创建一边赋值

  • 在实体类中创建对应有参构造
    Spring 学习笔记
    在对象前加这个注解即可

  • 配置文件中写入相关信息

<bean id="student1" class="com.makerjack.entity.Student">
    <constructor-arg name="id" value="2"></constructor-arg>
    <constructor-arg name="name" value="李四"></constructor-arg>
    <constructor-arg name="age" value="25"></constructor-arg>
    <constructor-arg name="score" ref="score"></constructor-arg>
</bean>

其中的name可以省略,其就是按照先后顺序赋值
当省略时,确保传递值的顺序不能错
name也可以换成index,其取值就是0~传递值的个数-1

<bean id="student1" class="com.makerjack.entity.Student">
    <constructor-arg index="0" value="2"></constructor-arg>
    <constructor-arg index="1" value="李四"></constructor-arg>
    <constructor-arg index="2" value="25"></constructor-arg>
    <constructor-arg index="3" ref="score"></constructor-arg>
</bean>

结果
Spring 学习笔记

给bean注入集合

如果有对象的属性为集合性质,需要存储多个同种数据
Spring 学习笔记
那么此处就不能直接引用对象
Spring 学习笔记
需要些成如下形式

<property name="scores">
    <list>
        <ref bean="score-1"></ref>
        <ref bean="score-2"></ref>
    </list>
</property>

Spring 学习笔记
效果如下
Spring 学习笔记

scope作用域

Spring管理的bean是根据scope来生成的,表示bean的作用域,共4种,默认是单例模式

  • singleton:单例,表示通过IoC容器获取的bean是唯一的
  • prototype:原型,表示通过IoC容器获取的bean是不同的
  • request:请求,表示在一次HTTP请求内有效
  • session:会话,表示在一个用户会话内有效
    request和session只适用于Web项目,大多数情况下,使用单例和原型比较多。
    在这里插入图片描述
    测试比如我们在无参构造函数中进行截断观察
    Spring 学习笔记
    Spring 学习笔记
    可以观察到
    prototype模式当业务代码获取IoC容器中的bean时,Spring才去调用无参构造创建对应的bean每次获取都会重新调用(创建一个新的)
    Spring 学习笔记
    可以看到
    signleton模式物理业务代码是否获取IoC容器中的bean,Spring在加载sprig.xml时就会创建对象而且每次调用不会创建新的

Spring的继承

与java的继承不同,java是类层面的继承,子类可以继承父类的内部结构信息,Spring是对象层面的继承,子对象可以继承父对象的属性值
比如stu想继承student的所有属性值
Spring 学习笔记
只需要在后面添加属性“parent”即可

<bean id="stu" class="com.makerjack.entity.Student" parent="student"></bean>

效果就是可以完全继承其全部属性
若想要覆盖某些属性,直接在内部重写属性即可
Spring 学习笔记

<property name="name" value="李四"></property>

效果如下
Spring 学习笔记
即便是不同的对象,如果属性/成员变量一样或 子类属性完全包含父类属性也是可以继承的(继承属性的数值)

Spring的依赖

与继承类似,依赖也是描述bean和bean之间的一种关系,配置依赖之后,被依赖的bean一定先创建,再创建依赖的bean:A依赖于B,则先创建B,后创建A

Spring的p命名空间

p命名空间是对IoC / DI的简化操作,使用p命名空间可以更方便地完成bean的配置以及bean之间的依赖注入
需要在xml文件中添加标签库
Spring 学习笔记

xmlns:p="http://www.springframework.org/schema/p"

在xml中直接在对象内部追加p,即可完成属性赋值,本质是对对象配置的简化

<bean id="student" class="com.makerjack.entity.Student" p:id="1" p:name="盖亚" p:age="23" p:scores-ref="score"></bean>

<bean id="score" class="com.makerjack.entity.Score" p:english="87" p:math="79"></bean>

Spring的工厂方法

IoC通过工厂模式创建bean的方式有两种

  • 静态工厂方法
  • 实例工厂方法

静态工厂方法

不需要实例化工厂,程序启动就会加载到内存当中,只要关注bean即可
首先建立实体类

package com.makerjack.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car {
    private String brand;
    private long id;
    private String color;
    private double price;
    private Date date;
}

然后创建静态工厂方法

package com.makerjack.factory;

import com.makerjack.entity.Car;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class StaticCarFactory {
    private static Map<Long, Car> carMap;
    static {
        carMap = new HashMap<Long, Car>();
        carMap.put(1L,new Car("benz",1L,"red",17.3,new Date()));
        carMap.put(2L,new Car("beck",2L,"white",11.7,new Date()));
    }
    public static Car getCar(long id){
        return carMap.get(id);
    }
}

再编写配置文件

<!-- 配置静态工厂创建car -->
<bean id="car" class="com.makerjack.factory.StaticCarFactory" factory-method="getCar">
    <constructor-arg value="2"/>
</bean>

测试Spring 学习笔记
Spring 学习笔记

实例工厂方法

实例对象依旧如上,实例工厂换成实际的对象,以便后续创建

package com.makerjack.factory;

import com.makerjack.entity.Car;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class InstanceCarFactory {
    private Map<Long, Car> carMap;
    public InstanceCarFactory() {
        carMap = new HashMap<Long, Car>();
        carMap.put(1L,new Car("benz",1L,"red",17.3,new Date()));
        carMap.put(2L,new Car("beck",2L,"white",11.7,new Date()));
        carMap.put(3L,new Car("lenor",3L,"blue",19.5,new Date()));
    }
    public Car getCar(long id){
        return carMap.get(id);
    }
}

xml文件中需要写入2个bean:工厂bean和car bean

<!-- 配置实例工厂 bean -->
<bean id="carFactory" class="com.makerjack.factory.InstanceCarFactory"></bean>
<!-- 配置实例工厂创建car -->
<bean id="car" factory-bean="carFactory" factory-method="getCar">
    <constructor-arg value="3"/>
</bean>

测试
Spring 学习笔记

IoC自动装载(Autowire)

IoC负责创建对象,DI负责完成对象的依赖注入,通过配置property标签的ref属性来完成,同时Spring提供了另外一种更加简便的依赖注入方式:自动装载,不需要手动配置property,IoC容器会自动选择完成注入

自动装载有2种方式:

  • byName:通过属性名自动装载
  • byType:通过属性的数据类型自动装载

比如有个person对象
Spring 学习笔记

以往是在此处引用先前创建的对象
Spring 学习笔记
自动装载就可以自动匹配现有的

byName是匹配同名对象,当有同名就会匹配不到(不会报错)Spring 学习笔记
byType是匹配同类的,当有同种就会抛出异常
Spring 学习笔记



上一篇:Spring中的IoC和DI简介


下一篇:实现IOC容器