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

1、第一个案例

 1.1、Book.java

package com.atguigu.ioc;
import lombok.Data;
@Data
public class Book {
    private String bid;
    private String bname;
}

 1.2、Book2.java

package com.atguigu.ioc;
import lombok.Data;
@Data
public class Book2 extends Book {
    private String coffee;

    @Override
    public String toString() {
        return "Book2{" +super.toString()+
                "coffee='" + coffee + '\'' +
                '}';
    }
}

1.3、applicationContext.html




        

        
        
                
                
        

        
        
        

1.4、BookFactoryBean.java

package com.atguigu.ioc;
import org.springframework.beans.factory.FactoryBean;
public class BookFactoryBean implements FactoryBean {
    @Override
    public Book getObject() throws Exception {
        Book2 book2 = new Book2();
        book2.setBid("b002");
        book2.setBname("钢铁是怎么炼成的");
        book2.setCoffee("酱香拿铁");
        return book2;
    }
    @Override
    public Class getObjectType() {
        return Book.class;
    }
}

1.5、Test

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

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的配置文件中,我们可以这样配置:


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

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

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

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

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

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

+---------------------------------------------------------------------+
|                                Client                               |
+---------------------------------------------------------------------+
         |                     |
         | 通知IOC容器加载配置文件 |
         |---------------------|
         |                     |
+---------------------------------------------------------------------+
|                             IOC容器                                |
+---------------------------------------------------------------------+
         |                     |
         | 创建FactoryBean实例  |
         |---------------------|
         |                     |
         | 将FactoryBean实例注册到IOC容器中 |
         |---------------------|
         |                     |
+---------------------------------------------------------------------+
|                          FactoryBean                               |
+---------------------------------------------------------------------+
         |                     |
         | 从配置文件中获取Bean定义 |
         |---------------------|
         |                     |
         | 创建Bean实例         |
         |---------------------|
         |                     |
         | 返回Bean实例         |
         |---------------------|
         |                     |
+---------------------------------------------------------------------+
|                                Client                               |
+---------------------------------------------------------------------+
         |                     |
         | 获取FactoryBean实例 |
         |---------------------|
         |                     |
         | 调用FactoryBean.getObject()方法获取Bean实例 |
         |---------------------|
         |                     |
         | 使用Bean实例         |
         |---------------------|
         |                     |
 

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

Spring-IOC-FactoryBean机制(难点且重点)_第1张图片

2、第二个案例

 2.1、ApplicationContext.xml



        
        
        
                
                
        

2.2、HappyFactoryBean.java

package com.atguigu.ioc;
import org.springframework.beans.factory.FactoryBean;
//实现FactoryBean接口时需要指定泛型
//泛型类型就是当前工厂要生产的对象的类型
public class HappyFactoryBean implements FactoryBean {
    private String machineName;

    public String getMachineName() {
        return machineName;
    }

    public void setMachineName(String machineName) {
        this.machineName = machineName;
    }

    @Override
    public HappyMachine getObject() throws Exception {
        //方法内部模拟创建、设置一个对象的复杂过程
        HappyMachine happyMachine = new HappyMachine();
        happyMachine.setMachineName(this.machineName);
        return happyMachine;
    }
    @Override
    public Class getObjectType() {
        //返回要生产的对象的类型
        return HappyMachine.class;
    }
}

class HappyMachine {
    private String machineName;

    public String getMachineName() {
        return machineName;
    }

    public void setMachineName(String machineName) {
        this.machineName = machineName;
    }
}

2.3、Test

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

你可能感兴趣的:(#,Spring,Framework,spring,java,后端,FactoryBean,getBean,ClassPath,Xml)