IOC 的底层原理和Bean管理XML方式、xml注入集合属性

news/2024/4/20 16:57:30/文章来源:https://blog.csdn.net/m0_57448314/article/details/128091436

目录

    什么是IOC 

          IOC底层管理 

工厂模式

IOC 的过程 

IOC 接口

 IOC 操作Bean 原理

Bean 管理操作有两种方式

1. 基于xml 配置方式创建对象

2. 基于xml方式注入属性

第二种使用有参数构造注入

p 名称空间注入

 ICO操作Bean管理(xml 注入其他类型属性)

注入属性-外部bean

注入属性 - 内部 bean 和级联赋值

IOC 操作Bean管理(xml注入集合属性)

在spring配置文件进行配置

在集合里面设置对象类型值

把集合部分注入提取出来


    什么是IOC 

        控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理
        使用IOC目的,为了降低耦合度 

    IOC底层管理 

          xml解析、工厂模式、反射

IOC的实现原理—反射与工厂模式的结合

工厂模式

下面是原始的模式

耦合度太高导致service 和到任何一个发生变化,另一个都会发生变化,所以我们需要将耦合度降低,并且降低到最低限度。

再看看工厂模式,下图通过工厂模式降低 service 和 Dao 的耦合性,最终的目的是将耦合度降低到最低限度。

IOC 的过程 

第一步:xml配置文件,配置创建的对象

<bean id= "dao" class="com.aiguigu.UserDao"></bean>

第二步,有service类和dao类,创建工厂类。

之前是直接new一个对象,但现在不这样做了,现在通过xml 解析和反射来完成。

由xml 解析来获取上面的值,然后通过反射得到编码文件创建对象

 目的:进一步降低耦合度

IOC 接口

1.IOC思想基于IIOC容器完成,IOC容器底层就是对象工厂。

2.Spring  提供IOC容器实现两种方式:(有两个接口) 

  BeanFactory :IOC容器基本实现,是spring 内部的使用接口,不提供开发人员进行使用

ApplicationContext :BeanFactory 接口的子接口,提供更多强大的功能,一般由于开发人员进行使用。

加载配置文件 时候就会把配置文件对象进行创建。

ApplicationContext 接口有实现类:

 IOC 操作Bean 原理

什么是Bean管理

Bean 管理指的是两个操作:Spring 创建对象、Spring注入属性。

如下,在创建对象过程中获取属性就叫bean管理。

创建了一个userName 属性,然后向username中设置值

public class User {private String userName;public void add() {System.out.println("add....");}
}

Bean 管理操作有两种方式

第一种: 基于xml 配置方式实现

第二种:基于注解方式实现

IOC 操作Bean 管理(基于xml方式)

1. 基于xml 配置方式创建对象

 配置User对象创建

<bean id= "dao" class="com.aiguigu.UserDao"></bean>

 1. 在spring 配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建。

2. 在bean标签有很多属性,介绍常用的属性:

id 属性:唯一标识

class属性:类全路径(包类路径)

3. 创建对象时候,默认也是执行无参数构造方法完成对象创建

2. 基于xml方式注入属性

DI : 依赖注入,就是注入属性

第一种注入方式,使用set方法进行注入。

public class Book {//使用set方法进行注入属性//创建属性private String bname;private String bautbur;//创建属性对应的set方法public void setBautbur(String bautbur) {this.bautbur = bautbur;}public void Book(String bname) {this.bname = bname;}
}

在spring 配置文件配置对象创建,配置属性注入

    <bean id="book" class="com.atguigu.spring5.Book"><!-- 使用property 完成属性注入name 类里面属性名称value :向属性注入的值--><property name="bname" value="异烟肼"></property><property name="bautbur" value="贵妃椅"></property></bean>

第二种使用有参数构造注入

1.创建类,定义属性,创建属性对应有参数构造方法

public class Orders {//属性private String oname;private String address;//有参构造public Orders(String oname, String address) {this.oname = oname;this.address = address;}
}

 在spring配置文件中进行配置

    <!--有参构造注入属性--><bean id="orders" class="com.atguigu.spring5.Orders"><constructor-arg name="oname" value="abc"></constructor-arg><constructor-arg name="address" value="China"></constructor-arg></bean>

p 名称空间注入

使用 p 名称空间注入,可以简化基于xml 配置方式。

第一步 添加p名称空间在配置文件中

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</bean>

第二步进行属性注入,在bean标签里面进行操作

    <bean id="book" class="com.atguigu.spring5.Book" p:bname="spring入门" p:bautbur="spring5书籍"></bean>
</beans>

 ICO操作Bean管理(xml 注入其他类型属性)

字面量

null

        <!--null值--><property name="address"><null/></property>

属性值包含特殊字符

  把<>进行转义&lt;&;

把带特殊字符内容写到CDATA

        <property name="address"><value><![CDATA[<<南京>>]]></value></property>

注入属性-外部bean

先看看原始的方式:创建 UserDao 对象

    public void add(){System.out.println("UserService  add...");//原始方式创建:创建 UserDao 对象UserDao userDao = new UserDaoImpI();userDao.update();}

 下面用另一种方式创建,先创建Userdao、Userservice、UserImpI层,在UserDaoImpI中创建两个对象,然后在Userservice注入到里面,可以有参构造也可以用set构造,之前是使用字符串类型,一个一个地注入,现在使用的是Userdao是对象类型,也可以是属性也可以是字符串、对象都可以,现在Userservice里面把UserDaoImpI注入。

先创建两个类service类和dao类,在service调用dao里面的方法,在spring配置文件中进行配置

UserDao

package com.atguigu.spring5.dao;public interface UserDao {public void update();
}

 UserDaoImpI

package com.atguigu.spring5.dao;public class UserDaoImpI implements UserDao{@Overridepublic void update() {System.out.println("dao update.....");}
}

UserService 

public class UserService {//创建UserDao类型属性生成set方法private UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;}public void add() {System.out.println("UserService  add...");
/*        //原始方式创建:创建 UserDao 对象UserDao userDao = new UserDaoImpI();*/userDao.update();}}

 xml 文件

    <!--service 和 dao 对象创建--><bean id="userService" class="com.atguigu.spring5.dao.UserDao.UserService"><!--注入userDao对象name 属性值:类里面属性名称ref 属性:创建 userDao 对象bean标签id值--><property name="userDao" ref="userDaoImpI"></property></bean>

注入属性 - 内部 bean 和级联赋值

一对多关系:部门和员工

一个部门有多个员工,一个员工属于一个部门;部门是一,员工是多。

在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示。

部门类

//部门类
public class Dept {private String dname;public void setDname(String dname) {this.dname = dname;}
}

员工类

//员工类
public class Emp {private String ename;private String gender;//员工属于某个部门,使用对象形式表示private Dept dept;public void setDept(Dept dept) {this.dept = dept;}public void setEname(String ename) {this.ename = ename;}public void setGender(String gender) {this.gender = gender;}
}

下面是内部bean ,内部bean效率较高,但大多数人喜欢外部bean的写法

<bean id="emp" class="com.atguigu.spring5.bean.Emp">  <!--设置两个普通属性 -->  <property name="ename" value="lucy"></property>  <property name="gender" value="女"></property>  <!--设置对象类型属性-->  <property name="dept>">  <bean id="dept" class="com.atguigu.spring5.bean.Dept">  <property name="dname" value ="安保部"></property>  </bean>  </property>  
</bean>

  注入属性-级联赋值 :

<bean id="emp" class="com.atguigu.spring5.bean.Emp">  <!--设置两个普通属性 -->  <property name="ename" value="lucy"></property>  <property name="gender" value="女"></property>  <!--级联赋值-->  <property name="dept>" ref="dept"></property>  
</bean>  
<bean id="dept" class="com.atguigu.spring5.bean.Dept">  <property name="dname" value="财务部"></property>  
</bean>

IOC 操作Bean管理(xml注入集合属性)

  • 注入数组类型属性
  • 注入List集合类型属性
  • 注入Map集合类型属性

创建类,定义数组、list、map、set 类型属性,生成对应set方法

public class Stu {//1. 数组类型属性private String[] courses;//2. list 集合类型属性private List<String> list;//3. map 集合类型属性private Map<String,String> map;//4. set 集合类型属性private Set<String> sets;public void setSets(Set<String> sets) {this.sets = sets;}public void setCourses(String[] courses) {this.courses = courses;}public void setList(List<String> list) {this.list = list;}public void setMap(Map<String, String> map) {this.map = map;}
}

在spring配置文件进行配置

数组类型属性注入

    <!--1.数组类型属性注入--><property name="courses"><array><value>java课程</value><value>数据库课程</value></array></property>

list 类型属性注入 

        <!--2. list 类型属性注入--><property name="list"><list><value>张三</value><value>小三</value></list></property>

map 类型注入 

        <!--map 类型注入--><property name="map"><map><entry key="JAVA" value="java"></entry><entry key="PHP" value="php"></entry></map></property>

set 类型属性注入 

        <!--set类型属性注入--><property name="sets"><set><value>MySQL</value><value>Redis</value></set></property>

 集合类型属性注入

    <!--1. 集合类型属性--><bean id="stu" class="com.atguigu.spring5.collectiontype.Stu"><!--1.数组类型属性注入--><property name="courses"><array><value>java课程</value><value>数据库课程</value></array></property><!--2. list 类型属性注入--><property name="list"><list><value>张三</value><value>小三</value></list></property><!--3. map 类型注入--><property name="map"><map><entry key="JAVA" value="java"></entry><entry key="PHP" value="php"></entry></map></property><!--4.set类型属性注入--><property name="sets"><set><value>MySQL</value><value>Redis</value></set></property>
</bean>

在集合里面设置对象类型值

创建多个course对象
    <!-- 创建多个course对象--><bean id="course1" class="com.atguigu.spring5.collectiontype.Course"><property name="cname" value="Spring5框架"></property></bean><bean id="course2" class="com.atguigu.spring5.collectiontype.Course"><property name="cname" value="MyBatis框架"></property></bean>
注入list集合类型,值是对象
<!-- 注入list集合类型,值是对象--><property name="courseList"><list><ref bean="course1"></ref><ref bean="course2"></ref></list></property>

把集合部分注入提取出来

在spring配置文件中引入名称空间until

<?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:p="http://www.springframework.org/schema/p"xmlns:until="http://www.springframework.org/schema/util"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

使用until标签完成list集合注入提取

    <!--1. 提取list集合类型属性注入--><until:list id="booklist"><value>JOJO</value><value>南计划</value><value>破解</value></until:list>
提取list集合类型属性注入使用
    <!--2. 提取list集合类型属性注入使用--><bean id="book" class="com.atguigu.spring5.collectiontype.Book"><property name="list" ref="booklist"></property></bean>

测试类

     @Testpublic void testCollection2(){ApplicationContext context =new ClassPathXmlApplicationContext("bean2.xml");Book stu = context.getBean("book", Book.class);stu.test();}

输出

public class Book {public List<String> list;public void setList(List<String> list) {this.list = list;}public void test(){System.out.println(list);}}

   

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

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

相关文章

翻转单词序列、按之字形顺序打印二叉树、二叉搜索树的第k个节点

1、翻转单词序列 本题考点&#xff1a;子串划分&#xff0c;子串逆置 牛客链接 题目描述&#xff1a; 牛客最近来了一个新员工Fish&#xff0c;每天早晨总是会拿着一本英文杂志&#xff0c;写些句子在本子上。同事Cat对Fish写的内容颇感兴趣&#xff0c;有一天他向Fish借来翻…

网络安全与IP安全

网络安全 是指网络系统的硬件&#xff0c;软件以及系统中的数据收到的保护。 保护的基本属性为&#xff1a;机密性&#xff0c;身份认证&#xff0c;完整性和可用性&#xff1b; 基本特征&#xff1a;相对性&#xff0c;时效性&#xff0c;相关性&#xff0c;不确定性&#xf…

azkaban表project_flows数据分析

project_flows表中数据是怎么存入进去的呢,其中有个JSON字符串是乱码,怎么设置的呢?搜索插入语句地方如下: 查看压缩类型,2为Gzip压缩 public enum EncodingType {PLAIN(1), GZIP(2); 查看flow.toObject方法,其实返回的是一个MAP,定义如下: 查看convertJsonToBytes方…

YonBuilder开发之后端函数

在前几期的文章中我们已经介绍过如何在YonBuilder中使用前端函数实现数据过滤功能。相对应于前端函数&#xff0c;在YonBuilder中还可以使用后端函数实现对于程序的扩展。通过前端函数实现的更多的是与页面交互相关的功能&#xff0c;而后端函数主要是用于预制按钮功能的扩展开…

自然算法 - AI面试基础补全

手撕BP神经网络手写Bert和Transformer&#xff08;BERT很细节的地方&#xff0c;比如文字标签CLS&#xff0c;par&#xff09;学习pytorch&#xff0c;tensorflow AI算法岗位 可看网站 牛客网站 面经回复 github 项目连接 算法工程师岗位必备知识 问答 ELMO、GPT、…

操作系统_多线程笔记(二)

文章目录1.线程状态2.多线程在的意义是什么?1.线程状态 状态是针对当前线程调度的情况来描述的,因为线程是系统调度的基本单位,所以状态是属于线程的属性 线程的六种状态: 注意: 1.一旦内核里的PCB消亡了,此时代码中创建的thread也就没有用了,即内核里的线程释放的时候无…

信号包络及其提取方法(Matlab)

信号包络及其提取方法 介绍信号包络&#xff0c;以及信号包络的提取方法。 一、信号包络 直观地从时域来讲&#xff0c;信号包络就是信号波形的轮廓。 本质上&#xff0c;信号包络是带通信号的基带部分。 一个实带通信号记为x(t)&#xff0c;将它频谱的中心频点搬移到零频…

Win,M1Mac上安装jupyter的MATLAB支持插件的方法

tags: MATLAB Win Mac Tips 写在前面 11月的最后一天了, 总结一下支持MATLAB的一个jupyter的插件, 有了这个你就可以在jupyter notebook或者jupyter lab上面使用MATLAB语句了, 还是很不错的, 虽然我安装了好久… 下面来说一下我在我的电脑以及朋友的电脑(Win11)上面安装这个…

实例方法(instance method)、类方法、构造方法(三)

实例方法&#xff08;没有static&#xff09;的概念 对象被称为实例。实例相关的有&#xff1a;实例变量、实例方法。实例变量是对象变量。实例方法是对象方法。实例方法没有static。&#xff08;对象方法&#xff0c;对象级别的方法&#xff09; 实例方法的调用需要先new一个…

高维多元时序数据聚类

1. 简介 收集数据的能力不断增强&#xff0c;使我们有可能收集大量的异构数据。在可用的异构数据中&#xff0c;时间序列代表着尚未被充分探索的信息母体。当前的数据挖掘技术在分析时间序列时存在多个缺点&#xff0c;尤其是在应同时分析多个时间序列&#xff08;即多维时间序…

JVM运行时数据 堆

JVM运行时数据 堆快速调试堆参数设置堆分类运行流程Minor GC、Major GC与Full GC分代思想内存分配策略TLAB堆空间参数设置快速调试 一个JVM实例只存在一个堆内存&#xff0c;对也是Java内存管理的核心区域Java 堆区在Jvm启动的时候创建&#xff0c;其空间大小也就确定了。是JV…

[附源码]计算机毕业设计springboot课室预约系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

NVIDIA 7th SkyHackathon(八)使用 Flask 与 Vue 开发 Web

1.页面效果 Web 采用 flaskvue 开发&#xff0c;效果图如下 2.后端 import sys import subprocess import os from PIL import Image from datetime import datetime from ASR_metrics import utils as metricsfrom werkzeug.wrappers import Request, Response from …

分层架构理论基础

一、三层架构 1、什么是三层架构 三层架构&#xff08;3-tier architecture&#xff09;通常意义上的三层架构就是将整个业务应用划分为&#xff1a;表示层&#xff08;User Interface layer&#xff09;、业务逻辑层&#xff08;Business Logic Layer&#xff09;、数据访问层…

数仓之hive自定义UDTF函数详解

学习目录一、自定义UDTF函数一、自定义UDTF函数 1.说明文档 A custom UDTF can be created by extending the GenericUDTF abstract class and then implementing the initialize, process, and possibly close methods. The initialize method is called by Hive to notify t…

本机使用python操作hdfs搭建及常见问题

一.虚拟机安装CentOS7并配置共享文件夹 二.CentOS 7 上hadoop伪分布式搭建全流程完整教程 三.本机使用python操作hdfs搭建及常见问题 四.mapreduce搭建 五.mapper-reducer编程搭建 本机使用python操作hdfs搭建及常见问题一、环境搭建1.打开虚拟机系统&#xff0c;打开hadoop2.修…

高效率开发Web安全扫描器之路(一)

一、背景 经常看到一些SRC和CNVD上厉害的大佬提交了很多的漏洞&#xff0c;一直好奇它们怎么能挖到这么多漏洞&#xff0c;开始还以为它们不上班除了睡觉就挖漏洞&#xff0c;后来有机会认识了一些大佬&#xff0c;发现它们大部分漏洞其实是通过工具挖掘的&#xff0c;比如说下…

安卓版微信8.0.31内测版出炉:安装包变小,功能变多!

人是社会性生物&#xff0c;建立依恋、经营亲密关系是人的本能&#xff0c;只不过到了网络时代之后&#xff0c;用户进行交流的方式几乎都变成了微信等社交软件。 不仅可以让用户很便捷的和朋友进行沟通&#xff0c;并且在上班办公的时候&#xff0c;也是可以轻松传输文件等&a…

MCUXpresso IDE下高度灵活的FreeMarker链接文件模板机制

一、准备工作 首先需要准备好环境&#xff0c;包含必要的软件&#xff0c;痞子衡的环境如下&#xff1a; 集成开发环境&#xff1a; MCUXpresso IDE_11.6.0_8187&#xff0c;点此下载软件开发包&#xff1a; SDK_2.12.1_EVK-MIMXRT1170&#xff08;Toolchain需包含MCUXpresso I…

Compose学习-> Text()

设置文本&#xff1a;text xxx 直接设置 Text(text "我是一个Text")引用资源文件&#xff1a;stringResource Text(text stringResource(id R.string.string_text))设置字体颜色&#xff1a;color xxx 引用系统自带的颜色 Text(text "我是一个Text"…