Spring源码(3)Aware接口、初始化和销毁方法、@Scope、@Primary

news2024/11/13 11:05:47

1、目标

本文的主要目标是学习Spring源码中Aware接口、初始化和销毁方法、@Scope注解、@Primary注解的使用

2、Aware接口

@Component
public class MyBeanAware implements BeanNameAware, ApplicationContextAware {
    @Override
    public void setBeanName(String name) {
        System.out.println("beanName = " + name);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("applicationContext = " + applicationContext);
    }
}

实现BeanNameAware接口,可以重写setBeanName方法
实现ApplicationContextAware接口,可以重写setApplicationContext方法

在这里插入图片描述

3、初始化和销毁方法

初始化方法有3种方式,依次的顺序是@PostConstruct注解指定初始化方法、实现InitializingBean接口并重写afterPropertiesSet方法、@Bean注解上指定initMethod=xxx

销毁方法有3种方式,依次的顺序是@PreDestroy注解指定销毁方法、实现DisposableBean接口并重写destroy方法、@Bean注解上指定destroyMethod=xxx

4、@Scope注解

Scope有单例singleton、多例prototype、request、session、application

单例对象中包含多例对象的属性,多次获取这个属性是是单例的吗还是多例?

结论:还是单例的,因为只会依赖注入1次多例对象

@Component
public class A {
    @Autowired
    private B b;
    public B getB() {
        return b;
    }
}

A对象是单例的

@Scope(value = "prototype")
@Component
public class B {
}

B对象设置多例的,即@Scope(value=“prototype”)

@SpringBootApplication
public class Demo02Application {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Demo02Application.class);
        A a = applicationContext.getBean("a", A.class);
        System.out.println(a.getB().getClass());
        System.out.println(a.getB());
        System.out.println(a.getB());
        System.out.println(a.getB());
    }
}

多个获取A对象中的属性B对象,A对象是单例对象,B对象是多例的,但是B对象只会依赖注入1次,因此多次获取B对象仍然是同一个对象

在这里插入图片描述

多次获取的B对象是同一个对象,说明只会依赖注入1次

如果希望属性是多例对象的话,多次获取可以得到多个不同的对象怎么办?

① @Lazy注解:@Lazy注解会创建属性的CGLIB动态代理对象,因此每次获取这个多例对象的时候动态代理对象会创建一个新的对象

@Component
public class A {
    @Lazy
    @Autowired
    private B b;
    public B getB() {
        return b;
    }
}

A对象是单例对象,依赖注入的B对象是多例对象,因此用@Lazy注解进行懒加载,会创建一个CGLIB动态代理对象,每次获取实际的B对象会创建一个新的B对象

在这里插入图片描述

B对象是CGLIB动态代理对象,每次获取B对象都会创建一个新的B对象

② 在被代理对象上的@Scope注解上添加proxyMode是TARGET_CLASS,表示会使用CGLIB动态代理对象创建一个新的对象

@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
@Component
public class B {
}

被代理对象B对象指定proxyMode=ScopedProxyMode.TARGET_CLASS

在这里插入图片描述

创建了CGLIB动态代理对象,每次获取B对象都会创建一个新的B对象

③ ObjectFactory工厂的getObject方法可以创建多个对象

@Component
public class A {
    @Autowired
    private ObjectFactory<B> b;
    public B getB() {
        return b.getObject();
    }
}

依赖注入ObjectFactory工厂对象,通过getObject方法可以创建B对象

在这里插入图片描述

创建CGLIB动态代理对象,多次获取B对象可以得到多个B对象

④ ApplicationContext容器的getBean方法可以获取多例对象的多个对象

@Component
public class A {
    @Autowired
    private ApplicationContext applicationContext;
    public B getB() {
        return applicationContext.getBean(B.class);
    }
}

依赖注入容器对象ApplicationContext对象,通过getBean方法多次获取B对象

在这里插入图片描述

创建CGLIB动态代理对象,每次获取B对象可以创建一个新的B对象

5、@Primary注解

@Primary 是 Spring Framework 中的一个注解,用于标记某个 Bean 作为候选 Bean 时的首选项。它的主要作用是在存在多个符合条件的 Bean 时,指定一个 Bean 为首选 Bean

如果只有一个 Bean 实现了接口或类,Spring 会自动选择这个 Bean,而不需要 @Primary

如果没有 @Primary 注解,并且有多个候选 Bean,那么在自动注入时会导致NoUniqueBeanDefinitionException 异常,Spring 会提示有多个 Bean 可用

public interface PaymentService {
    void processPayment();
}

@Component
public class CreditCardPaymentService implements PaymentService {
    @Override
    public void processPayment() {
        // Credit Card payment processing
    }
}

@Component
@Primary
public class PayPalPaymentService implements PaymentService {
    @Override
    public void processPayment() {
        // PayPal payment processing
    }
}

PaymentProcessor 会自动注入 PayPalPaymentService,因为它被标记为 @Primary

@Service
@RequireArgsConstructor
public class PaymentProcessor {
    private final PaymentService paymentService;

    @Autowired
    public PaymentProcessor(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    public void process() {
        paymentService.processPayment();
    }
}

PaymentProcessor 会自动注入 PayPalPaymentService,因为它被标记为 @Primary

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

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

相关文章

Linux系统本地化部署Dify并安装Ollama运行llava大语言模型详细教程

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

屏保壁纸 芝麻时钟比屏保壁纸更好看的桌面动态屏保 大气美观

屏保壁纸 芝麻时钟比屏保壁纸更好看的桌面动态屏保 大气美观&#xff0c;今天小编给大家带来一款非常大气美观的桌面时钟屏保&#xff0c;比屏保壁纸更好看&#xff0c;更美观的桌面屏保软件。非常有个性化哦&#xff0c;我们看看这种屏保主题&#xff0c;是不是让你眼前一亮呢…

20240908 每日AI必读资讯

新AI编程工具爆火&#xff1a;手机2分钟创建一个APP&#xff01; - AI初创公司Replit推出的智能体——Replit Agent。开发环境、编写代码、安装软件包、配置数据库、部署等等&#xff0c;统统自动化&#xff01; - 操作方式也是极其简单&#xff0c;只需一个提出Prompt的动作…

HBuilderx 安装 compile-node-sass编译工具

在使用HBuilderx工具&#xff0c;利用uni-app框架开发前端过程中&#xff0c;应用 “.scss”扩展名的的样式文件&#xff0c;scss作为css的预编译文件&#xff0c;在实际开发中是需要编译的&#xff0c;所以需要安装插件 compile-node-sass。 本人在CSDN下载插件“compile-node…

2.软件生命周期及流程(包含笔试/面试题)

一、软件生命周期 1.什么是软件的生命周期&#xff1f; 软件生命周期就是软件从开始研发到最终被废弃不用的一整个过程。 二、软件生命周期模型 1.瀑布型生命周期模型&#xff08;基本不用这个模型&#xff09; 最早期的模型&#xff0c;流程是从上而下的&#xff0c;如同瀑布流…

【机器人工具箱Robotics Toolbox开发笔记(二)】Matlab中机器人工具箱的下载与安装

Matlab机器人工具箱(Robotics Toolbox)可从Peter Corke教授提供的网站上免费下载。网址为:http://www.petercorke.com/Robotics_Toolbox.html。 图1 网站所提供的机器人工具箱版本 在Downloading the Toolbox栏目中单击here按钮进入下载页面,然后在该页面中填写国家、组织…

基于Python爬虫的淘宝服装数据分析项目

文章目录 一.项目介绍二.爬虫代码代码分析 三. 数据处理四. 数据可视化 一.项目介绍 该项目是基于Python爬虫的淘宝服装数据分析项目&#xff0c;以致于帮助商家了解当前服装市场的需求&#xff0c;制定更加精确的营销策略。首先&#xff0c;需要爬取淘宝中关于服装的大量数据…

JS_函数声明

JS中的方法,多称为函数,函数的声明语法和JAVA中有较大区别 函数说明 函数没有权限控制符不用声明函数的返回值类型,需要返回在函数体中直接return即可,也无需void关键字参数列表中,无需数据类型调用函数时,实参和形参的个数可以不一致声明函数时需要用function关键字函数没有…

STM32F407VET6开发板RT-Thread MSH 串口的适配

相关文章 STM32F407VET6开发板RT-Thread的移植适配 环境 STM32F407VET6 开发板&#xff08;魔女&#xff09;&#xff0c;http://www.stm32er.com/ Keil MDK5&#xff0c;版本 5.36 串口驱动 RT-Thread 通过适配 串口驱动&#xff0c;可以使用 MSH shell 当前手动搭建的 …

c++基础版

c基础版 Windows环境搭建第一个C程序c程序运行原理注释常亮字面常亮符号常亮 变量数据类型整型实型常量类型确定char类型字符串布尔类型 控制台输入随机数产生枚举定义数组数组便利 指针基础野指针空指针指针运算动态内存分配 结构体结构体默认值结构体数组结构体指针结构体指针…

JavaWeb笔记整理13——Mybatis

目录 Mybatis介绍 删除 预编译SQL SQL注入 新增 更新 查询 数据封装 条件查询 XML映射文件 动态SQL 更新案例 foreach Mybatis介绍 删除 预编译SQL SQL注入 新增 更新 查询 数据封装 条件查询 XML映射文件 动态SQL <if> 更新案例<set> foreach &l…

消息中间件 --Kafka

一、 Kafka 1.kafka介绍 Kafka 是一个分布式流媒体平台,类似于消息队列或企业消息传递系统。 生产者发送消息&#xff0c;多个消费者只能有一个消费者接收到消息 生产者发送消息&#xff0c;多个消费者都可以接收到消息 producer&#xff1a;发布消息的对象称之为主题生产者…

人工智能,语音识别也算一种人工智能。

现在挺晚了&#xff0c;还是没有去睡觉&#xff0c;自己在想什么呢&#xff0c;也不确定。 这是一篇用语音写的文章&#xff0c;先按自己的想法说出来&#xff0c;然后再适当修改&#xff0c;也许就是一个不错的文章。 看来以后就不需要打字了&#xff0c;语音识别度很高&#…

两数之和--力扣1

两数之和 题目思路C代码 题目 思路 根据题目要求&#xff0c;元素不能重复且不需要排序&#xff0c;我们这里使用哈希表unordered_map。注意题目说了只对应一种答案。 所以我们在循环中&#xff0c;使用目标值减去当前循环的nums[i]&#xff0c;得到差值&#xff0c;如果我们…

ICM20948 DMP代码详解(8)

接前一篇文章&#xff1a;ICM20948 DMP代码详解&#xff08;7&#xff09; 上一回讲解了EMP-App中的入口函数main()中重点关注的第2段代码的后一个函数inv_icm20948_register_aux_compass&#xff0c;讲解了其各个参数&#xff0c;本回对于函数代码进行解析。为了便于理解和回顾…

市场独宠大尺寸超微小间距LED显示屏COB智能会议一体机

在当今这个信息化高速发展的时代&#xff0c;大屏幕显示设备已成为企业会议、教育培训、展览展示、商业广告等多个领域不可或缺的重要工具。随着技术的不断进步&#xff0c;市场上涌现出了投影机、液晶一体机、DLP背投、小间距LED、LED会议一体机以及新兴的COB智能会议一体机等…

vulhub Thinkphp5 2-rce远程代码执行漏洞

步骤一&#xff1a; 执行以下命令启动靶场环境并在浏览器访问 cd /vulhub/thinkphp/2-rce #进入漏洞环境所在目录docker-compose up -d #启动靶场docker ps #查看容器信息 步骤二&#xff1a;访问网页 步骤三&#xff1a;?s/Index/index/L/${phpinfo()} 步骤四&#xff1a;?…

828华为云征文 | 搭建云服务器Flexus X实例,开启简单上云第一步

828华为云征文 | 搭建云服务器Flexus X实例&#xff0c;开启简单上云第一步 Flexus云服务器X实例是一个高度可扩展的云平台&#xff0c;提供了一系列的服务&#xff0c;包括数据处理、应用开发、服务器托管等&#xff1b;对于开发者来说&#xff0c;Flexus云服务器X实例提供了一…

Percona 开源监控方案 PMM 详解

文章目录 前言1. 安装部署1.1 Server 安装1.2 Client 安装 2. 监控数据库2.1 MySQL2.2 PostgreSQL 3. Dashboard 介绍总结 前言 Percona Monitoring and Management (PMM) 是 Percona 公司基于业界流行的组件 Prometheus 和 Grafana 设计开发的一体化数据库监控解决方案。本篇…

vulhub ThinPHP5 2-rce远程代码执行漏洞

1.打开环境 进入环境所在的文件 docker-compose up -d 一键启动 2.浏览器访问环境 3.构造payload ?s/index/index/L/${phpinfo()} 4.写入一句话木马 ?s/Index/index/name/${print(eval($_POST[cmd]))} 5.使用蚁剑连接 http://192.168.10.233:8080/?s/Index/index/name…