• Spring-IOC-FactoryBean机制(难点且重点)


    1、第一个案例

     1.1、Book.java

    1. package com.atguigu.ioc;
    2. import lombok.Data;
    3. @Data
    4. public class Book {
    5. private String bid;
    6. private String bname;
    7. }

     1.2、Book2.java

    1. package com.atguigu.ioc;
    2. import lombok.Data;
    3. @Data
    4. public class Book2 extends Book {
    5. private String coffee;
    6. @Override
    7. public String toString() {
    8. return "Book2{" +super.toString()+
    9. "coffee='" + coffee + '\'' +
    10. '}';
    11. }
    12. }

    1.3、applicationContext.html

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="p01" class="com.atguigu.ioc.Person">bean>
    6. <bean id="bo1" class="com.atguigu.ioc.Book">
    7. <property name="bid" value="boo1"/>
    8. <property name="bname" value="Java从入门到放弃"/>
    9. bean>
    10. <bean id="b02" class="com.atguigu.ioc.BookFactoryBean">bean>
    11. beans>

    1.4、BookFactoryBean.java

    1. package com.atguigu.ioc;
    2. import org.springframework.beans.factory.FactoryBean;
    3. public class BookFactoryBean implements FactoryBean {
    4. @Override
    5. public Book getObject() throws Exception {
    6. Book2 book2 = new Book2();
    7. book2.setBid("b002");
    8. book2.setBname("钢铁是怎么炼成的");
    9. book2.setCoffee("酱香拿铁");
    10. return book2;
    11. }
    12. @Override
    13. public Class getObjectType() {
    14. return Book.class;
    15. }
    16. }

    1.5、Test

    1. @Test
    2. public void test11() {
    3. BeanFactory beanFactory = new ClassPathXmlApplicationContext("applicationContext.xml");
    4. System.out.println(beanFactory.getBean("b02"));
    5. //Book2{Book(bid=b002, bname=钢铁是怎么炼成的)coffee='酱香拿铁'}
    6. }

    Spring-IOC(Inversion of Control,控制反转)是Spring框架的核心功能之一,它通过将对象的创建和依赖关系管理交给容器来实现松耦合的设计。而Spring中IOC容器提供的FactoryBean机制则是一种创建和管理Bean的途径。它允许开发者在获取Bean时,先获取一个特定的工厂Bean,然后再由工厂Bean来生成需要的最终Bean对象。

    使用FactoryBean机制,主要有以下几个步骤:

    1.编写自定义的FactoryBean实现类,该实现类需要实现Spring提供的 FactoryBean接口 ,重写其中的getObject()方法和getObjectType()方法。

    2.在Spring容器的配置文件中,将自定义的 FactoryBean 注册 到容器中。

    3.在需要使用Bean对象的地方,通过容器获取自定义的FactoryBean对象。

    4.通过调用自定义FactoryBean的getObject()方法,返回需要的Bean对象。

    举个例子,假设我们有一个自定义的DataSourceFactoryBean,用于创建数据源DataSource对象。那么,在Spring的配置文件中,我们可以这样配置:

    <bean id="dataSource" class="com.example.DataSourceFactoryBean"/>
    

    在程序中,如果我们需要获取DataSource对象,可以这样:

    1. DataSourceFactoryBean dataSourceFactoryBean = (DataSourceFactoryBean) applicationContext.getBean("dataSource");
    2. DataSource dataSource = dataSourceFactoryBean.getObject();

    FactoryBean机制在一些场景中非常有用,例如:

    1.在创建Bean时需要进行一些定制化操作,比如为Bean对象设置默认属性、开启/关闭某些特性等。

    2.当需要实现延迟加载、缓存等特殊需求时,FactoryBean机制可以更好地实现。

    总之,FactoryBean机制是Spring框架中一个非常重要的组成部分,它提供了一种更加灵活的Bean管理方式,适用于各种不同的场景。

    1. +---------------------------------------------------------------------+
    2. | Client |
    3. +---------------------------------------------------------------------+
    4. | |
    5. | 通知IOC容器加载配置文件 |
    6. |---------------------|
    7. | |
    8. +---------------------------------------------------------------------+
    9. | IOC容器 |
    10. +---------------------------------------------------------------------+
    11. | |
    12. | 创建FactoryBean实例 |
    13. |---------------------|
    14. | |
    15. | 将FactoryBean实例注册到IOC容器中 |
    16. |---------------------|
    17. | |
    18. +---------------------------------------------------------------------+
    19. | FactoryBean |
    20. +---------------------------------------------------------------------+
    21. | |
    22. | 从配置文件中获取Bean定义 |
    23. |---------------------|
    24. | |
    25. | 创建Bean实例 |
    26. |---------------------|
    27. | |
    28. | 返回Bean实例 |
    29. |---------------------|
    30. | |
    31. +---------------------------------------------------------------------+
    32. | Client |
    33. +---------------------------------------------------------------------+
    34. | |
    35. | 获取FactoryBean实例 |
    36. |---------------------|
    37. | |
    38. | 调用FactoryBean.getObject()方法获取Bean实例 |
    39. |---------------------|
    40. | |
    41. | 使用Bean实例 |
    42. |---------------------|
    43. | |

    在这个流程中,客户端通过IOC容器获取自定义的FactoryBean实例,然后调用其getObject()方法获取最终的Bean实例。而在IOC容器中,FactoryBean实例和最终的Bean实例都被注册到容器中,由容器统一管理和维护,使得整个过程变得更加灵活和便于扩展。

    2、第二个案例

     2.1、ApplicationContext.xml

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="happyMachine" class="com.atguigu.ioc.HappyFactoryBean">
    6. <property name="machineName" value="iceCreamMachine"/>
    7. bean>
    8. beans>

    2.2、HappyFactoryBean.java

    1. package com.atguigu.ioc;
    2. import org.springframework.beans.factory.FactoryBean;
    3. //实现FactoryBean接口时需要指定泛型
    4. //泛型类型就是当前工厂要生产的对象的类型
    5. public class HappyFactoryBean implements FactoryBean {
    6. private String machineName;
    7. public String getMachineName() {
    8. return machineName;
    9. }
    10. public void setMachineName(String machineName) {
    11. this.machineName = machineName;
    12. }
    13. @Override
    14. public HappyMachine getObject() throws Exception {
    15. //方法内部模拟创建、设置一个对象的复杂过程
    16. HappyMachine happyMachine = new HappyMachine();
    17. happyMachine.setMachineName(this.machineName);
    18. return happyMachine;
    19. }
    20. @Override
    21. public Class getObjectType() {
    22. //返回要生产的对象的类型
    23. return HappyMachine.class;
    24. }
    25. }
    26. class HappyMachine {
    27. private String machineName;
    28. public String getMachineName() {
    29. return machineName;
    30. }
    31. public void setMachineName(String machineName) {
    32. this.machineName = machineName;
    33. }
    34. }

    2.3、Test

    1. @Test
    2. public void testExperiment() {
    3. ApplicationContext iocContainer = new ClassPathXmlApplicationContext("applicationContext.xml");
    4. //注意:直接根据声明FactoryBean的id,获取的是getObject方法返回的对象
    5. HappyMachine happyMachine = iocContainer.getBean("happyMachine", HappyMachine.class);
    6. System.out.println("happyMachine = " + happyMachine);
    7. //如果想要获取FactoryBean对象,直接在id前添加&符号即可! 这是一种固定的约束
    8. Object bean = iocContainer.getBean("&happyMachine");
    9. System.out.println("bean = " + bean);
    10. }
    11. //happyMachine = com.atguigu.ioc.HappyMachine@4d02f94e
    12. //bean = com.atguigu.ioc.HappyFactoryBean@2b48a640

  • 相关阅读:
    MyBatis-plus:查询操作、分页查询
    图像处理黑科技——弯曲矫正、去摩尔纹、切边增强、PS检测
    从软件工程的角度比较Swift、Go和Julia,我有了这些发现
    Agile Management 2
    React18源码: Fiber树中的优先级与帧栈模型
    ndoe.js、npm相关笔记
    jq弹窗拖动改变宽高
    《神经网络与深度学习》算法伪代码汇总
    C++ 并发编程实战 第十一章 多线程应用的测试和除错
    “灯塔工厂”的中国路径:智造从点到面铺开
  • 原文地址:https://blog.csdn.net/m0_65152767/article/details/134517367