基于XML配置bean(二)

news/2024/5/17 12:51:16

文章目录

    • 1.工厂中获取bean
        • 1.静态工厂
          • 1.MyStaticFactory.java
          • 2.beans.xml
          • 3.测试
        • 2.实例工厂
          • 1.MyInstanceFactory.java
          • 2.beans.xml
          • 3.测试
        • 3.FactoryBean(重点)
          • 1.MyFactoryBean.java
          • 2.beans.xml
          • 3.测试
    • 2.bean配置信息重用
        • 继承抽象bean
          • 1.beans.xml
          • 2.测试
    • 3.bean细节介绍
        • 1.bean的创建顺序
          • 1.depends-on关键字
          • 2.问题引出
        • 2.bean对象的单例和多例
          • 1.应用实例
          • 2.使用细节
          • 3.单例与多例对比
            • 单例(非懒加载)
            • 单例(懒加载)
            • 多例
        • 3.bean的生命周期
          • 1.基本介绍
          • 2.简化来说
          • 3.生命周期演示案例
            • 1.House.java
            • 2.beans.xml
            • 3.测试
          • 4.配置bean后置处理器(难点)
            • 1.MyBeanPostProcessor.java
            • 2.beans02.xml
            • 3.测试
          • 5.通过属性文件配置bean
            • 1.src下创建my.properties
            • 2.beans03.xml
            • 3.测试
          • 6.自动装配bean
            • 1.OrderDao.java
            • 2.OrderService.java
            • 3.OrderServlet.java
            • 4.通过类型自动装配
            • 5.通过名字自动装配
            • 6.测试
          • 7.Spring El表达式(了解)

1.工厂中获取bean

1.静态工厂
1.MyStaticFactory.java
package com.sxs.spring.bean;import java.util.HashMap;
import java.util.Map;/*** @author 孙显圣* @version 1.0*/
public class MyStaticFactory {//hashmap存储对象private static Map<String, Monster> monsterHashMap;//静态代码块进行初始化static {monsterHashMap = new HashMap<>();//放进去两个对象monsterHashMap.put("monster01", new Monster(1, "牛魔王", "芭蕉扇"));monsterHashMap.put("monster01", new Monster(2, "牛魔王", "芭蕉扇"));}//提供get方法获取bean对象public static Monster getMonster(String key) {return monsterHashMap.get(key);}
}
2.beans.xml
    <!--静态工厂获取bean--><!--不需要创建MyStaticFactory的对象,通过类加载就可以初始化工厂--><bean class="com.sxs.spring.bean.MyStaticFactory" id="staticFactory" factory-method="getMonster"><constructor-arg value="monster01"/></bean>
3.测试
    //静态工厂获取bean对象@Testpublic void staticFactory() {ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");Monster bean = ioc.getBean("staticFactory", Monster.class);System.out.println(bean);}

image-20240218103817182

2.实例工厂
1.MyInstanceFactory.java
package com.sxs.spring.bean;import java.util.HashMap;
import java.util.Map;/*** @author 孙显圣* @version 1.0*/
public class MyInstanceFactory {//map存储monster对象private Map<String, Monster> monsterMap;//普通代码块进行初始化{monsterMap = new HashMap<>();//放进去两个对象monsterMap.put("monster01", new Monster(1, "牛魔王", "芭蕉扇"));monsterMap.put("monster01", new Monster(2, "牛魔王", "芭蕉扇"));}//提供get方法获取对象public Monster getMonster(String key) {return monsterMap.get(key);}
}
2.beans.xml
    <!--实例工厂获取bean--><!--创建bean对象,初始化两个实例工厂--><bean class="com.sxs.spring.bean.MyInstanceFactory" id="instanceFactory1"/><bean class="com.sxs.spring.bean.MyInstanceFactory" id="instanceFactory2"/><!--从第一个bean工厂中获取bean对象--><bean class="com.sxs.spring.bean.MyInstanceFactory" factory-bean="instanceFactory1" id="instanceFactory_1" factory-method="getMonster"><constructor-arg value="monster01"/></bean><!--从第二个bean工厂中获取bean对象--><bean class="com.sxs.spring.bean.MyInstanceFactory" factory-bean="instanceFactory2" id="instanceFactory_2" factory-method="getMonster"><constructor-arg value="monster01"/></bean>
3.测试
    //通过实例工厂获取bean对象@Testpublic void instanceFactory() {ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");//从第一个实例工厂中获取bean对象Monster monster1 = ioc.getBean("instanceFactory_1", Monster.class);//从第二个实例工厂中获取bean对象Monster monster2 = ioc.getBean("instanceFactory_2", Monster.class);System.out.println(monster1 == monster2);}

image-20240218111113422

3.FactoryBean(重点)
1.MyFactoryBean.java
package com.sxs.spring.bean;import org.springframework.beans.factory.FactoryBean;import java.util.HashMap;
import java.util.Map;/*** @author 孙显圣* @version 1.0*/
public class MyFactoryBean implements FactoryBean<Monster> {//bean工厂中的key,要取的key是什么就设置成什么private String key;//bean工厂private Map<String, Monster> monsterMap;//初始化bean工厂{monsterMap = new HashMap<>();//放进去两个对象monsterMap.put("monster01", new Monster(1, "牛魔王", "芭蕉扇"));monsterMap.put("monster02", new Monster(2, "牛魔王", "芭蕉扇"));}//设置key的方法(用于属性注入)public void setKey(String key) {this.key = key;}//根据key返回要得到的bean对象@Overridepublic Monster getObject() throws Exception {return this.monsterMap.get(key);}//返回bean对象的类型@Overridepublic Class<?> getObjectType() {return Monster.class;}//返回是否是单例的@Overridepublic boolean isSingleton() {return true;}
}
2.beans.xml
    <!--通过FactoryBean来获取bean--><bean class="com.sxs.spring.bean.MyFactoryBean" id="myFactoryBean"><!--直接对要获取的key进行属性注入即可--><property name="key" value="monster01"/></bean>
3.测试
    //通过factorybean获取bean对象@Testpublic void factoryBean() {ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");Monster myFactoryBean = ioc.getBean("myFactoryBean", Monster.class);System.out.println(myFactoryBean);}

image-20240218140602472

2.bean配置信息重用

继承抽象bean
1.beans.xml
    <!--抽象bean对象,不能够被实例化只能够被继承,--><bean class="com.sxs.spring.bean.Monster" id="Abstractmonster" abstract="true"><property name="monsterId" value="200"/><property name="name" value="孙悟空"/><property name="skill" value="金箍棒"/></bean><!--继承抽象bean对象(也可以继承抽象的bean对象),则属性与其一样--><bean class="com.sxs.spring.bean.Monster" id="monster3" parent="Abstractmonster"/>
2.测试
    //bean配置信息重用@Testpublic void configureInformationReuse() {ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");Monster monster03 = ioc.getBean("monster3", Monster.class);System.out.println(monster03);}

image-20240218142301845

3.bean细节介绍

1.bean的创建顺序
1.depends-on关键字
    <!--默认情况下是car5先创建,但是如果有depends-on绑定了car6,则在获取容器的时候是car6先创建--><bean class="com.sxs.spring.bean.Car" id="car5" depends-on="car6"/><bean class="com.sxs.spring.bean.Car" id="car6"/>
2.问题引出

image-20240218143948657

2.bean对象的单例和多例
1.应用实例
    <!--单例模式,默认的,每次都读取配置文件反射创建对象,然后将其放到容器中的字段里--><bean class="com.sxs.spring.bean.Monster" id="monster4" scope="singleton"/><!--多例模式,每次getBean的时候才会创建新对象--><bean class="com.sxs.spring.bean.Monster" id="monster5" scope="prototype"/>
2.使用细节

image-20240218145932813

3.单例与多例对比
单例(非懒加载)
  1. 获取ioc容器
    1. 读取配置文件
    2. 反射创建bean对象
    3. 放到ioc容器的字段中
  2. getBean直接从字段中获取
单例(懒加载)
  1. 获取ioc容器
    1. 读取配置文件
  2. getBean的时候创建bean对象
  3. 将bean对象放到ioc容器的字段中
  4. 下次getBean还是从该字段中获取
多例
  1. 获取ioc容器
    1. 读取配置文件
  2. getBean的时候创建bean对象
  3. 下次getBean再穿件bean对象
3.bean的生命周期
1.基本介绍

image-20240218150756890

2.简化来说
  1. 反射创建bean对象
  2. 依赖注入
  3. 初始化bean
  4. getBean
  5. 销毁bean(容器关闭才会调用)
3.生命周期演示案例
1.House.java
package com.sxs.spring.bean;/*** @author 孙显圣* @version 1.0*/
public class House {private String name;public String getName() {return name;}public void setName(String name) {System.out.println("setName方法被调用!");this.name = name;}//自定义的初始化方法,名字可以任意public void init() {System.out.println("bean初始化");}//自定义的销毁方法密码,名字可以任意public void destory() {System.out.println("bean对象被销毁");}
}
2.beans.xml
    <!--bean生命周期案例--><bean class="com.sxs.spring.bean.House" id="house" init-method="init" destroy-method="destory"><property name="name" value="北京豪宅"/></bean>
3.测试
    //生命周期案例演示@Testpublic void lifeCycle() {//1.反射创建bean对象,2.依赖注入ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");//3.初始化bean//4.getBeanHouse house = ioc.getBean("house", House.class);//5.销毁bean((ConfigurableApplicationContext)ioc).close();}

image-20240218154121983

4.配置bean后置处理器(难点)

image-20240219090132082

1.MyBeanPostProcessor.java
package com.sxs.spring.bean;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;/*** @author 孙显圣* @version 1.0*/
//bean的后置处理器对象
public class MyBeanPostProcessor implements BeanPostProcessor {/*** 在bean的init方法前被调用* @param bean 传入的在ioc容器中创建的bean* @param beanName 传入的在ioc容器中配置的bean的id* @return* @throws BeansException*/@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {//判断是否bean对象是house,如果是,将名字改为豪宅if (bean instanceof House) {((House) bean).setName("豪宅");}System.out.println("postProcessBeforeInitialization被调用 " + bean + "beanName=" + beanName);return bean;}/*** 在bean的init方法后被调用* @param bean* @param beanName* @return* @throws BeansException*/@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("postProcessAfterInitialization被调用 " + bean + "beanName=" + beanName);return bean;}
}
2.beans02.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--配置bean的后置处理器,会作用于所有的bean--><bean class="com.sxs.spring.bean.MyBeanPostProcessor" id="beanPostProcessor"/><bean class="com.sxs.spring.bean.House" id="house" init-method="init" destroy-method="destory"><property name="name" value="北京豪宅"/></bean><bean class="com.sxs.spring.bean.House" id="house02" init-method="init" destroy-method="destory"><property name="name" value="香港豪宅"/></bean>
</beans>
3.测试
    //后置处理器演示@Testpublic void MyBeanPostProcessor() {ApplicationContext ioc = new ClassPathXmlApplicationContext("beans02.xml");House house = ioc.getBean("house", House.class);//关闭bean((ConfigurableApplicationContext)ioc).close();}

image-20240219090412968

5.通过属性文件配置bean
1.src下创建my.properties

如果是中文则自己将中文转换成unicode编码

name=jack
skill=\u5403\u996d
monsterId=111
2.beans03.xml
    <!--设置配置文件的位置--><context:property-placeholder location="classpath:my.properties"/><!--使用${name}来读取配置文件中的信息--><bean class="com.sxs.spring.bean.Monster" id="monster"><property name="name" value="${name}"/><property name="skill" value="${skill}"/><property name="monsterId" value="${monsterId}"/></bean>
3.测试
    //测试使用配置文件配置bean@Testpublic void profiles() {ApplicationContext ioc = new ClassPathXmlApplicationContext("beans03.xml");Monster monster = ioc.getBean("monster", Monster.class);System.out.println(monster);}

image-20240219093101698

6.自动装配bean
1.OrderDao.java
package com.sxs.spring.dao;/*** @author 孙显圣* @version 1.0*/
public class OrderDao {public void saveOrder() {System.out.println("保存订单");}
}
2.OrderService.java
package com.sxs.spring.service;import com.sxs.spring.dao.OrderDao;/*** @author 孙显圣* @version 1.0*/
public class OrderService {OrderDao orderDao;public OrderDao getOrderDao() {return orderDao;}public void setOrderDao(OrderDao orderDao) {this.orderDao = orderDao;}
}
3.OrderServlet.java
package com.sxs.spring.web;import com.sxs.spring.service.OrderService;/*** @author 孙显圣* @version 1.0*/
public class OrderServlet {OrderService orderService;public OrderService getOrderService() {return orderService;}public void setOrderService(OrderService orderService) {this.orderService = orderService;}
}
4.通过类型自动装配
    <!--根据类型自动装配,会查找容器中是否有类型与属性一致的bean对象,如果有则自动注入--><!--使用类型类自动装配的话,需要保证容器中只有一个同类型的bean对象--><bean class="com.sxs.spring.dao.OrderDao" id="orderDao"/><bean autowire="byType" class="com.sxs.spring.service.OrderService" id="orderService"/><bean autowire="byType" class="com.sxs.spring.web.OrderServlet" id="orderServlet"/>
5.通过名字自动装配
    <!--根据名字自动装配,会查找容器中是否有与属性名字相同的id--><bean class="com.sxs.spring.dao.OrderDao" id="orderDao"/><bean autowire="byName" class="com.sxs.spring.service.OrderService" id="orderService"/><bean autowire="byName" class="com.sxs.spring.web.OrderServlet" id="orderServlet"/>
6.测试
    //测试使用autowire自动装配@Testpublic void setBeanByAutowire() {ApplicationContext ioc = new ClassPathXmlApplicationContext("beans03.xml");OrderServlet bean = ioc.getBean(OrderServlet.class);//验证是否装配成功System.out.println(bean.getOrderService());System.out.println(bean.getOrderService().getOrderDao());}

image-20240219100908234

7.Spring El表达式(了解)

image-20240219101043961

image-20240219101619907


http://www.mrgr.cn/p/83456587

相关文章

rabbitMQ入门教程(商品抢购实战)

什么是MQ? 官方地址: https://www.rabbitmq.com/docsMQ有什么用? docker方式 安装: docker run \ -e RABBITMQ_DEFAULT_USER=yourame \ -e RABBITMQ_DEFAULT_PASS=123456 \ -v mq-plugins:/plugins \ --name mq \ --hostname mq \ -p 15672:15672 \ -p 5672:5672 \ --…

网络基础-基于TCP协议的Socket通讯

一、Socket通讯基于TCP协议流程图 UDP 的 Socket 编程相对简单些不在介绍。 二、 服务端程序启动 服务端程序要先跑起来&#xff0c;然后等待客户端的连接和数据。 服务端程序首先调用 socket() 函数&#xff0c;创建网络协议为 IPv4&#xff0c;以及传输协议为 TCP 的…

强大的数据分析计算软件:Stata 15 for Mac 激活版

Stata 15 for Mac是一款高级统计分析软件&#xff0c;具有强大的数据管理和数据提取工具。以下是其功能和特点的详细介绍&#xff1a; 软件下载&#xff1a;Stata 15 for Mac 激活版版下载 数据管理&#xff1a;Stata 15 for Mac支持多种数据库、数据格式和计算机语言&#xff…

《QT实用小工具·二十九》托盘图标控件

1、概述 源码放在文章末尾 托盘图标控件 可设置托盘图标对应所属主窗体。 可设置托盘图标。 可设置提示信息。 自带右键菜单。 下面是demo演示&#xff1a; 项目部分代码如下&#xff1a; #ifndef TRAYICON_H #define TRAYICON_H/*** 托盘图标控件* 1. 可设置托盘图标…

【详细的Kylin使用心得】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

1.Chinese Tiny LLM_ Pretraining a Chinese-Centric Large Language Model

文章目录 摘要一、背景二、预训练数据统计信息数据处理 模型架构 三、SFT四、Learning from Human Preferences五、评估数据集和指标训练过程和比较分析安全性评估中文硬指令理解与遵循评价 六、结论 https://arxiv.org/abs/2404.04167https://github.com/Chinese-Tiny-LLM/Chi…

数据湖/数据仓库

数据湖&#xff08;Data Lake&#xff09;和数据仓库&#xff08;Data Warehouse&#xff09;的主要区别在于它们的目的、存储的数据类型、数据处理方式、数据结构、数据安全性以及数据应用。以下是相关介绍&#xff1a; 目的。数据湖旨在作为一个集中的存储库&#xff0c;存储…

软件无线电安全之GNU Radio基础 -上

GNU Radio介绍 GNU Radio是一款开源的软件工具集&#xff0c;专注于软件定义无线电&#xff08;SDR&#xff09;系统的设计和实现。该工具集支持多种SDR硬件平台&#xff0c;包括USRP、HackRF One和RTL-SDR等。用户可以通过GNU Radio Companion构建流程图&#xff0c;使用不同…

常见分类算法

一、ChatGPT 在人工智能和机器学习领域&#xff0c;分类算法是一种监督学习技术&#xff0c;用来识别输入数据所属的类别。以下是一些常见的分类算法&#xff1a; 1. 决策树&#xff08;Decision Trees&#xff09;: 决策树通过创建一系列的问题或决策&#xff0c;来将数据…

【无标题】PHP-parse_str变量覆盖

[题目信息]&#xff1a; 题目名称题目难度PHP-parse_str变量覆盖1 [题目考点]&#xff1a; 变量覆盖指的是用我们自定义的参数值替换程序原有的变量值&#xff0c;一般变量覆盖漏洞需要结合程序的其它功能来实现完整的攻击。 经常导致变量覆盖漏洞场景有&#xff1a;$$&…

HarmonyOS-基础之状态数据共享

1、LocalStorage页面级UI状态存储,通常用于UIAbility内、页面间的状态共享(1) 先抛出一个疑问疑问:如何实现一个页面中所有组件的数据共享?解决:使用LocalStorage技术(2) 页面级状态内存存储只能在一个页面中的所有组件中共享 退出应用不存在(3) 相关APILocalStorage({name…

vue中使用aplayer插件做一个网页音乐播放器

我们在浏览网页的时候,时常会看到一些网页音乐播放器,本文以vue为例,使用aplayer插件,做一个简单的网页播放器。我们先看一下效果图效果图正常模式吸底模式当然还有迷你模式,就是能隐藏的都隐藏,这里不赘述,做相应配置就会出现对应效果。注意,吸底模式会出现上一曲下一…

视频拍摄知识+AIGC数据预处理

视角 参考链接&#xff1a;https://www.polarpro.com/blogs/polarpro/filmmaking-101-types-of-camera-shots-and-angles Low Angle Shot 低角度拍摄、horizontal Shot 平视、Dutch Angle Shot 荷兰角斜拍、High Angle Shot 高角度拍摄、Bird’s-eye / Aerial Shot 鸟瞰 / 航…

神通数据库测试环境调优过程

神通数据库测试环境调优过程背景 同事中午时反馈一个环境速度很慢. 我通过grafana简单看了下应用的 jvm信息还有hikari都很正常. 没有大量FullGC,也没有很多失败的提示. 感觉很奇怪. 当时已经过了中午,想着下午再看. 1点时想起来, 应用没问题, 可能是数据库的异常. 才发现自己…

golang 使用栈模拟计算器

思路&#xff1a; // Author sunwenbo // 2024/4/12 16:51 package mainimport ("errors""fmt""strconv" )// 使用数组来模拟一个栈的应用 type Stack struct {MaxTop int //表示栈最大可以存放数的个数Top int //表示栈底&#xff…

CTF中常见的四种python逆向

pyc是一种二进制文件,是由py文件经过编译后,生成的文件,是一种byte code,py文件变成pyc文件后,加载的速度有所提高,pyc 文件是 Python 编译过的字节码文件。它是 Python 程序在运行过程中由源代码(通常是 .py 文件)自动或手动编译产生的二进制文件。说在前面:什么是py…

【笔试训练】day5

今天的题&#xff0c;最后一题忘公式了&#xff0c;卡了一会推出来了 1、游游的you 思路&#xff1a; 看清题目意思就行&#xff0c;这里的相邻两个o可以重复算&#xff0c;也就是说&#xff0c;“ooo”算2分。 先算you的得分&#xff0c;再算oo 对了&#xff0c;不开long lo…

手动给docusaurus添加一个搜索

如果algolia不能自动配置的话,我教你手动给docusaurus添加一个搜索新版博客用docusaurus重构已经有些日子了,根据docusaurus的文档上也申请了Algolia,想一劳永逸的解决博客的搜索问题。但是流水有意,落花无情。 algolia总是不给我回复,我只能对着algolia的申请页面仰天长叹。…

python聊天室

python聊天室 文章目录 python聊天室chat_serverchat_client使用方式1.局域网聊天2.公网聊天 下面是一个简单的示例&#xff0c;包含了chat_client.py和chat_server.py的代码。 chat_server chat_server.py监听指定的端口&#xff0c;并接收来自客户端的消息&#xff0c;并将消…