基于XML配置bean(二)

news2024/11/16 16:44:47

文章目录

    • 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对象
    @Test
    public 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对象
    @Test
    public 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对象
    @Override
    public Monster getObject() throws Exception {
        return this.monsterMap.get(key);
    }

    //返回bean对象的类型
    @Override
    public Class<?> getObjectType() {
        return Monster.class;
    }

    //返回是否是单例的
    @Override
    public 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对象
    @Test
    public 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配置信息重用
    @Test
    public 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.测试
    //生命周期案例演示
    @Test
    public void lifeCycle() {
        //1.反射创建bean对象,2.依赖注入
        ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");
        //3.初始化bean
        //4.getBean
        House 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
     */
    @Override
    public 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
     */
    @Override
    public 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.测试
    //后置处理器演示
    @Test
    public 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
    @Test
    public 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自动装配
    @Test
    public 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.coloradmin.cn/o/1605687.html

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

相关文章

《系统分析与设计》实验-----在线书店系统 需求规格说明书 哈尔滨理工大学PLUS完善版

文章目录 需求规格说明书1&#xff0e;引言1.1编写目的1.2项目背景1.3定义1.4参考资料 2&#xff0e;任务概述2.1目标2.2运行环境2.3条件与限制 3&#xff0e;数据描述3.1静态数据3.2动态数据3.3数据库介绍3.4数据词典3.5数据采集 4&#xff0e;功能需求4.1功能划分4.2功能描述…

transformer架构详细详解

一、transformer的贡献 transformer架构的贡献&#xff1a;该架构只使用自注意力机制&#xff0c;没有使用RNN或卷积网络。且可以实现并行计算&#xff0c;加快模型训练速度。 &#xff08;将所有的循环层全部换成&#xff1a;multi-headed self-attention&#xff09; 二、t…

Day13-Python基础学习之数据分析案例

数据分析案例 data_define.py # 数据定义的类 class Record:def __init__(self, date, order_id, money, province):self.date dateself.order_id order_idself.money moneyself.province province ​def __str__(self):return f"{self.date}, {self.order_id}, {se…

OpenGL:图元

OpenGL的图元 点 GL_POINTS: 将顶点绘制成单个的点 线 GL_LINES:将顶点用于创建线段,2个点成为一条单独的线段。如果顶点个数是奇数,则忽略最后一个。 顶点:v0, v1, v2, v3, … , vn,线段:v0-v1, v2-v3, v4-v5, … , vn-1 - vn GL_LINE_STRIP:将顶点用于创建线段,…

驱动创新成长,智能费控助力国央企财务数智化升级

如果说中小企业是我国国民经济的毛细血管&#xff0c;那么国央企就是承载着我国市场发展的主动脉&#xff0c;是国民经济的重要支柱。今年以来&#xff0c;面对复杂严峻的国内外发展环境&#xff0c;国央企锚定目标&#xff0c;深入开展提质增效专项行动&#xff0c;打出深化改…

基础算法之二分算法

前言 本次博客&#xff0c;将要介绍二分算法的基本原理以及如何使用&#xff0c;深入浅出 二分可以针对整型以及浮点型接下来对其讲解希望对小白有所帮助吧 整型的二分法 一般要在一个数组中猜出一个数是否存在我们可以遍历一遍整个数组&#xff0c;判断是否存在&#xff0…

python学习笔记B-07:序列结构之列表--列表的常用函数和方法

以xx_函数名(列表名)的形式出现的是函数&#xff1b;以xx_列表名.xx_方法名的形式出现的是方法。 列表常用函数如下&#xff1a; len()&#xff1a;计算列表元素数量 max()&#xff1a;获取列表元素最大值 min():获取列表元素最小值 sum():计算列表中各元素之和 列表常用方法如…

wps导出pdf文献引用不能跳转解决办法

问题描述 本科论文参考文献使用wps设置交叉引用&#xff0c;但导出pdf后无法跳转引用 尝试 用office word打开文件word版跳转没有问题&#xff0c; 另存为pdf或导出pdf。 但是pdf版跳转完全错误。 16跳到14.但是总体而言都是跳到包含该序号的页 要求不高的话也可以&#x…

【WebSocket连接异常】前端使用WebSocket子协议传递token时,Java后端的正确打开方式!!!

文章目录 1. 背景2. 代码实现和异常发现3. 解决异常3.1 从 URL入手3.2 从 WebSocket子协议的使用方式入手&#xff08;真正原因&#xff09; 4. 总结&#xff08;仍然存在的问题&#xff09; 前言&#xff1a; 本篇文章记录的是使用WebSocket进行双向通信时踩过的坑&#xff0c…

链表(C语言)

前言&#xff1a;前面几篇文章我们详细介绍了顺序表&#xff0c;以及基于顺序表来实现的通讯录。今天我们连介绍一下链表的下一个结构链表。那么链表和顺序表究竟有什么区别呢&#xff1f;他们两个的优缺点分别是什么。今天这篇文章就带大家了解一下链表。 目录 一.链表的概念…

新质生产力走红背后,华为云的基本盘和自我修养

文 | 智能相对论 作者 | 沈浪 今年全国两会期间走红的“新质生产力”正成为中国产业转型升级的关键方向。政府工作报告更是把“大力推进现代化产业体系建设&#xff0c;加快发展新质生产力”放在今年政府工作任务的重要位置。 何为新质生产力&#xff1f;简单来说&#xff0…

C++奇迹之旅:探索C++拷贝构造函数

文章目录 &#x1f4dd;拷贝构造函数&#x1f320; 概念&#x1f309;特征 &#x1f320;浅拷贝(值拷贝)&#x1f309;深拷贝 &#x1f320;拷贝构造函数典型调用场景&#x1f320;应用时效率的思考&#x1f6a9;总结 &#x1f4dd;拷贝构造函数 &#x1f320; 概念 在现实生…

web轮播图

思路&#xff1a; 例如&#xff1a;有5张轮播的图片&#xff0c;每张图片的宽度为1024px、高度为512px.那么轮播的窗口大小就应该为一张图片的尺寸&#xff0c;即为&#xff1a;1024512。之后将这5张图片0px水平相接组成一张宽度为&#xff1a;5120px,高度依然为&#xff1a;5…

SpringBoot - Logback 打印第三方 Jar 日志解决方案

问题描述 最近碰到一个很苦恼的问题&#xff0c;就是第三方的 Jar 在自己项目里日志可以正常输出&#xff0c;但是一旦被引用到其他项目里&#xff0c;就日志死活打不出来…… 解决方案 这是原来的配置 - logback.xml <?xml version"1.0" encoding"UTF-8…

5G-A有何能耐?5G-A三载波聚合技术介绍

2024年被称作5G-A元年。5G-A作为5G下一阶段的演进技术&#xff0c;到底有何能耐呢&#xff1f; 三载波聚合&#xff08;3CC&#xff09;被认为是首个大规模商用的5G-A技术&#xff0c;将带来手机网速的大幅提升。 █ 什么是3CC 3CC&#xff0c;全称叫3 Component Carriers…

python聊天室

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

一个 .net 8 + Azure 登录 + Ant Design Blazor 的基本后台框架

一个 .net 8 Azure 登录 Ant Design Blazor 的基本后台框架 主界面使用了 Ant Design Blazor 项目模板搭建 后台技术是 .net 8 Blazor run at server 模式 登录方式使用 Azure 实现了菜单导航和路由 此外实现了读取和修改本地Json文件的功能&#xff0c;不是必须的&#x…

【Python】OPC UA模拟服务器实现

目录 服务器模拟1. 环境准备2. 服务器设置3. 服务器初始化4. 节点操作5. 读取CSV文件6. 运行服务器 查看服务器客户端总结 在工业自动化和物联网&#xff08;IoT&#xff09;领域&#xff0c;OPC UA&#xff08;开放平台通信统一架构&#xff09;已经成为一种广泛采用的数据交换…

Leo赠书活动-24期 【三大层次学习企业架构框架TOGAF】文末送书

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 赠书活动专栏 ✨特色专栏&#xff1a;…

鸿蒙开发岗突增!它和前端开发到底有哪些区别和联系?

2024年1 月 18 日&#xff0c;鸿蒙 Next 预览版面向开发者正式开放申请。至此&#xff0c;鸿蒙原生应用版图已成型&#xff0c;这个中国自主研发的操作系统&#xff0c;正式走上了独立之路。 有许多的公司都陆续地加入了鸿蒙原生应用开发的队列&#xff0c;从年初宣布的200个应…