首页 > 其他分享 >Spring的FactoryBean接口的作用

Spring的FactoryBean接口的作用

时间:2023-12-10 11:55:53浏览次数:33  
标签:Spring 接口 bean FactoryBean Car public car

FactoryBean是Spring提供的一个接口,通过实现这个接口可以定制实例化bean。

FactoryBean 接口对于 Spring 框架来说占有重要的地位,Spring 自身就提供了 70 多个FactoryBean 的实现。它们隐藏了实例化一些复杂 bean 的细节,给上层应用带来了便利。

Spring为什么使用FactoryBean

一般情况下,Spring 通过反射机制利用 bean 的 class 属性指定实现类来实例化 bean。

在某些情况下,实例化 bean 过程比较复杂,如果按照传统的方式,则需要提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。

Spring 为此提供了一个 org.Springframework.bean.factory.FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 bean 的逻辑。

FactoryBean接口

从Spring3.0开始,FactoryBean 开始支持泛型,即接口声明改为 FactoryBean< T> 的形式:

public interface FactoryBean<T> {

    T getObject() throws Exception;

    Class<?> getObjectType();

    default boolean isSingleton() {
        return true;
    }
}
  • T getObject():返回由 FactoryBean 创建的 bean 实例,如果 isSingleton()返回 true,则该实例会放到 Spring 容器中单实例缓存池中。
  • boolean isSingleton():返回由 FactoryBean 创建的 bean 实例的作用域是 singleton 还是prototype。
  • Class getObjectType():返回 FactoryBean 创建的 bean 类型。

当配置文件中< bean>的 class 属性配置的实现类是 FactoryBean 时,通过 getBean()方法返回的不是 FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的对象。相当于FactoryBean#getObject()代理了 getBean()方法。

FactoryBean案例演示

定义POJO

import lombok.Data;

@Data
public class Car {

    private String color;

    private String maxSpeed;

    private String price;

    @Override
    public String toString() {
        return "Car{" +
            "color='" + color + '\'' +
            ", maxSpeed='" + maxSpeed + '\'' +
            ", price='" + price + '\'' +
            '}';
    }
}

实现FactoryBean

import org.springframework.beans.factory.FactoryBean;

/**
 * @description: 通过逗号分隔符的方式一次性为Car的所有属性指定配置值。
 */
public class CarFactoryBean implements FactoryBean<Car> {

    private String carInfo;

    @Override
    public Car getObject() throws Exception {
        Car car = new Car();
        String[] infoArr = carInfo.split(",");
        car.setColor(infoArr[0]);
        car.setPrice(infoArr[1]);
        car.setMaxSpeed(infoArr[2]);
        return car;
    }

    @Override
    public Class<Car> getObjectType() {
        return Car.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }

    /**
     * 功能描述:给carInfo属性注入指定值。(xml方式注入值)
     *
     * @param carInfo 值
     */
    public void setCarInfo(String carInfo) {
        this.carInfo = carInfo;
    }
}

配置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 id = "car" class="com.harvey.CarFactoryBean" >
        <property name="carInfo" value="红色,100,200"/>
    </bean>

</beans>

测试类

import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class FactoryBeanTest {

    @Test
    public void test () {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("com/cms/factorybean/car.xml");

        // 1.当调用 getBean("car")时,Spring 通过反射机制发现 CarFactoryBean 实现了 FactoryBean的接口,这时 Spring 容器就调用接口方法 CarFactoryBean#getObject()方法返回。
        Car car = (Car) context.getBean("car");
        // 输出:Car{color='红色', maxSpeed='200', price='100'}
        System.out.println(car);
        
        //2.如果希望获取CarFactoryBean 的实例,则需要在使用 getBean(beanName)方法时在 beanName 前显示的加上"&”前缀,例如 getBean("&car")。
        CarFactoryBean carFactoryBean = (CarFactoryBean)context.getBean("&car");
        // 输出:com.cms.factorybean.CarFactoryBean@7748410a
        System.out.println(carFactoryBean.toString());
    }
}

源码分析

 

标签:Spring,接口,bean,FactoryBean,Car,public,car
From: https://www.cnblogs.com/xfeiyun/p/17892265.html

相关文章

  • 3分钟快速上手springBoot全局异常处理
    统一异常处理前后端都是有个统一的格式返回如Result,中有code,message,data。而若service、controller抛出异常则会导致不是统一格式的返回而是以下格式:而导致前端接受不到约定好的code,message最终导致内部发生异常而用户却得不到最基本的反馈。可以通过java中统一异常处理的......
  • Spring的事件发布机制
    观察者模式的事件思想观察者模式作为对象间一对多依赖关系的实现。在观察者模式中,被观察者相当于事件中的时间发布者,而观察者相当于事件中的监听者。因此可以说:观察者模式就是事件驱动机制的一种体现。事件驱动一个常见的形式就是发布-订阅模式,在跨进程的通信间,我们常常使......
  • Redis和Springboot在Windows上面设置开机启动的方法
    Redis和Springboot在Windows上面设置开机启动的方法背景同事遇到一个问题Windows晚上自动更新服务然后第二天Springboot开发的程序没有启动起来.所以基于此想创建一个开机启动的服务设置很早之前自己研究过Winsw等工具但是感觉对springboot比较复杂的应用使用起来比......
  • ApplicationContextInitializer在Spring容器执行refresh之前执行
    ApplicationContextInitializer用于在刷新Spring容器之前的回调接口。ApplicationContextInitializer是Spring框架原有的概念,这个类的主要目的就是在ConfigurableApplicationContext类型(或者子类型)的ApplicationContext进行刷新refresh之前,允许我们对ConfigurableApplicatio......
  • 【SpringBootWeb入门-8】分层解耦-三层架构
    1、架构前言在讲解三层架构之前,我们先来看一段Controller代码段,代码如下:packagecom.hiker.controller;importcom.hiker.pojo.Emp;importcom.hiker.pojo.Result;importcom.hiker.utils.XmlParserUtils;importorg.springframework.web.bind.annotation.RequestMapping......
  • 京东App秒杀抢购流程接口分析(基于pypp技术)
    App数据抓包必需工具必需工具:小米手机,Charles,HttpCanary从2022年2月后,京东只限于从app发起抢购,所以,网上的很多工具已经无效了。只能分析app端的底层协议和流程。github地址:https://github.com/geeeeeeeek/jd_mt通过抓包可以发现,整个抢购流程分为七个步骤,如下:第一步是genToke......
  • springboot023学生宿舍管理系统的设计与开发-计算机毕业设计源码+LW文档
    学生宿舍管理系统的设计与开发摘要:随着信息技术的日益发展深入到社会的各个角落,学生宿舍管理也不例外。为了适应现代社会人们高度强烈的时间观念,学生宿舍管理系统为学校的教学管理带来了极大的方便。我所开发的系统采用JAVA语言和IntelliJ软件作为开发工具,利用HTML、CSS,SpringM......
  • nginx代理knife4j接口文档
    nginx配置(11215是服务的端口信息)location~*^(/v2|/swagger-resources|/swagger-ui|/swagger-ui/index.html|/webjars/|/favicon.ico/|/doc.html){ proxy_redirectoff; proxy_set_headerX-Real-IP$remote_addr; proxy_set_headerX-Forwarded-For$proxy_add_x_fo......
  • SpringBoot项目之Kaptcha实现登录验证码
    一、pom.xml加载该依赖<dependency><groupId>com.github.axet</groupId><artifactId>kaptcha</artifactId><version>0.0.9</version></dependency>二、RestFul风格,在这里写一个调用验证码的接口:@GetMapping(value="/captcha.......
  • Spring Web应用的启动流程分析
    在ServletAPI中有一个ServletContextListener接口,它能够监听ServletContext对象的生命周期,实际上就是监听Web应用的生命周期。当Servlet容器启动或终止Web应用时,会触发ServletContextEvent事件,该事件由ServletContextListener来处理。在ServletContextListener接口中定义了处......