基于XML配置bean(二)

server/2025/3/26 12:04:59/

文章目录

    • 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.ppmy.cn/server/721.html

相关文章

IO多路转接之epoll

目录 1. 简单认识下 epoll 相关接口 2. epoll 原理 2.1. 前置性认识 2.2. epoll 底层原理 2.2.1. 红黑树 2.2.2. 就绪队列 2.2.3. 回调机制 2.3. 红黑树和就绪队列 2.3.1. eventpoll 结构 2.3.2. epitem 结构 2.4. 总结 3. epoll 实例 3.1. epoll_event &&am…

python 文件输入输出

python 文件输入输出 一、输入输出1. 输出格式美化2. 旧式字符串格式化3. 读取键盘输入4. 读和写文件5. 文件对象的方法6. pickle 模块 二、文件操作1. File(文件) 方法2. mode 参数有&#xff1a;3. file 对象 三、 OS 文件操作1. OS 文件/目录方法 四、代码概览&#xff08;输…

Vue源码解读学习

Vue源码 观察者模式 & 发布订阅 观察者模式&#xff1a;中心一对多 系统单点间的灵活和拓展&#xff08;广播的方式&#xff09; 发布订阅&#xff1a;将注册列表遍历发布给订阅者 initInject initState initProvide他们挂载顺序为什么这样设计&#xff1f; initstate…

NAND数据恢复的方案

NAND Flash是固态硬盘&#xff08;SSD&#xff09;的核心数据存储。然而&#xff0c;NAND Flash因其物理特性和工作原理&#xff0c;存在一定的内在脆弱性&#xff0c;尤其是在数据存储的长期可靠性方面。 比特错误是指在读取NAND Flash时&#xff0c;原本存储的二进制位&#…

git 命令大全(常用)

Git 是一个功能强大的版本控制系统&#xff0c;它提供了大量的命令来执行各种版本控制操作。除了之前提到的添加、查看和修改用户名和邮箱地址的命令外&#xff0c;Git 还有许多其他命令。以下是一些常用的 Git 命令的概述&#xff1a; 接下来☀️☀️公&#x1f437;&#x1…

大唐杯题目

5G NR 系统中&#xff0c;UE 收到 RRCSetup后&#xff0c;可能会有以下哪些过程 A.进入 RRC CONNECTED&#xff0c;停止小区重选: B.如果 NAS 层提供了多个S-NSSAI&#xff0c;则写入 s-nssai-List; C.发送 RRCSetupComplete. D.UE 启动 T300&#xff0c;将 RRCSetupReguest 消…

详解Qt添加外部库

在Qt项目中添加外部库是一项常见任务&#xff0c;无论是静态库还是动态库都需要正确的配置才能让项目顺利编译链接。以下是详细步骤和不同场景下的配置方法&#xff1a; 方法一&#xff1a;手动编辑.pro文件 添加头文件路径&#xff1a; 在Qt项目中的.pro文件中使用INCLUDEPAT…

使用Flask和Flask-JWT-Extended保护API免受跨站请求攻击

在本文中&#xff0c;我们将探讨如何使用Flask和Flask-JWT-Extended库来保护您的API免受跨站请求攻击&#xff08;CSRF&#xff09;。我们将首先简要介绍CSRF攻击的概念&#xff0c;然后详细说明如何使用Flask-JWT-Extended库来保护您的API。 什么是跨站请求攻击&#xff08;C…