Java之spring新手教程(包教包会)

2023-10-27

Java-Spring(一)之IoC以及bean的生命周期

文章目录


一、什么是Spring

在这里插入图片描述
这是度娘上的比较官方的解释。
说得更加详细一点,Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架,由Rod Johnson在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为J2EE应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式)轻量级开源框架。

二、Spring的核心

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。

轻量——从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。

控制反转——Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。

面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。

容器——Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。

框架——Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。
所有Spring的这些特征使你能够编写更干净、更可管理、并且更易于测试的代码。它们也为Spring中的各种模块提供了基础支持。

三、什么是耦合

简单来讲耦合指的就是两个类之间的联系的紧密程度
最简单的例子就是我些了一段代码,而在另外一个地方又写了一遍差不了太对的代码。这样可以成为耦合度高。

在java编程的过程中,我们尽量要避免重复的造轮子,应运而生的框架就诞生了,Spring就能够做到解耦合。

四、spring项目的搭建

这里我是用的是maven仓库来添加的依赖
把以下依赖加入pom文件中

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.20</version>
      <scope>provided</scope>
    </dependency>
 <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.3.3</version>
          </dependency>
          <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.9</version>
          </dependency>
          <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.3.8</version>
          </dependency>
          <!-- https://mvnrepository.com/artifact/taglibs/standard -->
          <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
          </dependency>

这就是我们spring所需要的基础的依赖

五、配置文件

在资源文件包下建立一个XML文件作为我们spring的一个配置文件

六、IoC(控制反转)

在基本的项目搭建完成之后,我们就要先来了解Spring的核心之一:
IoC(控制反转)
在我们以前的程序书写中,我们用到对象大都是以new的方式去创建对象:
以前学到创建对象的方式
1、new
2、反射
3、序列化

那么Spring给我们提供的一种全新的创建对象的方式。
我们可以把创建对象的工作全部交给Spring来给我们完成
这个就叫做IoC
比如:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Person {
    private String name;
    private Car car;
    private List<String> list;
}

我这里有一个对象,那么我们要创建对象就可以去配置文件中书写

<bean id="per" class="pojo.Person" p:name="张三" p:car-ref="car" p:list-ref="list1"/>

来表示我们创建的对象,以及相应的赋值

在主方法中调用

  ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) ac.getBean("per");

以getBean()的方式来获取我们的bean对象

七、属性注入的方式

1、设值注入

<!--	set 注入(设值注入)  spring 调用对象中set方法
		简单类型注入
		<property name="属性名" value="值"/>
-->
	<bean id="user" class="pojo.User">
		<property name="userName" value="张三"/>
		<property name="password" value="123456"/>
		<property name="role" ref="role"/>
	</bean>

这其实就是简单的调用set方法来给属性赋初值,如果在类中没有set方法,就会出现异常

2、构造方法注入

<!--	构造注入  调用有参构造方法   声明对象不用关心顺序,二次扫描-->
	<bean id="user1" class="pojo.User">
		<constructor-arg name="userName" value="李四"/>
		<constructor-arg name="password" value="654321"/>
		<constructor-arg name="role" ref="role"/>
	</bean>

顾名思义,和设置注入一样就是通过构造器去给属性赋值,同set一样,也是必须要有有参构造方法的书写的。

八、DI(依赖注入)

IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency IInjection,依赖注入)来实现的。

比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。

其实在上面的例子中我们也用到了DI,

<constructor-arg name="role" ref="role"/>

这里的User也依赖与我们的Role的一个对象,

所以我们要在配置文件中添加一个新的Bean对象。

	<bean id="user" class="pojo.User">
		<property name="userName" value="张三"/>
		<property name="password" value="123456"/>
		<property name="role" ref="role"/>
	</bean>
<!--	对象注入  -->
	<bean id="role" class="pojo.Role">
		<property name="roleName" value="openlab"/>
	</bean>

注意:在我们DI的过程中我们是不需要去注意Bean对象的顺序,spring会进行二次扫描,来创建我们需要有依赖的对象。

九、集合属性的注入

其实集合也是一种对象我们可以通过DI的方式去注入集合属性

1、内部注入

<bean id="per" class="pojo.Person" p:name="张三" p:car-ref="car">
		<property name="list">
			<list>
				<value>123</value>
				<value>123</value>
				<value>123</value>
			</list>
		</property>
	</bean>

在我们的Bean对象的内部去注入我们的属性<list>就是我们注入的集合类型

set集合 map映射改这里就行

			<map>
				<entry key="1" value="123"></entry>
			</map>

由于map是以键值对的形式存储的,我们在给值的同时,也要以entry来给值

2、外部注入

这里我们就要用到我们的头部文件,

xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">

就能在我们xml配置文件中来用到我们的util工具

<util:list id="list1">
			<value>123</value>
			<value>123</value>
			<value>123</value>
	</util:list>

十、Spring管理Bean的作用域

spring bean作用域的作用域有5种
Spring Bean 中所说的作用域,在配置文件中即是“scope”

1、singleton(单实例)

是默认的作用域
在不配置scope时我们创建的对象时单例的

 Person person = (Person) ac.getBean("per0");
        Person person1 = (Person) ac.getBean("per0");
        Person person2 = (Person) ac.getBean("per0");
        Person person3 = (Person) ac.getBean("per0");

在这里插入图片描述
所有对象的地址相同

2、prototype

修改scope的值为prototype之后
在这里插入图片描述
就变成了不同的对象

3、request

Request作用域针对的是每次的Http请求,Spring容器会根据相关的Bean的
定义来创建一个全新的Bean实例。而且该Bean只在当前request内是有效的。

4、session

针对某个HTTP Session,Spring容器会根据userPreferences bean定义创建一个全新的userPreferences bean实例, 且该userPreferences bean仅在当前HTTP Session内有效。 与request作用域一样,你可以根据需要放心的更改所创建实例的内部状态,而别的HTTP Session中根据userPreferences创建的实例, 将不会看到这些特定于某个HTTP Session的状态变化。 当HTTP Session最终被废弃的时候,在该HTTP Session作用域内的bean也会被废弃掉。

5、global session

global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session的概念,它被所有构成某个portlet web应用的各种不同的portlet所共享。在global session作用域中定义的bean被限定于全局portlet Session的生命周期范围内。

十一、Bean的生命周期

1、五步

1、构造
2、set赋值
3、初始化
4、对象获取到了
5、销毁

这里我们要重写init方法和destroy方法

public class BeanLife {
    private String name;

    public BeanLife () {
        System.out.println("无参构造");
    }

    public void setName (String name) {
        System.out.println("Set");
        this.name = name;
    }
    public void init(){
        System.out.println("init");
    }
    public void destroy(){
        System.out.println("destroy");
    }
}

执行结果为
在这里插入图片描述

2、七步

在Bean创建对象的时还有一种在前后插入方法的类

public class BeanLife1 implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException {
        System.out.println("之前");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException {
        System.out.println("之后");
        return bean;
    }
}


<bean class="pojo.BeanLife" id="beanLife" p:name="张三" init-method="init" destroy-method="destroy"/>
	<bean class="pojo.BeanLife1" id="beanLife1"/>

我们创建BeanLife时就会出现

在这里插入图片描述
1、构造
2、set赋值
3、之前插入方法
4、初始化
5、对象获取到了
6、之后回去方法
7、销毁

十二、Bean的两种方式

1、创建普通Bean对象

就是最普通的创建普通Bean对象

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext1.xml");
        Person person = ac.getBean("factory",Person.class);
        person.setName("lili");
        System.out.println(person);

2、创建工程Bean工厂

public class Factory implements FactoryBean<Person> {
    @Override
    public Person getObject () throws Exception {
        return new Person();
    }

    @Override
    public Class<?> getObjectType () {
        return Person.class;
    }
}

然后来通过工厂来创建队形的实例

最后

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

小编已加密:aHR0cHM6Ly9kb2NzLnFxLmNvbS9kb2MvRFVrVm9aSGxQZUVsTlkwUnc==出于安全原因,我们把网站通过base64编码了,大家可以通过base64解码把网址获取下来。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java之spring新手教程(包教包会) 的相关文章

随机推荐

  • iText包对每页pdf文件加水印

    https ishare iask sina com cn f 31zwqlKmIwM html
  • 用户编写的python程序、无需修改就可以_python的笔记(一)

    Python的基本特点一种动态解释型的编程语言 规范的代码 Python 采用强制缩进的方式使得代码具有极佳的可读性 高级语言特性 封装内存管理等 可移植性 程序如果避免使用依赖于系统的特性 那么无需修改就可以在任何平台上运行 解释性 直接
  • 带你入门TypeScript

    一 为何学习TS 1 TypeScript 在社区的流行度越来越高 它非常适用于一些大型项目 也非常适用于一些基础库 极大地帮助我们提升了开发效率和体验 2 TypeScript 可以编译出纯净 简洁的 JavaScript 代码 并且可以
  • python画玫瑰图_python windrose(风玫瑰图)

    conda install c https conda anaconda org conda forge windrose b 用pip install windrose可以成功 但是安装的路径 python找不到 from windros
  • 多表联查优化

    多表联查优化我总结有以下几点 优化sql语句 索引优化 反范式设计 业务代码优化 使用缓存 优化sql语句 sql性能分析 查看执行频次 查看执行频次 select insert delete update shwo global sess
  • Python应该怎么学,如何系统地自学Python?

    这是一份kaggle上的银行的数据集 研究该数据集可以预测客户是否认购定期存款y 这里包含20个特征 1 分析框架 2 数据读取 数据清洗 导入相关包 import numpy as np import pandas as pd 读取数据
  • 厉害了,用 Java 也能实现图片识别!

    点击上方 Java基基 选择 设为星标 做积极的人 而不是积极废人 源码精品专栏 原创 Java 2020 超神之路 很肝 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 Rock
  • VS2010 编译 sqlite3 生成动态库和链接库

    如果想以dll的方式使用sqlite而新建空的dll工程 添加sqlite源文件 会发现能生成dll 但缺乏lib函数信息映射库 单独使用dll文件是比较麻烦的 而网上多数做法是通过lib exe手动生成lib 这当然不是我想要的 结合几篇
  • 给NVMe设备发送一个SCSI READ_10命令

    0 READ 10命令 READ 6命令只能支持块大小为512B设备的2GB范围的寻址 因此官方推荐将READ 6迁移到READ 10 READ 10具有2TB的寻址能力 对于800G的NVMe设备来说当然是极好的 其实READ 10具有更
  • 【解决】手机安卓已经导入burp证书,但仍提示此证书并非来自被信任的机构

    安卓手机已经安装burpsuite证书 但app应用软件仍无法访问https联网 浏览器可以访问http但https提示此证书并非来自被信任的机构 这问题应该是安卓独有的 博主之前的模拟器访问完全没问题 最近突然无法访问 用控制变量法 我改
  • 2013年11月26日星期二(t3dlib1剩余部分---2)

    接下来 继续进行T3DLIB1剩余部分 倒着进行 先进行bob碰撞检测 int DDraw BOB Collision BOBS BOB PTR bob1 BOB PTR bob2 if bob1 bob2 return 0 int wid
  • 【Unity3D游戏开发学习笔记】(七)上帝之眼—第三人称摄像机的简单实现(跟随视角,自由视角)

    陆陆续续又开始更新自己的博客 看来自我驱动能力还是不够啊 废话不多说了 之前的内容大概说了一下Unity的一些基础知识 接下来我们将要对一些基本功能做一些学习 大家都知道 一个游戏 少不了摄像机的参与 这不是废话么 没摄像机怎么玩 画面都不
  • linux脚本的注释符号是什么,Shell中的变量和符号

    Shell中的变量 变量 shell 变量 可以保存如路径名 文件名或者一个数字 变量名称可以由字母 数字和下划线组成 但是不能以数字开头 如果变量名是 2name 则是错误的 在Bash中 变量的默认类型都是字符串型 如果要进行数值运算
  • log4j2史诗级漏洞攻击重现

    早上来到公司 就听到安全团队的同事说log4j2有个高危漏洞 起初并不是很在意 想着一个日志框架能有啥高危漏洞嘛 但是仔细一看 居然是远程执行命令的漏洞 上次看到这个名字还是struts2 修复方法也很简单 升级log4j依赖版本到2 15
  • vue【element ui】el-date-picker 日期选择器控件 限制可选的开始时间和结束时间

    项目场景 总结一下日期控件实现开始日期 结束日期的选择范围限制 以便更符合实际情况 需求 1 开始时间和结束时间都不能选当前日期之后的时间 当前时间 2022年5月16日 2 先选开始时间的话 结束时间是在开始时间的后一周内选择 也就是不能
  • 实习中了解的互联网数仓

    大数据平台 之前在两家互联网企业都做过数仓相关方面的实习岗位 一家中大厂 一家大厂 在这里简单分享一些数仓在企业中实际的运作 方便一些对数仓有兴趣但尚未在企业中数仓岗位实践过的同学了解 数据开发平台 一般来说 中型或大型企业都会有自己的大数
  • 【Shell编程】条件判断

    系列文章 Shell编程 Shell中的正则表达式 Shell编程 字符截取命令cut printf命令 Shell编程 字符截取命令awk sed命令 目录 系列文章 按照文件类型进行判断 实例 测试上一条命令是否执行成功 编写一个she
  • 建立图(邻接矩阵、邻近表任选其一)的存储结构、实现图的深度优先遍历和广度优先遍历。

    include
  • Qt connect 中, SIGNAL,SLOT 与 lambda 对比

    简单的信息就不说了 主要谈谈区别 首先结论是 推荐用 lambda 格式绑定信号槽 个人看法 有其他建议欢迎讨论 具体原因如下 SIGNAL SLOT 是 Qt4 时期的方法 lambda 是 Qt5 引入的 新的总比老的好 SIGNAL
  • Java之spring新手教程(包教包会)

    Java Spring 一 之IoC以及bean的生命周期 文章目录 Java Spring 一 之IoC以及bean的生命周期 一 什么是Spring 二 Spring的核心 三 什么是耦合 四 spring项目的搭建 五 配置文件 六