认识Spring(下)

news2024/11/15 11:12:07

作者:~小明学编程 

文章专栏:Spring框架

格言:热爱编程的,终将被编程所厚爱。
在这里插入图片描述

目录

Spring更加高效的读取和存储对象

存储bean对象

五大注解

关于五大类注解

对象的注入

属性注入

构造方法注入

Setter注入

三种注入方式的区别

@Resource 和 @Autowired 的区别

Bean的作用域和生命周期

Spring的执行流程

Bean的生命周期


Spring更加高效的读取和存储对象

存储bean对象

前面我们所介绍的方法过于的繁琐,我们可以通过注解来快速实现上述的功能。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:content="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <content:component-scan base-package="com.beans"></content:component-scan>
</beans>

首先是我们所依赖的资源,其中com.beans是我们所要扫描的类的包。

五大注解

  1. Controller 控制器
  2. Service 服务
  3. Repository 仓库
  4. Configuration 配置
  5. Component 组件

利用上面这五大注解都可以完成我们对象的注入。

@Service
public class UserService {
    public void sayHi() {
        System.out.println("hi Service");
    }
}
@Repository
public class UserRepository {
    public void sayHi() {
        System.out.println("Hi Res");
    }
}
@Controller
public class UserController {
    public void sayHi() {
        System.out.println("hello");
    }
}
@Configuration
public class UserConfig {
    public void sayHi() {
        System.out.println("Hi Con");
    }
}
@Component
public class UserComponent {
    public void sayHi() {
        System.out.println("Hi Com");
    }
}

获取:

    public static void main1(String[] args) {
        //1.获取上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //2.得到bean
        UserController userController = context.getBean("userController",UserController.class);
        userController.sayHi();
        UserService userService = context.getBean("userService",UserService.class);
        userService.sayHi();
        UserRepository userRepository = context.getBean("userRepository",UserRepository.class);
        userRepository.sayHi();
        UserConfig userConfig = context.getBean("userConfig",UserConfig.class);
        userConfig.sayHi();
        UserComponent userComponent = context.getBean("userComponent",UserComponent.class);
        userComponent.sayHi();
    }

获取的时候我们需要注意这个beanname,这个beanname是根据如下的逻辑。

关于五大类注解

既然我们五种注解的随便一种都能完成我们的对象的注入,那么我们为什么还是需要五种注解呢

 因为我们一个软件是分为多个层面的,分为多层有助于我们的管理和控制。

Configuration 就是配置层:关于当前项目中的所有配置,都会写在这个文件夹里。
Controller 就是控制层:就是前端参数校验,主要就是校验前端数据的合理性和正确性。
Service 就是服务层,负责数据的组装和接口调用。更直白的说,服务器九四 “牵线搭桥” 让程序去调用对应的功能/接口/服务。
Repository 叫做仓库,但其实是 数据持久层,也叫做 Dao 层,就是对数据进行持久化操作(对数据库进行增删改查操作)。

我们使用不同的注解便于我们了解不同的代码的功能同时也方便我们对代码进行一个管理。

当然这五大类注解之间是有一定的关系的:

 可以看到我们的configuration注解是调用了我们的component注解的,其它几个注解的实现方法也是如此,可以说我们的component注解是我们其它四大注解的一个父类。

对象的注入

前面我们了解了怎么样将对象给存储起来,也就是使用五大注解可以高效方便的将我们的对象给放在spring中,但是当我们想要使用的时候有没有什么方式可以比较高效的来使用呢,下面就介绍三种方式来实现我们对象的一个注入。

属性注入

通过 @Autowired 注入:

@Controller
public class UserController {
    @Autowired
    private UserService userService;
    public void sayHi() {
        userService.sayHi();
    }
}

这里我们就通过关键字Autoeired的关键字来直接实现我们对象的一个注入,然在下面的方法之中我们就可以直接调用我们注入好的对象的方法了。

    public static void main(String[] args) {
        //1.获取上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        UserController userController = context.getBean(UserController.class);
        userController.sayHi();//hi Service
    }

构造方法注入

@Controller
public class UserController {
//    @Autowired
    private UserService userService;
    public UserController(UserService userService) {
        this.userService = userService;
    }
    public void sayHi() {
        userService.sayHi();
    }
}

这里我们可以直接通过构造方法的方式来进行对象的一个注入,但是值得我们注意的是,当我们的构造方法不止一个的时候就必须要使用Autowired关键字了,不然会报错。

@Controller
public class UserController {
//    @Autowired
    private UserService userService;
    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
    public UserController(UserService userService,int num) {
        this.userService = userService;
    }
    public void sayHi() {
        userService.sayHi();
    }
}

Setter注入

@Controller
public class UserController {
    private UserService userService;
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void sayHi() {
        userService.sayHi();
    }
}

同样我们也可以使用Setter这样一个方法来进行一个注入。

三种注入方式的区别

  1. 属性注入特点是写法简单,但是通用性不好,只能运行在 IoC 容器下,如果是 非 IoC 容器的话,就会出现问题。
  2. 构造方法注入,通用性更好。因为构造方法的优先级是最高的。确保使用注入对象之前,对象一定初始化过了。当构造方法注入参数太多时,就需要检查自己的代码是否符合单一设计原则的规范了。构造方法注入,也是 Spring 推荐的注入方法。
  3. Setter 注入是早期 Spring 版本推荐的写法,但是通用性没有构造方法注入通用,因为只有一个参数。

@Resource 和 @Autowired 的区别

相同点:都可以完成对象的注入。

不同点:

  • 出身不同,@Resource 来自于 JDK,@Autowired 是由 Spring 框架提供的。
  • @Autowired 支持属性注入,构造方法注入 和 Setter 注入,而 @Resource 不支持构造方法注入。
  • 支持的参数不同:@Resource 支持更多的参数设置,比如 name、type 设置。而 @Autowired 只支持 required 参数设置。

Bean的作用域和生命周期

在我们使用bean的时候其实默认是用的同一个bean也就是说如果我们对其中的bean进行一个更改的话,那么当我们再次去使用这个bean此时依然是更改之后的bean。

@Component
public class UserBean {

    @Bean(name = {"user","user1"})
//    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public User user2() {
        User user = new User(15,"lisi");
        return user;
    }
    @Bean(name = {"user2"})
    public User user1() {
        User user = new User(12,"zhangsan");
        return user;
    }
}
@Component
public class BeanScope1 {
    @Autowired
    private User user2;

    public User getUser() {
        user2.setStr("aaa");
        return user2;
    }
}
@Component
public class BeanScope2 {
    @Autowired
    private User user2;//user2必须事被注入过的

    public User getUser() {
        return user2;
    }
}

这个时候我们注入了两次bean对象,此时查看输入的结果:

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        BeanScope1 beanScope1 = context.getBean(BeanScope1.class);
        System.out.println(beanScope1.getUser());
        BeanScope2 beanScope2 = context.getBean(BeanScope2.class);
        System.out.println(beanScope2.getUser());


    }

 可以看到我们在对其进行更改之后,再次注入仍然是更改之后的User。

产生这样的原因是因为 Bean 在 Spring 中,默认情况下是单例状态,也就是所有人的使用都是同一个对像。这样可以很好的节约资源,避免资源的浪费。

Bean 的六种作用域
singleton:单例作用域(默认)在这种模式下的 Bean 在 IoC 容器里面,只存在一个实例。
prototype:原型作用域(多例模式)每次对作用域下的 Bean 请求,都会创建新的实例,然后再去获取 Bean。
request:请求作用域(Spring MVC)每次 Http 请求会创建新的 Bean 实例,类似于 prototype。
session:会话作用域(Spring MVC)在一个 http session 中,定义一个 Bean 实例。记录用户的登录信息。
application:全局作用域(Spring MVC)更多人使用的时候,就用 application。也是单例模式,应用在 Web 应用的上下文信息。
websocket:Http WebSocket 作用域(Spring WebSocket)在 WebSocket 会话中使用。
 

当我们想要改变其作用域的时候可以通过@Scope 的注解来进行改变

可以看到此时我们 所注入的对象就都是新的对象了。

设置作用域的时候,只需要通过 @Scope 注解就可以了

  1. 直接设置值:@Scope(“prototype”)
  2. 使用枚举设置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

Spring的执行流程

1.我们首先是要启动我们的容器,去加载我们的配置文件。

也就是我们上面的这段代码。

2.接着就是根据我们的配置来完成我们的bean初始化。

 通过扫描包中的spring注解。

3.注册 Bean 对象到容器中,只有在包扫描的路径上的类,且使用 Spring 的注解才可以被注册到容器当中。

 4.装配 Bean 属性,也就是把 Bean 注册到其他类当中:

Bean的生命周期

Bean的生命周期就是Baen从诞生到销毁的一个过程 。

  1. 实例化 Bean(为 Bean 分配内存空间)
  2. 设置属性(Bean 注入和装配)
  3. Bean 初始化                                                                                                                         a)执行各种通知(各种Aware)如:BeanNameAware,BeanFactoryAware,ApplicationContextAware 的接口方法。
    b)执行 BeanPostProcessor 初始化前置方法。
    c)执行 @PostConstruct 初始化方法,依赖注入操作之后被执行。
    d)执行自己指定的 init-method 方法(如果有指定的话
    e)执行 BeanPostProcessor 初始化后置方法。
  4. 使用 Bean
  5. 销毁 Bean,通过方法来销毁容器:如 @PreDestroy、DisposableBean、destroy-method



其大概的流程图就是这样的。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:content="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <content:component-scan base-package="com.beans"></content:component-scan>
    <bean id="beanLife"
          class="com.beans.BeanLife" init-method="init"></bean>
</beans>
package com.beans;

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 86184
 * Date: 2023-03-06
 * Time: 22:07
 */
@Component
public class BeanLife implements BeanNameAware {
    @PostConstruct
    public void Post() {
        System.out.println("PostConstruct");
    }
    @PreDestroy
    public void Pre() {
        System.out.println("pre");
    }
    public void use() {
        System.out.println("use");
    }
    public void init() {
        System.out.println("init");
    }
    public void setBeanName(String s) {
        System.out.println("通知");
    }
}

 执行流程如上。

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

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

相关文章

golang的垃圾回收详解

golang的垃圾回收详解 一、三色标记法 作为一门现代化的语言&#xff0c;golang与java一样&#xff0c;都在语言中内置了垃圾回收的功能&#xff0c;不需要程序员自己去回收堆内存。而垃圾回收中&#xff0c;最重要的两个部分就是垃圾检测算法以及垃圾回收算法。垃圾检测算法决…

《c++ primer笔记》第八章 IO库

前言 简单看一下就行 文章目录一、IO类1.1基本概念1.2管理输出缓冲二、文件输入输出2.1文件模式三、string流3.1istringstream3.2ostringstream一、IO类 1.1基本概念 ​ 我们常见的流有istream和ostream&#xff0c;这两个流都是有关输入和输出的&#xff0c;此外&#xff0c…

如何在SSMS中生成和保存估计或实际执行计划

在引擎数据库执行查询时执行的过程的步骤由称为查询计划的一组指令描述。​查询计划在SQL Server中也称为SQL Server执行计划,我们可以通过以下步骤来生成和保存估计或实际执行计划。 估计执行计划和实际执行计划是两种执行计划: 实际执行计划:当执行查询时,实际执行计划出…

Spring之实例化Bean(2)

Spring是非常复杂的一个框架&#xff0c;想要一篇博客就说完实例化Bean的全流程&#xff0c;那将注定会是是很长很长的篇博客&#xff0c;说实话&#xff0c;换做我自己是没有耐心看完的。 本章&#xff0c;我将会以一个最简单的例子来阐述Spring实例化Bean的过程&#xff0c;…

8.SpringSecurity中的核心过滤器-CsrfFilter

SpringSecurity中的核心过滤器-CsrfFilter Spring Security除了认证授权外功能外&#xff0c;还提供了安全防护功能。本文我们来介绍下SpringSecurity中是如何阻止CSRF攻击的。 一、什么是CSRF攻击 跨站请求伪造&#xff08;英语&#xff1a;Cross-site request forgery&#…

uos 20 统信 fprintd 记录

uos 20 统信 fprintd 记录 sudo busctl deepin-authenticate.service /usr/lib/systemd/system/deepin-authenticate.service [Unit] DescriptionDeepin Authentication[Service] Typedbus BusNamecom.deepin.daemon.Authenticate ExecStart/usr/lib/deepin-authenticate/d…

Activty启动到显示的过程[二]

Activity的显示从handleResumeActivity()方法开始。 //ActivityThread.javaOverridepublic void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,String reason) {final ActivityClientRecord r performResumeActivity(token, finalStat…

LCD液晶段码驱动IC/LCD液晶驱动芯片VK2C22高抗干扰/抗噪,适用于汽车仪表/单相智能电表

产品型号&#xff1a;VK2C22A/B产品品牌&#xff1a;永嘉微电/VINKA封装形式&#xff1a;LQFP52/48、DICE(COB邦定片)、COG(邦定玻璃用)产品年份&#xff1a;新年份原厂&#xff0c;工程服务&#xff0c;技术支持&#xff01;VK2C22A/B概述&#xff1a;VK2C22是一个点阵式存储映…

自然语言处理-基于预训练模型的方法-chapter3基础工具集与常用数据集

文章目录3.1NLTK工具集3.1.1常用语料库和词典资源3.1.2常见自然语言处理工具集3.2LTP工具集3.3pytorch基础3.3.1张量基本概念3.3.2张量基本运算3.3.3自动微分3.3.4调整张量形状3.3.5广播机制3.3.6索引与切片3.3.7降维与升维3.4大规模预训练模型3.1NLTK工具集 3.1.1常用语料库和…

2023年3月软考高项(信息系统项目管理师)报名走起!!!

信息系统项目管理师是全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试&#xff08;简称软考&#xff09;项目之一&#xff0c;是由国家人力资源和社会保障部、工业和信息化部共同组织的国家级考试&#xff0c;既属于国家职业资格考试&#xff0c;又是职称资…

图表控件LightningChart.NET 系列教程(十一):LightningChart 组件——添加至 Blend WPF 项目

LightningChart.NET 是一款高性能 WPF 和 Winforms 图表,可以实时可视化多达1万亿个数据点。可有效利用CPU和内存资源&#xff0c;实时监控数据流。同时&#xff0c;LightningChart使用突破性创新技术&#xff0c;以实时优化为前提&#xff0c;大大提升了实时渲染的效率和效果&…

网络编程 socket 编程(一)

1. C/S 架构 C/S 架构即客户端/服务端架构&#xff0c;B/S 架构&#xff08;浏览器与服务端&#xff09;也是 C/S 架构的一种。 C/S 架构与 socket 的关系&#xff1a;学习 socket 可以完成 C/S 架构的开发。 2. osi 七层 一个完整的计算机系统由硬件、操作系统以及应用软件…

Redis:主从同步

Redis&#xff1a;主从同步一. 概述二. 原理(1) 全量同步(2) 增量同步(3) 优化Redis主从集群三. 总结一. 概述 引入&#xff1a; Redis主从集群采用一个Master负责写&#xff0c;多个Slave负责读的方式&#xff08;读多写少&#xff09;&#xff0c;那么如何让读取数据时多个从…

访问学者进入美国哪些东西不能带?

随着疫情的稳定&#xff0c;各国签证的逐步放开&#xff0c;成功申请到国外访问学者、博士后如何顺利的进入国外&#xff0c;哪些东西不能带&#xff0c;下面就随知识人网小编一起看一看。一、畜禽肉类(Meats, Livestock and Poultry)不论是新鲜的、干燥的、罐头的、真空包装的…

pycharm激活虚拟环境时报错:无法加载文件activate.ps1,因为在此系统上禁止运行脚本,Windows10系统

问题&#xff1a; ii_env\Scripts\activate : 无法加载文件 F:\gitlab\AutoFrame\ii_env\Scripts\Activate.ps1&#xff0c;因为在此系统上禁止运行脚本。 有关详细信息&#xff0c;请参阅 https:/go.microsoft.com/fwlink/?LinkID135170 中的 about_Execution_Policies。 所在…

34 openEuler使用LVM管理硬盘-创建并挂载文件系统

文章目录34 openEuler使用LVM管理硬盘-创建并挂载文件系统34.1 创建文件系统34.2 手动挂载文件系统34.3 自动挂载文件系统34 openEuler使用LVM管理硬盘-创建并挂载文件系统 在创建完逻辑卷之后&#xff0c;需要在逻辑卷之上创建文件系统并挂载文件系统到相应目录下。 34.1 创…

大型医院云HIS系统:采用前后端分离架构,前端由Angular语言、JavaScript开发;后端使用Java语言开发 融合B/S版电子病历系统

一套医院云his系统源码 采用前后端分离架构&#xff0c;前端由Angular语言、JavaScript开发&#xff1b;后端使用Java语言开发。融合B/S版电子病历系统&#xff0c;支持电子病历四级&#xff0c;HIS与电子病历系统均拥有自主知识产权。 文末卡片获取联系&#xff01; 基于云计…

谷歌留痕霸屏平台有哪些?

谷歌留痕霸屏平台有哪些&#xff1f; 答案是&#xff1a;光算可以做谷歌留痕霸屏 我们要先了解什么是谷歌留痕霸屏平台这个概念。 很简单&#xff0c;就是你有哪些可以做排名的网站资源&#xff0c;一般情况下你不够专业&#xff0c;是没办法把这件事做好的。 通常你要做谷…

学python的第四天---基础(2)

一、三角形类型读入数组并排序的方法nlist(map(float,input().split())) c,b,asorted(n)list_1 list(map(float, input().split())) list_1.sort() list_1.reverse()lengthssorted(map(float,input().split(" ")),reverseTrue)二、动物写法一&#xff1a;d{" &…

css系统化学习

元素的语义化 SEO:搜索引擎优化 根据搜索引擎展示的规律,语义化的元素更容易被展示获得更多浏览量 字符编码 css历史 内联样式(inline) style"内容全写在等号后面,双引号里面,多个之间用;隔开" 内部样式(internal) style写在head里面,在title下面,不是在body内, …