Java Spring创建bean流程及自定义构造方法示例

news/2024/4/27 23:08:44/文章来源:https://blog.csdn.net/qq_34207422/article/details/137018804

一、spring容器创建bean的简单步骤
1、扫描被@Service,@Component等注解标识的类。
2、找到类的构造方法
默认使用无参构造方法构建bean,如果类中定义了有参构造方法则会按照有参构造方法构建bean。
3、依赖注入
如果类中存在@Autowired或有参的构造方法,会先从单例池获取对象,如果单例池没有对象则会创建对象,之后在放入单例池中 。如果有构造方法,会在注入完成后去执行该方法,进行一些属性的配置等。
4、执行spring的其他机制
(1)、实现aware类型的接口则会去执行相对应的set方法;
(2)、实现InitializingBean接口则会执行对应afterProperties方法;
(3)、系统定义了实现BeanPostProcessor接口的类,会在创建每一个bean之前执行(postProcessBeforeInitialization)和之后执行(postProcessAfterInitialization)方法等等。
5、使用bean
(1)、使用@Autowired,@Resource注解注入
(2)、被扫描的类存在构造方法,构造方法参数中获取bean。常用于当前bean的其他属性赋值。

二、自定义构造方法创建bean代码示例
1、创建统一的出售服务SailService

import com.zw.study.springBean.dto.Fruit;
public interface SailService {String getFruitType();   // 定义类型,用于区分实现类void addOrder(Fruit fruit);
}

2、实例化苹果和梨的SailService

// 苹果的实现类
import com.zw.study.springBean.dto.Fruit;
import com.zw.study.springBean.service.SailService;
import org.springframework.stereotype.Service;
@Service
public class AppleSailServiceImpl implements SailService {@Overridepublic String getFruitType() {return "apple";}@Overridepublic void addOrder(Fruit fruit) {System.out.println("新增苹果的订单");}
}// 梨子的实现类
import com.zw.study.springBean.dto.Fruit;
import com.zw.study.springBean.service.SailService;
import org.springframework.stereotype.Service;
@Service
public class PearSailServiceImpl implements SailService {@Overridepublic String getFruitType() {return "pear";}@Overridepublic void addOrder(Fruit fruit) {System.out.println("新增梨子的订单");}
}

3、订单服务根据业务类型选择不同Service去执行(自定义构造方法)

import com.zw.study.springBean.dto.Fruit;
import com.zw.study.springBean.service.SailService;
import com.zw.study.springBean.service.FruitService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;@Service
public class FruitServiceImpl implements FruitService {// 所有销售服务的封装Mapprivate Map<String, SailService> fruitSailServiceMap = new HashMap<>();// 说明:本例中因为SailService有多个实现类,需要区分业务在不同情况下选择不同的类去执行,所以不能直接通过@Autowired去注入SailService服务,所以这里需要创建Map将所有的SailService都获取到,之后业务在根据自己的需要选择Service去执行。// 这里的Map是FruitServiceImpl的一个属性。本例通过指定带参的构造方法去封装属性。spring容器在加载FruitServiceImpl这个bean的时候通过这个有参的构造方法去创建实例,之后在这个构造方法中去封装属性Map// 注意:如果没有指定任何构造方法的话,java会默认提供一个无参的构造方法,但是指定了就不会有默认的构造方法了。// 参数SailService[],容器会在创建该bean的时候,从spring容器的单例池去获取,如果不存在则会先创建之后在放入单例池中public FruitServiceImpl(SailService[] sailServices){for (SailService sailService : sailServices){String fruitType = sailService.getFruitType();if (!fruitSailServiceMap.containsKey(fruitType)){fruitSailServiceMap.put(fruitType, sailService);}}}@Overridepublic void sailFruit(Fruit fruit) {// 根据参数指定的类型,选择对应的销售服务去创建订单SailService sailService = getSailServie(fruit);sailService.addOrder(fruit);}// 根据类型获取指定的业务处理服务private SailService getSailServie(Fruit fruit) {String type = fruit.getType();return fruitSailServiceMap.get(type);}
}

4、测试验证
参数传不同的类型
在这里插入图片描述
在这里插入图片描述

以上完成了通过自定义构造方法,实例化bean的过程。常用于:
1、一个通用接口,有多个实例对象的场景
2、创建bean时封装bean的属性

附:
BeanPostProcessor:
是Spring框架中非常强大的一个接口,它允许开发者在Spring容器创建和初始化Bean的过程中插入自定义的逻辑。亲测会在每一个bean创建的过程中都会被调用一次,因此业务需要梳理清晰,不要做很多无畏的操作。可以在此方法中设置bean的属性,或者配合自定义注解完成一些特俗业务等。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {// bean创建之前执行 @Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("**Before Initialization****: " + beanName);return bean; // 返回原bean或修改后的bean}// bean创建之后执行 @Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("**After Initialization****: " + beanName);return bean; // 返回原bean或修改后的bean}
}

学海无涯苦作舟!!!

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何使用PHP和RabbitMQ实现延迟队列(方式二)?

前言 前几天写了一篇关于PHP和RabbitMQ如何通过插件实现延迟队列的功能。 今天写另外一篇不需要插件的方式&#xff0c;使用RabbitMQ的死信队列&#xff08;Dead-Letter-Exchanges, DLX&#xff09;和消息TTL&#xff08;Time-To-Live&#xff09;。 这种方法涉及到设置消息…

记一次 .NET某防伪验证系统 崩溃分析

一&#xff1a;背景 1. 讲故事 昨晚给训练营里面的一位朋友分析了一个程序崩溃的故障&#xff0c;因为看小伙子昨天在群里问了一天也没搞定&#xff0c;干脆自己亲自上阵吧&#xff0c;抓取的dump也是我极力推荐的用 procdump 注册 AEDebug 的方式&#xff0c;省去了很多沟通…

[flink] flink macm1pro 快速使用从零到一

文章目录 快速使用 快速使用 打开 https://flink.apache.org/downloads/ 下载 flink 因为书籍介绍的是 1.12版本的&#xff0c;为避免不必要的问题&#xff0c;下载相同版本 解压 tar -xzvf flink-1.11.2-bin-scala_2.11.tgz启动 flink ./bin/start-cluster.sh打开 flink web…

RTOS线程切换的过程和原理

0 前言 RTOS中最重要的一个概念就是线程&#xff0c;线程的按需切换能够满足RTOS的实时性要求&#xff0c;同时能将复杂的需求分解成一个个线程执行减轻我们开发负担。 本文从栈的角度出发&#xff0c;详细介绍RTOS线程切换的过程和原理。 注&#xff1a;本文参考的RTOS是RT-T…

<QT基础(5)>事件监听

事件监听 事件监听&#xff08;Event Handling&#xff09;是在程序中监视和响应发生的事件的一种机制。在Qt中&#xff0c;事件监听是一种常见的用于处理用户输入、系统事件以及其他类型事件的方法。通过事件监听&#xff0c;您可以在发生特定事件时捕获事件并执行相应的操作…

【AI】在本地 Docker 环境中搭建使用 Hugging Face 托管的 Llama 模型

目录 Hugging Face 和 LLMs 简介利用 Docker 进行 ML格式的类型请求 Llama 模型访问创建 Hugging Face 令牌设置 Docker 环境快速演示访问页面入门克隆项目构建镜像运行容器结论推荐超级课程: Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战Hugging Fa…

7、鸿蒙学习-共享包概述

HarmonyOS提供了两种共享包&#xff0c;HAR&#xff08;Harmony Archive&#xff09;静态共享包&#xff0c;和HSP&#xff08;Harmony Shared Package&#xff09;动态共享包。 HAR与HSR都是为了实现代码和资源的共享&#xff0c;都可以包含代码、C库、资源和配置文件&#xf…

iPhone用GPT替代Siri

shigen坚持更新文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 个人IP&#xff1a;shigen 前一段时间&#xff0c;因为iCloud协议的更新&#xff0c;我的云盘空间无法正常…

RISC-V特权架构 - 中断定义

RISC-V特权架构 - 中断定义 1 中断类型1.1 外部中断1.2 计时器中断1.3 软件中断1.4 调试中断 2 中断屏蔽3 中断等待4 中断优先级与仲裁5 中断嵌套6 异常相关寄存器 本文属于《 RISC-V指令集基础系列教程》之一&#xff0c;欢迎查看其它文章。 1 中断类型 RISC-V 架构定义的中…

helm 部署 Kube-Prometheus + Grafana + 钉钉告警部署 Kube-Prometheus

背景 角色IPK8S 版本容器运行时k8s-master-1172.16.16.108v1.24.1containerd://1.6.8k8s-node-1172.16.16.109v1.24.1containerd://1.6.8k8s-node-2172.16.16.110v1.24.1containerd://1.6.8 安装 kube-prometheus mkdir -p /data/yaml/kube-prometheus/prometheus &&…

CDH集群hive初始化元数据库失败

oracle数据库操作&#xff1a; 报错如下&#xff1a;命令 (Validate Hive Metastore schema (237)) 已失败 截图如下&#xff1a; 后台日志部分摘录&#xff1a; WARNING: Use “yarn jar” to launch YARN applications. SLF4J: Class path contains multiple SLF4J binding…

UE RPC 外网联机(1)

技术&#xff1a;RPC TCP通信 设计&#xff1a;大厅服务<---TCP--->房间服务<---RPC--->客户端&#xff08;Creator / Participator&#xff09; 1. PlayerController 用于RPC通信控制 2.GameMode 用于数据同步 3.类图 4. 注意 &#xff08;1&#xff09;RPC&a…

机器学习之决策树现成的模型使用

目录 须知 DecisionTreeClassifier sklearn.tree.plot_tree cost_complexity_pruning_path(X_train, y_train) CART分类树算法 基尼指数 分类树的构建思想 对于离散的数据 对于连续值 剪枝策略 剪枝是什么 剪枝的分类 预剪枝 后剪枝 后剪枝策略体现之威斯康辛州乳…

GIMP - GNU 图像处理程序 - 工具栏窗口 (Toolbox)

GIMP - GNU 图像处理程序 - 工具栏窗口 [Toolbox] 1. GNU Image Manipulation Program2. Windows -> Recently Closed Docks -> ToolboxReferences 1. GNU Image Manipulation Program 2. Windows -> Recently Closed Docks -> Toolbox References [1] Yongqiang …

软件概要设计说明书word原件(实际项目)

一、 引言 &#xff08;一&#xff09; 编写目的 &#xff08;二&#xff09; 范围 &#xff08;三&#xff09; 文档约定 &#xff08;四&#xff09; 术语 二、 项目概要 &#xff08;一&#xff09; 建设背景 &#xff08;二&#xff09; 建设目标 &#xff08;三&a…

Typora字数过多的时候造成卡顿现象如何解决?

Typora字数过多的时候造成卡顿现象如何解决&#xff1f; 点击 、切换、滚动、打字都有点卡顿&#xff0c;下面介绍三种方法&#xff0c;三种方法都可以尝试&#xff0c;建议先尝试方法一&#xff0c;效果不满意就用方法二&#xff0c;实在不行就最后一个取巧的办法。 方法1&a…

图像处理与视觉感知---期末复习重点(5)

文章目录 一、膨胀与腐蚀1.1 膨胀1.2 腐蚀 二、开操作与闭操作 一、膨胀与腐蚀 1.1 膨胀 1. 集合 A A A 被集合 B B B 膨胀&#xff0c;定义式如下。其中集合 B B B 也称为结构元素&#xff1b; ( B ^ ) z (\hat{B})z (B^)z 表示 B B B 的反射平移 z z z 后得到的新集合。…

《Vision mamba》论文笔记

原文出处&#xff1a; [2401.09417] Vision Mamba: Efficient Visual Representation Learning with Bidirectional State Space Model (arxiv.org) 原文笔记&#xff1a; What&#xff1a; Vision Mamba: Efficient Visual Representation Learning with Bidirectional St…

llama-index 结合chatglm3-6B 利用RAG 基于文档智能问答

简介 llamaindex结合chatglm3使用 import os import torch from llama_index.core import VectorStoreIndex, ServiceContext from llama_index.core.callbacks import CallbackManager from llama_index.core.llms.callbacks import llm_completion_callback from llama_ind…

Groovy基础入门

一、Groovy简介 Groovy是运行在JVM中的一种动态语言&#xff0c;可以在Java平台上进行编程&#xff0c;使用方式基本与使用Java代码的方式相同&#xff0c;它的语法与Java语言的语法很相似&#xff0c;与Java相比&#xff0c;Groovy更加灵活、简洁&#xff0c;而且完成同样的功…