一文吃透 Spring 中的IOC和DI(二)

news2024/11/16 19:29:40

在这里插入图片描述

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。
🍎个人主页:Java Fans的博客
🍊个人信条:不迁怒,不贰过。小知识,大智慧。
💞当前专栏:SSM 框架从入门到精通
✨特色专栏:国学周更-心性养成之路
🥭本文内容:一文吃透 Spring 中的IOC和DI

文章目录

    • 准备工作
    • bean 的自动注入
    • bean 的生命周期
    • Bean 的作用域
    • Spring 注解开发
      • 1、@Component 注解
      • 2、@Scope 注解
      • 3、@Value 注解
      • 4、@Autowired 注解
      • 5、@Qualifier 注解
      • 6、@Resource 注解
      • 7、xml配置方式与注解方式的比较

在这里插入图片描述

准备工作

entity 包中的创建一个 Student 类和 Teacher 类,代码如下:

Student 类:

package cn.kgc.spring02.entity;

import lombok.Data;

@Data
public class Student {
    private String name;
    private Integer id;

    private Teacher teacher;
}

Teacher 类:

package cn.kgc.spring02.entity;

import lombok.Data;

@Data
public class Teacher {
    private String name;
    private Double salary;
}

创建一个测试类和一个 shouldAnswerWithTrue 测试方法:

package cn.kgc.spring02;

import cn.kgc.spring02.entity.Student;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 如何通过配置 或注解完成自动注入
 */
public class AppTest {
    @Test
    public void shouldAnswerWithTrue(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring-config.xml");
        Student student = ac.getBean("student", Student.class);
        System.out.println("student = " + student);
    }
}

bean 的自动注入

  1. autowire=“byType” 根据属性的类型完成自动注入
    <bean id="student" class="cn.kgc.spring02.entity.Student" autowire="byType">
        <property name="id" value="1"></property>
        <property name="name" value="tom"></property>
    </bean>
    <bean id="teacher" class="cn.kgc.spring02.entity.Teacher">
        <property name="name" value="jack"></property>
        <property name="salary" value="200"></property>
    </bean>

运行测试类中的 shouldAnswerWithTrue 方法,运行效果如下:

在这里插入图片描述

局限: 保证spring容器中只能有一个指定类型的bean

  1. autowire=“byName” 根据属性的名字完成自动注入,属性名字和哪个 beanid 相等,则完成注入。测试的运行效果和上面一样。
    <bean id="student" class="cn.kgc.spring02.entity.Student" autowire="byName">
        <property name="id" value="1"></property>
        <property name="name" value="tom"></property>
    </bean>
    <bean id="teacher" class="cn.kgc.spring02.entity.Teacher">
        <property name="name" value="jack"></property>
        <property name="salary" value="200"></property>
    </bean>

bean 的生命周期

1.singleton 容器启动的时候创建对象,容器正常关闭时销毁对象

2.prototype 获取对象的时候创建对象,spring容器不负责对象的销毁

生命周期的过程:

1.调用无参创建对象

2.调用set方法初始化属性

3.调用初始化方法

4.对象创建完成,使用对象

5.关闭容器,调用销毁的方法

Bean 的作用域

在配置文件中,除了可以定义 Bean 的属性值和相互之间的依赖关系,还可以声明 Bean 的作用域。例如,如果每次获取 Bean 时,都需要一个 Bean 实例,那么应该将 Bean 的 scope 属性定义为 prototype,如果 Spring 需要每次都返回一个相同的 Bean 实例,则应将 Bean 的 scope 属性定义为 singleton。

作用域的种类

Spring 容器在初始化一个 Bean 实例时,同时会指定该实例的作用域。Spring 5 支持以下 6 种作用域。

1)singleton

默认值,单例模式,表示在 Spring 容器中只有一个 Bean 实例,Bean 以单例的方式存在。

<bean id="..." class="..." scope="singleton"/>

2)prototype

原型模式,表示每次通过 Spring 容器获取 Bean 时,容器都会创建一个 Bean 实例。

<bean id="..." class="..." scope="prototype"/>

3)request

每次 HTTP 请求,容器都会创建一个 Bean 实例。该作用域只在当前 HTTP Request 内有效。

4)session

同一个 HTTP Session 共享一个 Bean 实例,不同的 Session 使用不同的 Bean 实例。该作用域仅在当前 HTTP Session 内有效。

5)application

同一个 Web 应用共享一个 Bean 实例,该作用域在当前 ServletContext 内有效。

类似于 singleton,不同的是,singleton 表示每个 IoC 容器中仅有一个 Bean 实例,而同一个 Web 应用中可能会有多个 IoC 容器,但一个 Web 应用只会有一个 ServletContext,也可以说 application 才是 Web 应用中货真价实的单例模式。

6)websocket

websocket 的作用域是 WebSocket ,即在整个 WebSocket 中有效

Spring 注解开发

除了用 XML 配置方式进行依赖注入外,还可以使用注解直接在类中定义 Bean 实例,这样就不再需要在 Spring 配置文件中声明 Bean 实例。使用注解,除了原有 Spring 配置,还要注意以下关键步骤。

spring-config.xml 开启注解的包扫描

<?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:context="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">
    <!--开启包扫描  base-package  设置需要扫描的包 -->
    <context:component-scan base-package="cn.kgc.spring02"></context:component-scan>
</beans>

1、@Component 注解

@Component 该注解的 value 属性用于指定该 bean 的 id 值。例如在实体类 User 上添加注解@Component(value=“user”),它的意思是创建一个 User 类的 bean 实例,bean 的 id 为 user。

@Component("user")
public class User {
	private String uid;
	private String uname;
	private String gender;
	private int age;
	private Company company;
//省略其他方法
}

【注意】@Component(“user”) 等同于@Component(value=“user”),即默认的属性是value,其效果等同于xml配置文件。

Spring还另外提供了3个功能与@Component等效的注解:

  • @Repository 专用于对 DAO 层实现类进行注解 。
  • @Service 专用于对 Service 层实现类进行注解 。
  • @Controller 专用于对 Controller 类进行注解。

四个注解的功能是一样的,只是使用不同的注解可以看出层次结构

2、@Scope 注解

需要在类上使用注解@Scope,其value属性用于指定作用域,默认为singleton(单例bean)。

(1)在项目spring5的Student类中添加下面的注解。

@Scope("prototype")
@Component("student")
public class User {	
//省略其他代码
}

@Scope(“prototype”)等同于@Scope(value=“prototype”),这样就设置bean的作用范围为"prototype"(原型bean)

3、@Value 注解

需要在属性上使用注解@Value,该注解的value属性用于指定要注入的值。使用该注解完成属性注入时,类中无需setter。当然,若属性有setter,则也可将其加到setter上。

@Scope("prototype")
@Component("user")
public class User {	
	@Value("1")
	private String uid;
	@Value("李白")
	private String uname;
	@Value("男")
	private String gender;
	@Value("18")
	private int age;
public void show(){
	     System.out.println("用户编号:"+uid+" 用户姓名:"+uname+"性别:"+gender+"年龄:"+age);
	}
//省略其他方法
}

4、@Autowired 注解

需要在域属性上使用注解@Autowired,该注解默认使用按类型自动装配Bean的方式。根据类型不能完成注入,则在根据名字完成注入, 以上两种方式都失败则抛出异常。

@Component("user")
public class User {
	@Value("1")
	private String uid;
	@Value("李白")
	private String uname;
	@Value("男")
	private String gender;
	@Value("18")
	private int age;	
	@Autowired
	private Company company;
//省略其他方法
}

5、@Qualifier 注解

@Qualifier的value属性用于指定要匹配的Bean的id值。

@Component("user")
public class User {	
	//省略其他代码
	@Autowired(required=false)
@Qualifier("mycolleg")
	private Company company;
}

这时域属性company必须装配id为mycompany的bean。如果找不到会报错。

6、@Resource 注解

使用@Resource注解既可以按名称匹配Bean,也可以按类型匹配 Bean。

(1)按类型注入域属性

@Resource 注解若不带任何参数,则会按照类型进行Bean的匹配注入。

@Component("user")
public class User {	
	//省略其他代码
@Resource
	private Company company;
}

(2)按名称注入域属性。@Resource 注解指定其name属性,则name的值即为按照名称进行匹配的Bean的id。

@Component("user")
public class User {	
	//省略其他代码		
@Resource(name="mycompany")
	private Company company;
}

7、xml配置方式与注解方式的比较

注解的好处是: 配置方便,直观。

缺点: 以硬编码的方式写入到了Java代码中,其修改需要重新编译代码的。

xml配置方式的好处是: 对其所做修改,无需编译代码,只需重启服务器即可将新的配置加载。

若注解与xml同用,xml的优先级要高于注解。


  码文不易,本篇文章就介绍到这里,如果想要学习更多Java系列知识点击关注博主,博主带你零基础学习Java知识。与此同时,对于日常生活有困扰的朋友,欢迎阅读我的第四栏目:《国学周更—心性养成之路》,学习技术的同时,我们也注重了心性的养成。

在这里插入图片描述

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

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

相关文章

【前端八股文】浏览器系列:单进程与多进程、浏览器进程、异步、事件循环、同源策略、输入URL回车后、TCP三次挥手四次握手

文章目录概述单进程VS多进程浏览器进程主要分为异步场景事件循环同源策略与跨域问题输入URL回车后过程URL几大部分TCP连接与释放TCP三次握手TCP四次挥手参考本系列目录&#xff1a;【前端八股文】目录总结 是以《代码随想录》八股文为主的笔记。详情参考在文末。 代码随想录的博…

AI又进化了,突破性革命来了

大家好&#xff0c;我是 Jack。 2023 年&#xff0c;AI 真的杀疯了。短短不到一年的时间&#xff0c;当我们还在感慨 AI 一键生成的二次元画作精美万分的时候&#xff0c;它已经进化到了写实美照也能手到擒来的地步。 更多的效果&#xff0c;可以看刚刚发布的视频&#xff0c;…

Java爬虫系列 - 爬虫补充内容+ElasticSearch展示数据

一&#xff0c;定时任务Cron表达式Component public class TaskTest {Scheduled(cron "0/5 * * * * *") // 从0秒开始&#xff0c;每个五秒 执行一次 { 秒 分 时 天 月 周 }public void test(){System.out.println("定时任务执行了");} }二&#xff0c;网…

第一章 初识 Spring Security

第一章 初识 Spring Security 1、权限管理 权限管理 基本上涉及到用户参与的系统都要进行权限管理&#xff0c;权限管理属于系统安全的范畴&#xff0c;权限管理实现了对用户访问系统的控制&#xff0c;按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资…

【白话科普】聊聊网络架构变革的关键——SDN

最近二狗子在网上冲浪的时候&#xff0c;不小心将 CDN 搜索成了 SDN&#xff0c;结果跳出来了一大堆相关的知识点。 好学的二狗子当然不会随随便便糊弄过去&#xff0c;于是认认真真学习了好久&#xff0c;终于了解了 SDN 是什么。 原来&#xff0c;SDN 的全称是 Software De…

第十一届“泰迪杯”数据挖掘挑战赛携“十万”大奖火热来袭

第十一届“泰迪杯”数据挖掘挑战赛 竞赛组织 主办单位&#xff1a; 泰迪杯数据挖掘挑战赛组织委员会 承办单位&#xff1a; 广东泰迪智能科技股份有限公司 人民邮电出版社 协办单位&#xff1a; 重庆市工业与应用数学学会、广东省工业与应用数学学会、广西数学学会、河北省工业…

心跳机制Redis

 进入命令传播阶段候&#xff0c;master与slave间需要进行信息交换&#xff0c;使用心跳机制进行维护&#xff0c;实现双方连接保持在线 master心跳&#xff1a; 指令&#xff1a;PING 周期&#xff1a;由repl-ping-slave-period决定&#xff0c;默认10秒 作用&#…

4|无线传感器网络与应用|无线传感器网络原理及方法-许毅版|第3章:无线传感器网络通信-3.1协议结构 3.2物理层|青岛科技大学|课堂笔记

第3章&#xff1a;无线传感器网络通信3.1协议结构3.1.1 OSI参考模型1.网络通信协议MAC层和物理层采用IEEE 802.15.4协议*(1)物理层wsn物理层负责信号的调制和数据的收发&#xff0c;传输介质&#xff1a;无线电、红外线、光波等。(2)数据链路层wsn数据链路层负责数据成帧、帧检…

光谱实验反射、透射光谱测量

标题反射、透射光谱测量的基本原理  暗背景/基线&#xff1a;Dark………………………………………………………………0%  &#xff08;空&#xff09;白参考&#xff1a;Reference…………………………………………………………100%  样品反射/透射光谱&#xff1a;Sampl…

【Redis】 数据结构:SDS、跳跃表等底层数据结构详解

【Redis】 数据结构&#xff1a;SDS、跳跃表等底层数据结构详解 文章目录【Redis】 数据结构&#xff1a;SDS、跳跃表等底层数据结构详解底层数据结构引入Redis数据结构 - 动态字符串 SDSSDS 概述SDS动态扩容为什么使用SDS小结Redis数据结构 - 整数集 intsetIntSet概述内存布局…

从JDK源码来看XXE的触发原理和对应的防御手段

前言 这几天继续在重写GadgetInspector工具&#xff0c;进一步的增强该自动化工具的source点和sink点&#xff0c;同时增强过程中的漏报和误报的问题。 这里主要是对其中有关于XXE中的两点sink进行几点分析。 sinks DocumentBuilder类 这个JDK中内置的类是一种的DOM型的解…

基础组件之内存池

内存池技术 操作系统在运行进程的过程中&#xff0c;会产生内存碎片&#xff0c;降低了内存的使用率。内存池技术就是为了解决/减少内存碎片的一种方法&#xff0c;内部底层的具体实现根据不同业务场景使用不要的方式&#xff0c;以下是一种好理解的方式&#xff0c;供大家一起…

光学分辨率光声显微镜中基于深度学习的运动校正算法

在这项研究中&#xff0c;我们提出了一种基于深度学习的方法来校正光学分辨率光声显微镜 (OR-PAM) 中的运动伪影。该方法是一种卷积神经网络&#xff0c;它从具有运动伪影的输入原始数据建立端到端映射&#xff0c;以输出校正后的图像。首先&#xff0c;我们进行了仿真研究&…

PYTHON爬虫基础

一、安装package 在使用爬虫前&#xff0c;需要先安装三个包&#xff0c;requests、BeautifulSoup、selenium。 输入如下代码&#xff0c;若无报错&#xff0c;则说明安装成功。 import requests from bs4 import BeautifulSoup import selenium二、Requests应用 了解了原理…

关于IDEA中Thread.activeCount()的问题记录

回顾&#xff1a; Thread类的activeCount()方法用于返回当前线程的线程组中活动线程的数量。返回的值只是一个估计值&#xff0c;因为当此方法遍历内部数据结构时&#xff0c;线程数可能会动态更改。总之它返回当前线程的线程组中活动线程的数量。 在研究多线程对同一变量的修…

【FAQ】集成分析服务的常见问题及解决方案

常见问题一&#xff1a;如何验证Analytics是否上报/接入成功&#xff1f;以及关键日志含义是什么&#xff1f; 在初始化Analytics SDK前添加SDK日志开关如下&#xff1a; HiAnalyticsTools.enableLog (); 2.初始化SDK代码如下&#xff1a; HiAnalyticsInstance instance Hi…

kettle安装部署_简单认识_Spoon勺子界面---大数据之kettle工作笔记002

然后我们来看一下这个kettle的安装,很简单,下载解压就可以了 上面的地址是官网很烂 下面的地址好一些 这个是官网可以看到很慢,很不友好 这个是下面那个地址,可以看到 最新的是9.0了,一般都用 一般都用8.2 这里下载这个就可以了 下载以后可以看到有个pdi

【代码随想录训练营】【Day19休息】【Day20】第六章|二叉树|654.最大二叉树|617.合并二叉树|700.二叉搜索树中的搜索|98.验证二叉搜索树

最大二叉树 题目详细&#xff1a;LeetCode.654 这道题在题目几乎就说明了解题的思路了&#xff1a; 创建一个根节点&#xff0c;其值为 nums 中的最大值&#xff1b;递归地在最大值左边的子数组上构建左子树&#xff1b;递归地在最大值右边的子数组上构建右子树&#xff1b;…

计算机系统基础知识

计算机的基本组成 计算机组成逻辑图 计算机部件作用 一级部件作用 运算器&#xff1a;计算机的执行部件&#xff0c;受控制器控制&#xff0c;执行算术运算或逻辑运算控制器&#xff1a;决定计算机运行过程的自动化。不仅能保证程序指令的正确执行&#xff0c;还能处理异常事…

12款适合小团队协作、任务管理和进度跟踪的在线任务管理的工具推荐?

国内外12款主流任务管理软件测评: 1.开发任务管理PingCode; 2.多合一项目任务管理Worktile;3.个人和小团队项目任务管理Notion; 4.企业任务管理平台SmartTask; 5.小团队任务管理Teambition;6.IT任务追踪管理Jira等。无论是做好工作任务管理还是个人任务管理&#xff0c;从来都不…