Spring框架学习笔记(一):Spring基本介绍(包含容器底层结构)

news2024/12/23 18:28:28

1 官方资料 

1.1 官网

https://spring.io/

1.2 进入 Spring5

下拉 projects, 进入 Spring Framework

进入 Spring5 github

1.3 在maven项目中导入依赖

<dependencies>
    <!--加入spring开发的基本包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.8</version>
    </dependency>
    <!--加入spring开发切面编程需要的包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.3.8</version>
    </dependency>
</dependencies>

 1.4 官方文档

在线文档 : https://docs.spring.io/spring-framework/docs/current/reference/html/
线: spring-framework-5.3.8\docs\reference\html\index.html
线API:spring-framework-5.3.8/docs/javadoc-api/index.html

Spring核心内容

上图说明:

(1)Spring 核心学习内容 IOC AOP, jdbcTemplate, 声明式事务
(2)IOC: 控制反转 , 可以管理 java 对象
(3)AOP : 切面编程
(4)JDBCTemplate : spring 提供一套访问数据库的技术
(5) 声明式事务 : 基于 ioc/aop 实现事务管理
(6)IOC, AOP 是重点和难点

3 Spring的几个重要概念

(1)Spring 可以整合其他的框架(Spring 是管理框架的框架)

(2)Spring 有两个核心的概念: IOC AOP

(3)IOC(Inversion Of Control 反转控制)

  • 传统的开发模式[JdbcUtils / 反射]

程序------>环境(程序读取环境配置,然后自己创建对象.)

解读:程序员编写程序, 在程序中读取配置信息;创建对象, new 或者 反射方式;使用对象完成任务

  • IOC 的开发模式 [EmpAction EmpService EmpDao Emp] 

程序<-----容器(容器创建好对象,程序直接使用.)

解读: 

1 Spring 根据配置文件 xml/ 注解 创建对象, 并放入到容器 (ConcurrentHashMap) , 并且可以完成对象之间的依赖
2 、当需要使用某个对象实例的时候 , 就直接从容器中获取即可
3 、程序员可以更加关注如何使用对象完成相应的业务
4. DI—Dependency Injection 依赖注入,可以理解成是 IOC 的另外叫法 .
5. Spring 最大的价值,通过配置,给程序提供需要使用的
web [Servlet (Action/Controller) ]/Service/Dao/[JavaBean/entity] 对象 ,
这个是核心价值所在,也是 ioc 的具体体现 , 实现解耦.

4 Spring快速入门

4.1 需求说明

通过 Spring 的方式( 配置文件) ,获取 JavaBean: Monster 的对象,并给该对象属性赋值,输出该对象信息.

4.2 实现步骤

(1)创建一个maven项目,在pom.xml文件中导入以下依赖

<dependencies>
    <!--加入spring开发的基本包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.8</version>
    </dependency>
    <!--加入spring开发切面编程需要的包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>5.3.8</version>
    </dependency>
</dependencies>

(2) 创建 Moster 的javabean/entity,无参构造器一定要写

public class Monster {
    private Integer monsterId;
    private String name;
    private String skill;

    //全参构造器
    public Monster(Integer monsterId, String name, String skill) {
        this.monsterId = monsterId;
        this.name = name;
        this.skill = skill;
    }


    //无参构造器一定要写,Spring反射创建对象时,需要使用
    public Monster() {
    }

    public Integer getMonsterId() {
        return monsterId;
    }

    public void setMonsterId(Integer monsterId) {
        this.monsterId = monsterId;
    }

    public String getName() {
        return name;
    }

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

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }

    @Override
    public String toString() {
        return "Monster{" +
                "monsterId=" + monsterId +
                ", name='" + name + '\'' +
                ", skill='" + skill + '\'' +
                '}';
    }
}

(3) 新建一个容器配置文件:鼠标右键目录名 --> new --> XML Configuration --> Spring Config,然后给配置文件取个名字,这里取beans(对于Maven项目XML文件通常在 src/main/resources 目录)

点击 创建 Spring facet ,然后点击确定

 

 (4)在xml文件中配置Moster对象,在beans标签加入以下配置

 注意:将class属性值修改为指定类的全路径

<!--
        1. 配置monster对象/javabean
        2. 在beans中可以配置多个bean
        3. 一个bean表示就是一个java对象
        4. class属性是用于指定类的全路径->spring底层使用反射创建
        5. id属性表示该java对象在spring容器中的id, 通过id可以获取到对象
        6. <property name="monsterId" value="100"> 用于给该对象的属性赋值
-->
<bean class="com.spring.bean.Monster" id="monster01">
    <property name="monsterId" value="100"/>
    <property name="name" value="牛魔王"/>
    <property name="skill" value="芭蕉扇"/>
</bean>

<bean class="com.spring.bean.Monster" id="monster02">
    <property name="monsterId" value="1001"/>
    <property name="name" value="牛魔王~"/>
    <property name="skill" value="芭蕉扇~"/>
</bean>

(5)新建一个测试类来获取容器中的对象

public class SpringBeanTest {

    @Test
    public void getMonster(){

        //1. 创建容器 ApplicationContext
        //2. 该容器和容器配置文件关联
        ApplicationContext ioc =
                new ClassPathXmlApplicationContext("beans.xml");

        //3. 通过getBean获取对应的对象
        //   默认返回的是Object , 但是运行类型Monster
        //Object monster01 = ioc.getBean("monster01");
        Monster monster01 = (Monster) ioc.getBean("monster01");

        //4. 输出
        System.out.println("monster01=" + monster01 + " 运行类型=" + monster01.getClass());
        System.out.println("monster01=" + monster01 + "属性name=" + monster01.getName() +
                " monserid=" + monster01.getMonsterId());


        //5. 也可以在获取的时候,直接指定Class类型, 可以再次获取
        Monster monster011 = ioc.getBean("monster01", Monster.class);
        System.out.println("monster011=" + monster011);
        System.out.println("monster011.name=" + monster011.getName());


        //6. 查看容器注入了哪些bean对象,会输出bean的id
        System.out.println("================================");
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println("beanDefinitionName=" + beanDefinitionName);
        }
        System.out.println("================================");

        System.out.println("ok~~~");
    }
}

运行结果:

4.3 注意事项

(1)该代码为什么读取到beans.xml文件

ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");

该代码通过类路径加载配置文件,可通过以下方式输出类加载路径

File f = new File(this.getClass().getResource("/").getPath());
System.out.println(f);

maven项目的类加载路径是:target\classes

(2)debug 看看 spring 容器结构/机制

 

(3) 当调用getBean(),方法获取对象时,会去beanDefinitionMap中去查找,如果发生该bean是单例的,就会返回 singletonobject 中初始化好了的对象,如果不是,就会动态的通过反射机制返回一个临时创建的对象

 5 实现简单的基于XML配置的Spring

5.1 需求说明

(1)自己写一个简单的 Spring 容器, 通过读取 beans.xml,获取第 1 个 JavaBean: Monster 的
对象,并给该的对象属性赋值,放入到容器中, 输出该对象信息
(2)也就是说,不使用 Spring 原生框架,我们自己简单模拟实现

5.2 思路分析

(1)使用xml的解析技术-Dom4j
(2)读取beans.xml
(3)解析得到monster对象的id,classpath,属性
(4)使用反射,创建对象
(5)放入到ioc容器(hashmap)
(6)提供一个getBean方法

5.3 实现步骤

(1)在maven项目中添加dom4j依赖

第一种方式:如果导入低版本(1.6.1),需要如下两个依赖

<dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
</dependency>
<dependency>
            <groupId>jaxen</groupId>
            <artifactId>jaxen</artifactId>
            <version>1.1.1</version>
</dependency>

第二种方式:如果导入高版本(2.0.0),需要如下一个依赖

<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.0.0</version>
</dependency>

(2)实现容器类 WwjApplicationContext,java

注意:项目系统目录不能有中文,或者会找不到XML文件

package com.spring.wwjApplicationContext;

import com.spring.bean.Monster;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 1. 这个程序用于实现Spring的一个简单容器机制
 * 2. 这里实现如何将beans.xml文件进行解析,并生成对象,放入容器中
 * 3. 提供一个方法 getBean(id) 返回对应的对象
 */
public class WwjApplicationContext {

    private ConcurrentHashMap<String, Object> singletonObjects =
            new ConcurrentHashMap<>();


    //构造器
    //接收一个容器的配置文件 比如 beans.xml, 该文件默认在resources
    public WwjApplicationContext(String iocBeanXmlFile) throws Exception {

        //1. 得到类加载路径
//        String path = this.getClass().getClassLoader().getPath();
        String path = this.getClass().getResource("/").getPath();

        //2. 创建 Saxreader
        SAXReader saxReader = new SAXReader();

        //3. 得到Document对象
        Document document =
                saxReader.read(new File(path + iocBeanXmlFile));

        //4. 得到rootDocument
        Element rootElement = document.getRootElement();

        //5. 得到第一个bean-monster01
        Element bean = (Element) rootElement.elements("bean").get(0);

        //6. 获取到第一个bean-monster01的相关属性
        String id = bean.attributeValue("id");
        String classFullPath = bean.attributeValue("class");
        List<Element> property = bean.elements("property");
        //遍历
        Integer monsterId =
                Integer.parseInt(property.get(0).attributeValue("value"));

        String name = property.get(1).attributeValue("value");
        String skill = property.get(2).attributeValue("value");

        //7. 使用反射创建对象.=> 回顾反射机制
        Class<?> aClass = Class.forName(classFullPath);
        //这里o对象就是Monster对象
        Monster o = (Monster) aClass.newInstance();
        //给o对象赋值
        o.setMonsterId(monsterId);
        o.setName(name);
        o.setSkill(skill);

        //8. 将创建好的对象放入到singletonObjects
        singletonObjects.put(id, o);

    }

    public Object getBean(String id) {
        return singletonObjects.get(id);
    }
}

(3)创建main类测试

package com.spring;

import com.spring.bean.Monster;
import com.spring.wwjApplicationContext.WwjApplicationContext;

public class AppMain {
    public static void main(String[] args) throws Exception {
        WwjApplicationContext ioc = new WwjApplicationContext("beans.xml");
        Monster monster01 = (Monster)ioc.getBean("monster01");
        System.out.println("monster01 = " + monster01);
    }
}

运行结果:

Spring 原生容器底层结构

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1648722.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ISIS的工作原理

1.邻居关系建立 &#xff08;1&#xff09;IS-IS领接关系建立原则 1、通过将以太网接口模拟成点到点接口&#xff0c;可以建立点到点链路邻接关系。 2、当链路两端IS-IS接口的地址不在同一网段时&#xff0c;如果配置接口对接收的Hello报文不作IP地址检查&#xff0c;也可以建…

解决github的remote rejected|git存储库的推送保护

前言 git存储库的推送保护。当你试图推送代码到GitHub仓库时&#xff0c;由于存在与主分支&#xff08;master&#xff09;相关的仓库规则违规行为&#xff0c;推送会被拒绝了。这种保护机制帮助确保只有经过授权和符合规定的代码才能被合并到主分支&#xff0c;从而保护了主分…

【LeetCode刷题】410. 分割数组的最大值

1. 题目链接2. 题目描述3. 解题方法4. 代码 1. 题目链接 410. 分割数组的最大值 2. 题目描述 3. 解题方法 题目中提到的是某个和的最大值是最小的&#xff0c;这种题目是可以用二分来解决的。 确定区间&#xff0c;根据题目的数据范围&#xff0c;可以确定区间就是[0, 1e9]…

省份数量00

题目链接 省份数量 题目描述 注意点 1 < n < 200isConnected[i][j] 为 1 或 0isConnected[i][i] 1isConnected[i][j] isConnected[j][i] 解答思路 最初想到的是广度优先遍历&#xff0c;当某个城市不属于省份&#xff0c;需要从该城市开始&#xff0c;根据isConne…

直说了,你可能从没真正理解MPLS

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 你们好&#xff0c;我的网工朋友。 尽管 MPLS 技术已经相当成熟&#xff0c;有关它的文章数不胜枚举&#xff0c;涵盖了从基本原理到 SR-MPLS 等…

卸载系统自带APP

Firefly RK3588 android 12自动多个系统软件&#xff0c;无法从UI界面进行手动删除。因此&#xff0c;考虑使用shell指令进行处理。 系统自动APP大多都安装在system/app目录下&#xff0c;且该目录多为只读。因此采用如下步骤&#xff0c; //Shell su adb shell su //重新挂载…

【前端】HTML基础(2)

文章目录 前言一、HTML常见标签1、 注释标签1.1 标题标签1.2 段落标签1.3 换行标签 2、 格式化标签2.1 加粗标签2.2 倾斜标签2.3 删除线标签2.4 下划线标签 3、 图片标签3.1 src属性3.2 alt属性3.3 title属性3.4 图片大小3.5 图片边框 4、 超链接标签4.1 属性4.2 属性 前言 这篇…

从项目开始学习Vue——02(若依框架)

往期&#xff1a; 从项目开始学习Vue——01 目录标题 一、基础插件&#xff08;一&#xff09;路由Vue Router&#xff08;二&#xff09;导航守卫&#xff08;路由拦截器&#xff09;二、Vuex&#xff08;一&#xff09;什么是VuexVuex的部分介绍内容&#xff1a; &#xff08…

antdVue 自定义table列配置

最近做项目的时候需要对页面的table进行列配置的需求 子组件 <div><a-modaltitle"列配置" :visible"visible" :closable"false" :footer"null"width"800px" height"448px"><div><a-row>…

多C段的美国站群服务器有什么用途?

多C段的美国站群服务器有什么用途? 多C段的美国站群服务器是一种常见的网络运营策略&#xff0c;其用途主要体现在以下几个方面&#xff1a; 多C段的美国站群服务器有什么用途? 1. 提高站点排名和流量 部署多个站点在不同的C段IP地址上&#xff0c;可以通过不同的IP地址发布…

linux - 主次设备号自动申请

alloc_chrdev_region 原型如下&#xff0c;该函数向内核申请一个空闲的主设备号。 alloc_chrdev_region(&g_aputriger_dev, 0, APUTRIGER_MAX_NUM, "aputriger0"); 第四个参数是我们使用cat /proc/devices 看到的名称 /*** alloc_chrdev_region() - register a…

外包干了2年,人都要废了。。。

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号【互联网杂货铺】&#xff0c;回复 1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 简单的说下&#xff0c;我大学的一个同学&#xff0c;毕业后我自…

程序员技术文档编写神器Typora【图文详情】

文章目录 前言一、Typora是什么&#xff1f;二、如何安装三、如何使用总结 前言 在软件项目开发过程中&#xff0c;需要进行开发设计&#xff0c;编写相关的开发设计文档&#xff0c;本文介绍一下编写开发设计文档的神器Typora。 一、Typora是什么&#xff1f; Typora 是一款…

SinoDB数据库导入导出工具External table

External table又叫SinoDB外部表&#xff0c;外部表采用多线程机制&#xff0c;支持多线程读取、写入数据文件以及多线程数据转换、插入操作。多线程机制只需要消耗相对较少的系统资源&#xff0c;但是能提供高速数据导入、导出&#xff0c;可以应用在数据采集、表重建、数据库…

04-xss获取cookie实验

二、开发XSS服务器端 1、确认实验环境 攻击者服务器&#xff1a;192.168.74.134&#xff0c;将获取到cookie数据保存到该服务器的数据库中&#xff0c;运行PHP代码暴露一个接收Cookie的URL地址。 正常Web服务器&#xff1a;192.168.74.133&#xff0c;用于正常的用户访问的目…

java编程中,实现分页对象的类型转换

一、背景 当数据库分页查询返回的对象与接口要返回的对象类型不一致时&#xff0c;不可避免需要进行类型转换。 示例&#xff1a;数据库分页查询返回的对象是PageDTO&#xff0c;而接口返回的对象类型是PageVO。 PageDTO Data public class PageDTO<T> {/*** Current…

Android 巧用putBinder方法传递大文件

使用Intent传递数据大家都知道&#xff0c;但是如果你使用Intent传递大于1Mb的数据时&#xff0c;就一定会报如下的错误&#xff1a; Caused by: android.os.TransactionTooLargeException: data parcel size 1049112 bytes 就是说你的传输数据太大了&#xff0c;当前的大小达…

【C++】滑动窗口:将x减到0的最小操作数

1.题目 2.算法思路 这个题目难在要转化一下才能用滑动窗口。 题意是需要在数组的前后两段区间进行解题&#xff0c;但同时对两段区间进行操作是比较困难的&#xff0c;我们可以将中间这段区间只和与nums_sum-x&#xff08;数组总和-x&#xff09;进行比较&#xff0c;这样就可…

数据库(MySQL)—— DML语句

数据库&#xff08;MySQL&#xff09;—— DML语句 什么是DML语句添加数据给全部字段添加数据批量添加数据 修改数据删除数据 什么是DML语句 在MySQL中&#xff0c;DML&#xff08;Data Manipulation Language&#xff0c;数据操纵语言&#xff09;语句主要用于对数据库中的数…

Django 4.x 智能分页get_elided_page_range

Django智能分页 分页效果 第1页的效果 第10页的效果 带输入框的效果 主要函数 # 参数解释 # number: 当前页码&#xff0c;默认&#xff1a;1 # on_each_side&#xff1a;当前页码前后显示几页&#xff0c;默认&#xff1a;3 # on_ends&#xff1a;首尾固定显示几页&#…