Spring中的工厂模式详解及应用示例

1. Spring中的BeanFactory

BeanFactory是一个接口,表示它是一个工厂,负责生产和管理bean。在Spring中,BeanFactory是IOC容器的核心接口,定义了管理Bean的通用方法,如 getBeancontainsBean

BeanFactory与IOC容器

在这里插入图片描述

DefaultListableBeanFactory类图

在这里插入图片描述

BeanFactory只是个接口,并不是IOC容器的具体实现。Spring提供了多种实现,如 DefaultListableBeanFactoryXmlBeanFactoryApplicationContext等。

ApplicationContext

ApplicationContext是Spring框架中最常用的IoC容器,是BeanFactory的子接口,提供了更丰富的功能和更强的扩展性。

在这里插入图片描述

ApplicationContext的子类

  1. ClassPathXmlApplicationContext:基于XML配置文件的ApplicationContext实现类,可以加载类路径下的XML配置文件。
  2. FileSystemXmlApplicationContext:基于XML配置文件的ApplicationContext实现类,可以加载文件系统中的XML配置文件。
  3. AnnotationConfigApplicationContext:基于Java注解的ApplicationContext实现类,可以通过Java配置类来管理Bean实例。
  4. WebApplicationContext:适用于Web应用场景的ApplicationContext子接口,提供了更丰富的Web应用支持。

这些ApplicationContext子类都实现了ApplicationContext接口,提供了不同的功能和扩展性,可以根据具体的应用场景选择合适的ApplicationContext子类来管理Bean实例。

BeanFactory的使用示例

// User.java
public class User {
    private int id;
    private String name;
    private Friends friends;

    public User() { }

    public User(Friends friends) {
        this.friends = friends;
    }

    // getters and setters...
}

// Friends.java
public class Friends {
    private List<String> names;

    public Friends() { }

    public List<String> getNames() {
        return names;
    }

    public void setNames(List<String> names) {
        this.names = names;
    }
}

配置文件(bean.xml)

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.2.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task-4.2.xsd">
  
    <bean id="User" class="com.example.factory.User">
        <property name="friends" ref="UserFriends" />
    </bean>
    <bean id="UserFriends" class="com.example.factory.Friends">
        <property name="names">
            <list>
                <value>LiLi</value>
                <value>LuLu</value>
            </list>
        </property>
    </bean>
</beans>

测试类

public class SpringFactoryTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
        User user = ctx.getBean("User", User.class);

        List<String> names = user.getFriends().getNames();
        for (String name : names) {
            System.out.println("FriendName: " + name);
        }

        ctx.close();
    }
}

2. Spring中的FactoryBean

FactoryBean 是一个工厂Bean,相当于将工厂类放到了Spring中管理。当获取此Bean时返回的是该工厂生成的Bean。

FactoryBean通常用于创建比较复杂的bean。对于一般的bean,可以直接用XML配置;但如果一个bean的创建过程中涉及到很多其他bean和复杂的逻辑,用XML配置可能比较困难,这时可以考虑用FactoryBean。

FactoryBean接口

public interface FactoryBean<T> {
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

    @Nullable
    T getObject() throws Exception;

    @Nullable
    Class<?> getObjectType();

    default boolean isSingleton() {
        return true;
    }
}

代码示例

Car实体

public class Car {
    private String color;
    private String brand;
    private double price;

    // getters and setters...
}

CarFactoryBean

@Component("carFactoryBean")
public class CarFactoryBean implements FactoryBean<Car> {
    @Override
    public Car getObject() throws Exception {
        System.out.println("FactoryBean的getObject替换掉getBean...");
        return new Car();
    }

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

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

测试类

public class Test01 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

        Car car = context.getBean(Car.class);
        System.out.println(car);
    }
}

// 打印结果
// FactoryBean的getObject替换掉getBean...
// com.example.Car@4d14b6c2

在实例化Bean过程比较复杂的情况下,如果按照传统的方式,则需要在中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个 FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。

FactoryBean 与 BeanFactory 的区别

  • BeanFactory是一个大工厂,是IOC容器的根基,有繁琐的bean声明周期处理过程,可以生成各种各样的Bean。
    在这里插入图片描述

  • FactoryBean是一个小工厂,它自己本身也是一个Bean,但是可以生成其他Bean。用户可以通过实现该接口定制实例化Bean的逻辑。
    在这里插入图片描述

这种设计模式本质上是一个工厂方法模式,通过公共的工厂接口和不同的具体工厂,来获取对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬砖的小熊猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值