Java开发——Spirng 5入门(一)

简介

本文是基于狂神说java的教学视频的,希望记录自己的学习过程,同时也欢迎大家交流。
  spring是一个开源且免费的框架,主要用于解决web应用开发。其特点是轻量级且非侵入式

  spring两个核心概念是:支持控制翻转(IOC)和面向切片编程(AOP)。同时,由于这两个特性,使得其对事务的支持性极强。
Spring的组成模块如下:source


在这里插入图片描述

我们常用的功能包括:

  1. spring Boot:
    1. 快速开发的脚手架
    2. 构建单个微服务
  2. spring cloud
    1. 是基于spring boot实现的
    2. 协调各个微服务

学习spring和springMVC是掌握spring boot的基础。

核心知识点

  在没有学习spring之前就听说过大名鼎鼎的IOC和AOP这两个spring和核心概念。下面来详细了解一下。

1. IOC

所谓控制翻转是指的依赖对象的方式反转了。之前对象的创建是依赖于代码的编写,控制反转的思想就是,将对象创建的过程交给用户,由用户自己来决定使用什么样的对象。作为程序的设计者,只需要为用户提供相应的接口实现即可。其中使用到的是:

  • set接口
  • 设计思想:工厂模式
    在这里插入图片描述(图片来自网络)
      IOC保证了我们不需要再对程序进行任何的修改了,只需要修改xml文件,对象的完全托付给spring进行管理。

2. Hello Spring 测试案例

过程说明:

  1. 使用maven创建项目;
  2. 导入spring依赖;
  3. 创建测试实体类;
  4. 创建spring核心配置文件;
  5. 测试spring对象管理功能。
    项目结果如下:
    在这里插入图片描述

2.1 使用maven创建项目

使用maven创建一个新的空项目,将项目中的src目录删除,并在项目下新建模块。在子模块的基础上进行测试。

2.2 导入spring依赖

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.2</version>
        </dependency>
    </dependencies>

2.3 编写测试实体类

package com.yindarui.POJO;
public class Hello {
    private String str;
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                ", id=" + id +
                '}';
    }
}

2.4 编写spring的核心配置文件:applicationContext.xml

这里我们只使用property标签来为对象赋值。

<?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 IOC的核心,即容器管理对象,将对象创建的过程变得透明-->
    <!--id是你绑定的对象在容器中的名称,在使用时我们只需要指定该对象在容器中的名字就可以创建该对象,过程可以理解为如下:
        Hello hello = new hello();
    -->
    <bean id="hello" class="com.yindarui.POJO.Hello">
        <!--property是bean的子元素,str就是HelloSpring里的str变量,张三就是给str变量赋的值-->
        <property name="str" value="张三"/>
        <property name="id" value="123"/>
    </bean>
</beans>

2.5 测试类

package HelloSpringTest;

import com.yindarui.POJO.Hello;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test1 {
    @Test
    public void test() {
//        加载配置文件,即获取容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//        通过context来获取对象
        Hello hello = (Hello) context.getBean("hello");
//        查看对象的值是否被修改了
        System.out.println(hello.toString());

    }
}

2.6 结果

Hello{str='张三', id=123}

2.7 执行原理

  spring创建对象的原理是:
1. 对于一个没有有参构造的类,spring将利用该类无参构造来初始化对象,且利用property标签调用该类的set方法来为对象赋值。
2. 对于一个含有 有参构造的类由于有参构造会覆盖无参构造,此时无法正常利用默认无参构造初始化对象,则会报错。此时需要使用spring使用constructor-arg 标签来创建对象。

<?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 IOC的核心,即容器管理对象,将对象创建的过程变得透明-->
    <!--id是你绑定的对象在容器中的名称,在使用时我们只需要指定该对象在容器中的名字就可以创建该对象,过程可以理解为如下:
        Hello hello = new hello();
    -->
    <bean id="hello" class="com.yindarui.POJO.Hello">
<!--        name是指定的构造函数中的参数名-->
        <constructor-arg name="str" value="李四"/>
<!--        id是指定的构造函数的参数的位置,从零开始-->
        <constructor-arg index="1"  value="1"/>
<!--        采用ref的方式使得我们不需要显示的指定构造函数参数的索引或类型-->
        <constructor-arg ref="tele"/>
    </bean>
    <bean id="tele" class="java.lang.String"/>
</beans>

结果:

// 注意这里的tel的默认参数是空字符串,而不是null
Hello{str='李四', id=1, tel=''}

2.8 对象何时被创建

测试:

  1. 在实体类的构造函数中添加输出语句;
  2. 在context对象创建前添加输出语句;
  3. 在context对象创建后添加输出语句;
    测试类:
package HelloSpringTest;

import com.yindarui.POJO.Hello;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 *
 */
public class Test1 {
    @Test
    public void test() {
        System.out.println("context object will be created then!");
//        加载配置文件,即获取容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("context object is created!");
//        通过context来获取对象
        Hello hello = (Hello) context.getBean("hello");
        Hello hello2 = (Hello) context.getBean("hello");
        System.out.println(hello == hello2 ? "两个引用指向的是同一个对象": "两个引用指向的不是同一个对象");
//        查看对象的值是否被修改了
        System.out.println(hello.toString());

    }
}

结果:

构造函数被创建
context object is created!
两个引用指向的是同一个对象
Hello{str='李四', id=1, tel=''}

分析:使用spring管理对象时,对象会在用户加载这个配置文件时被创建,用户使用只需要知道自己要使用的类在容器中的名称即可。同时,每个对象在一个容器中只有一份

3. 配置文件

3.1 别名

bean起的别名。

 <alias name="hello" alias="hello2"/>

3.2 Bean

   <!-- id——bean的唯一标识符
    class——bean绑定的类的全限定名
    name——起别名,使用空格分隔来以起多个别名 -->
    <bean id="h1" class="java.lang.String" name="ss1 ss2" />

3.3 import

  将多个编写的applicationContext.xml合并为一个总的。
在这里插入图片描述

4. 依赖注入(dependency injection DI)

  bean对象的创建依赖于容器,bean对象的所有属性,由容器来注入。其实就是按照配置文件的方式对类进行初始化,根据不同的类型大致有以下几种:

  • 基本数据类型
  • 引用数据类型
  • 集合
  • 列表
  • map
    准备测试的类:
package com.yindarui.POJO;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 *
 */
public class DependencyInjectionTest {
    private int id;
    private String name;
    private Map<String, Integer> score;
    private int[] nums;
    private String[] strs;
    private List<String> list;
    private Set<String> set;

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setScore(Map<String, Integer> score) {
        this.score = score;
    }

    public void setNums(int[] nums) {
        this.nums = nums;
    }

    public void setStrs(String[] strs) {
        this.strs = strs;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Map<String, Integer> getScore() {
        return score;
    }

    public int[] getNums() {
        return nums;
    }

    public String[] getStrs() {
        return strs;
    }

    public List<String> getList() {
        return list;
    }

    public Set<String> getSet() {
        return set;
    }

    @Override
    public String toString() {
        return "DependencyInjectionTest{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", score=" + score +
                ", nums=" + Arrays.toString(nums) +
                ", strs=" + Arrays.toString(strs) +
                ", list=" + list +
                ", set=" + set +
                '}';
    }
}

4.1 构造器注入

4.2 set方式注入

配置文件:
<?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="testName" class="java.lang.String"/>
    <bean id="DITest" class="com.yindarui.POJO.DependencyInjectionTest">
<!--     1.普通值注入-->
        <property name="id" value="1"/>
<!--        2. bean注入, 注入的是另一个bean ref-->
        <property name="name" ref="testName"/>
<!--        3. 注入map集合,注入的是一个键值对-->
        <property name="score">
            <props>
                <prop key="语文">100</prop>
                <prop key="数学">100</prop>
                <prop key="英语">60</prop>
            </props>
        </property>
<!--        4. 注入基本类型数组-->
        <property name="nums">
            <array>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </array>
        </property>
        <property name="strs">
            <array>
<!--                直接赋值-->
                <value>"我是一个元素"</value>
<!--                使用ref赋值-->
                <ref bean="listBean"/>
            </array>
        </property>
<!--        5. 注入list集合,为引用数据类型-->
        <property name="list">
            <list>
                <value>"好好学习"</value>
                <ref bean="listBean"/>
            </list>
        </property>
<!--        6. 注入set集合, 为引用数据类型-->
        <property name="set">
            <set>
                <value>2</value>
                <value>3</value>
<!--                这个值是无法加入的,set元素不可重复-->
                <value>3</value>
            </set>
        </property>
    </bean>
    <bean id="listBean" class="java.lang.String"/>
</beans>
测试方法
    @Test
    public void testForDI() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "DITest.xml");
        DependencyInjectionTest diTest = (DependencyInjectionTest) context.getBean("DITest");
        System.out.println(diTest.toString());
        System.out.println(diTest.getStrs()[1] == diTest.getList().get(1));
    }

测试结果
DependencyInjectionTest{id=1, name='', score={数学=100, 语文=100, 英语=60}, nums=[1, 2, 3], strs=["我是一个元素", ], list=["好好学习", ], set=[2, 3]}
// 注意,list中第二个空字符串和strs中第二个空字符串同一个对象
true

4.3 其他方式注入

  spring中提供了俩种快捷的注入方式:

  • c命名空间注入:要求类中有有参构造。
  • p命名空间注入:要求类中有有效的无参构造,代替了property标签,在bean标签中直接为参数注入值;
      命名空间的使用要求导入约束:
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"

5. bean作用域

作用域中文描述
singleton单例(默认)对于一个对象,整个容器中保留一份
prototype原型将单个bean定义定义为任意数量的对象实例
reques请求
session一个session中
application整个web程序
websocket一个socket中

单例

在这里插入图片描述

原型

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值