夯实spring(二十三): 父子容器

本文要点:

  1. 什么是父子容器
  2. 为什么需要用父子容器
  3. 父子容器如何使用

先来一个案例

系统中有2个模块:module1和module2,两个模块是独立开发的,module2会使用到module1中的一些类,module1会将自己打包为jar提供给module2使用。

模块1

module1.service1

@Component
public class Service1 {public String m1() {return "我是module1中的Servce1中的m1方法";}
}

module1.service2

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Service2 {@Autowiredprivate Service1 service1; public String m1() {return this.service1.m1();}
}

module1.Module1Config

import org.springframework.context.annotation.ComponentScan;
//会自动扫描当前类所在的包中的所有类,将标注有@Compontent注解的类注册到spring容器,即Service1和Service2会被注册到spring容器。
@ComponentScan
public class Module1Config {
}

模块2

module2.Service1

import org.springframework.stereotype.Component;
@Component
public class Service1 {public String m2() {return "我是module2中的Servce1中的m2方法";}
}

module2.Service3

import com.javacode2018.lesson002.demo17.module1.Service2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Service3 {//使用模块2中的Service1@Autowiredprivate module2.Service1 service1;//使用模块1中的Service2@Autowiredprivate module1.Service2 service2;public String m1() {return this.service2.m1();}public String m2() {return this.service1.m2();}
}

module2.Module2Config

@ComponentScan
public class Module2Config {
}

上面的这些使用spring来操作是会有问题的

会报错,因为两个模块中都有Service1,被注册到spring容器的时候,bean名称会冲突,导致注册失败。

运行看一下

public class ParentFactoryTest {@Testpublic void test1() {//定义容器AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();//注册beancontext.register(Module1Config.class, Module2Config.class);//启动容器context.refresh();}
}

Caused by:
org.springframework.context.annotation.ConflictingBeanDefinitionException:
Annotation-specified bean name ‘service1’ for bean class
[module2.Service1] conflicts with existing, non-compatible bean
definition of same name and class [module1.Service1]

我们可以使用spring中的父子容器就可以很好的解决上面这种问题。

什么是父子容器

创建spring容器的时候,可以给当前容器指定一个父容器。

方式1:BeanFactory的方式

//创建父容器parentFactory
DefaultListableBeanFactory parentFactory = new DefaultListableBeanFactory();
//创建一个子容器childFactory
DefaultListableBeanFactory childFactory = new DefaultListableBeanFactory();
//调用setParentBeanFactory指定父容器
childFactory.setParentBeanFactory(parentFactory);

方式2:ApplicationContext的方式

//创建父容器
AnnotationConfigApplicationContext parentContext = new AnnotationConfigApplicationContext();
//启动父容器
parentContext.refresh();
//创建子容器
AnnotationConfigApplicationContext childContext = new AnnotationConfigApplicationContext();
//给子容器设置父容器
childContext.setParent(parentContext);
//启动子容器
childContext.refresh();

父子容器特点

  1. 父容器和子容器是相互隔离的,他们内部可以存在名称相同的bean
  2. 子容器可以访问父容器中的bean,而父容器不能访问子容器中的bean
  3. 调用子容器的getBean方法获取bean的时候,会沿着当前容器开始向上面的容器进行查找,直到找到对应的bean为止
  4. 子容器中可以通过任何注入方式注入父容器中的bean,而父容器中是无法注入子容器中的bean,原因是第2点

使用父子容器解决上面的问题

@Test
public void test2() {//创建父容器AnnotationConfigApplicationContext parentContext = new AnnotationConfigApplicationContext();//向父容器中注册Module1Config配置类parentContext.register(Module1Config.class);//启动父容器parentContext.refresh();//创建子容器AnnotationConfigApplicationContext childContext = new AnnotationConfigApplicationContext();//向子容器中注册Module2Config配置类childContext.register(Module2Config.class);//给子容器设置父容器childContext.setParent(parentContext);//启动子容器childContext.refresh();//从子容器中获取Service3Service3 service3 = childContext.getBean(Service3.class);System.out.println(service3.m1());System.out.println(service3.m2());
}

我是module1中的Servce1中的m1方法
我是module2中的Servce1中的m2方法

springmvc的父子容器

springmvc父子容器就是controller层交给一个spring容器加载,其他的service和dao层交给另外一个spring容器加载,这两个容器组成了父子容器的关系

  • springmvc中只使用一个容器是可以正常运行的。
  • 通常我们使用springmvc的时候,采用3层结构,controller层,service层,dao层;父容器中会包含dao层和service层,而子容器中包含的只有controller层;这2个容器组成了父子容器的关系,controller层通常会注入service层的bean。
  • 采用父子容器可以避免有些人在service层去注入controller层的bean,导致整个依赖层次是比较混乱的。

父容器和子容器的需求也是不一样的,比如父容器中需要有事务的支持,会注入一些支持事务的扩展组件,而子容器中controller完全用不到这些,对这些并不关心,子容器中需要注入一下springmvc相关的bean,而这些bean父容器中同样是不会用到的,也是不关心一些东西,将这些相互不关心的东西隔开,可以有效的避免一些不必要的错误,而父子容器加载的速度也会快一些。

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

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

相关文章

Java05基础 数组

Java05数组 一、数组 数组指的是一种容器,可以用来存储同种数据类型的多个值。 1、数组的静态初始化 初始化:就是在内存中,为数组容器开辟空间,并将数据存入容器中的过程 1.1 数组定义格式 //格式一 数据类型[] 数组名 …

linux tar 压缩文件 排除对应的目录 exclude

有时候需要压缩多个目录,其中 有的目录中携带uploads 目录 如web里面有个uploads目录,我想要屏蔽掉 使用exclude 屏蔽目录 命令如下: tar -czvf archive.tar.gz --excludeweb/uploads/* --excludelogs/ web/ web1/* 错误的命令: tar -czvf archive.tar.gz --exclud…

rush 功能特性梳理

Rush 可以让 JavaScript 开发者更轻松地同时构建、发布多个 NPM 包,即将多个包或项目放到一个大仓库下管理。 仅需一次 NPM 安装 仅需一步,Rush 便可以将你项目的所有依赖安装到一个公共文件夹下,该文件夹并不像 “package.json” 一样位于项…

git 拉取指定目录

指令方式 打开 git 自带的Git Bash 工具 以拉取github中 fastjson 的 /src/test/java/oracle/sql/ 目录为例 1.创建文件夹和git 初始化 cd D:/Program\ Files mkdir fastjson cd fastjson git init 2.设置允许克隆子目录 git config core.sparsecheckout true 3.添加远程…

Tomcat闪退

Tomcat闪退可能由多种原因引起,包括内存不足、程序异常、端口冲突、配置文件错误、版本不兼容、硬件故障等。以下是一些解决Tomcat闪退问题的常见方法: 检查内存:Tomcat运行需要大量的内存资源。如果服务器内存不足,可以尝试增加…

企业大模型如何成为自己数据的“百科全书”?

作者 | 郭炜 编辑 | Debra Chen 在当今的商业环境中,大数据的管理和应用已经成为企业决策和运营的核心组成部分。然而,随着数据量的爆炸性增长,如何有效利用这些数据成为了一个普遍的挑战。 本文将探讨大数据架构、大模型的集成&#xff0…

text-align、align-items 和 justify-content

当我们使用 CSS 来控制布局时&#xff0c;我们可以采用一些通用的属性来控制文本、元素等在页面上的位置和对齐方式。下面是关于 text-align、align-items 和 justify-content 的通用总结 text-align&#xff1a; 适用范围&#xff1a; 适用于文本元素&#xff0c;如 <p>…

Win10安装mamba个人总结的2种实现方式

强烈推荐大家参考这篇文章&#xff0c;讲述的完整且全面。 Mamba 环境安装踩坑问题汇总及解决方法_error: could not build wheels for causal-conv1d, w-CSDN博客 我的环境是win10&#xff0c;Pycharm2019&#xff0c;miniconda&#xff0c;Python 3.10.14&#xff0c;cuda …

c语言指针学习:交换变量值1

交换地址和交换指针 //交换pt_x和pt_y所指向的地址int *temp;temp pt_x; pt_x pt_y; pt_y temp; //交换pt_x和pt_y的值int temp;temp *pt_x; *pt_x *pt_y; *pt_y temp; 假如没有指针p int i1; p&i; //p指的是所指向变量的地址 即 i的地址 //*p指的是指针所指…

Google I/O 2024:探索未来AI技术的无限可能

近日&#xff0c;Google I/O 2024大会圆满落幕&#xff0c;带给我们一场关于人工智能的盛宴。在这场大会上&#xff0c;Google推出了一系列令人激动的AI新功能和工具&#xff0c;让我们得以一窥未来的科技发展。今天&#xff0c;就让我来为大家总结一下这些亮点吧&#xff01; …

springboot报错‘url’ attribute is not specified and no embedded datasource could

APPLICATION FAILED TO START Description: Failed to configure a DataSource: ‘url’ attribute is not specified and no embedded datasource could be configured. Reason: Failed to determine a suitable driver class Action: Consider the following: If you wa…

你是学会了还是学废了:Elasticsearch 7 集群拷贝到其它环境如何重置密码

欢迎您关注我的公众号【尚雷的驿站】 公众号&#xff1a;尚雷的驿站 CSDN &#xff1a;https://blog.csdn.net/shlei5580 墨天轮&#xff1a;https://www.modb.pro/u/2436 PGFans&#xff1a;https://www.pgfans.cn/user/home?userId4159 前言 本文描述了将生产ES集群打包拷贝…

知识图谱 | 语义网络写入图形数据库(含jdk和neo4j的安装过程)

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本文主要介绍如何使用 Neo4j 图数据库呈现语义网络&#xff0c;并通过 Python 将语义网络的数据写入数据库。具体步骤包括识别知识中的节点和关系&#xff0c;将其转化为图数据库的节点和边&#xff0c;最后通过代码实现数据的写…

【车载开发系列】AUTOSAR BSW基础模块常用术语

【车载开发系列】AUTOSAR BSW基础模块常用术语 BSW供应商提供的AUTOSAR BSW模块有&#xff1a;EcuM、Os、WdgM、WdgIf、BswM、Rte这六种。AUTOSAR BSW当中常用的属于如下。 名称说明WdgMWatchdog Manager的简称WdgIfWatchdog Interface的简称BswMBasic Software Manager的简称…

css案例 tab上下滚动,左右滚动

效果图&#xff1a; 完整代码&#xff1a; <template><view class"content"><view class"content-item"><view class"content-title"><h4>美食热搜</h4><ul><li>火鸡面</li><li>糖…

听劝!普通人千万别随意入门网络安全

一、什么是网络安全 网络安全是一种综合性的概念&#xff0c;涵盖了保护计算机系统、网络基础设施和数据免受未经授权的访问、攻击、损害或盗窃的一系列措施和技术。经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”…

Batch Normalization 批归一化 每个mini-batch进行归一化操作 显著提高深度神经网络的训练速度和性能

Batch Normalization Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift NLP相关Paper笔记和代码复现 本文提出了Batch Normalization(批标准化)技术,旨在加速深度神经网络的训练过程,并通过减少内部协变量偏移(internal…

图文教程 | 2024年IDEA安装使用、破解教程,JDK简易下载方法

前言 &#x1f4e2;博客主页&#xff1a;程序源⠀-CSDN博客 &#x1f4e2;欢迎点赞&#x1f44d;收藏⭐留言&#x1f4dd;如有错误敬请指正&#xff01; 目录 一、IDEA安装 二、激活 三、JDK安装 四、JDK环境配置 五、验证 一、IDEA安装 进入官网下载&#xff1a; Other…

命令行中,Python 想使用本地环境,但总是显示为Anaconda的虚拟环境

电脑环境 Python 本地环境&#xff08;Python3.9.5&#xff09;Anaconda 虚拟环境&#xff08;Python3.8.8&#xff09; 遇到的问题 在cmd 中&#xff0c;我想在本地环境使用 Python、pip &#xff0c;但它却是一直识别成Anaconda的虚拟环境。 解决方法 环境变量配置中&am…

Go Gin使用JWT实现认证机制

什么是JWT JWT是JSON Web Token的缩写,是一种跨域认证的解决方案。 使用JWT解决什么问题 传统的登录认证的实现,依赖客户端浏览器的cookie和服务器的session,这种实现登录的方式有很大的局限性。 对于部署在单台服务器的应用来说,使用cookie+session登录认证的方案尚…