1 FactoryBean接口的使用

一般情况下,Spring通过反射机制利用bean的class属性指定实现类来实例化bean。在某些情况下,实例化bean过程比较复杂,如果按照传统的方式,则需要在标签中提供大量的配置信息,配置方式的灵活性是受限的。为此,spring可以通过实现FactoryBean的接口来定制实例化bean的逻辑。

1 创建User对象#

package com.gientech.factoryBean;



public class User {

    private String id;

    private String userName;

    private String email;

    private String password;

    public User(String userName) {
        this.userName = userName;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

2 创建MyFactoryBean#

package com.gientech.factoryBean;


import org.springframework.beans.factory.FactoryBean;

public class MyFactoryBean implements FactoryBean<User> {
    @Override
    public User getObject() throws Exception {
        return new User("wangmazi");
    }

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

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

3 修改xml配置文件#

<bean id="userFactory" class="com.gientech.factoryBean.MyFactoryBean">
    <property name="userInfo" value="1,zhangsan,123456@163.com,123qaz"></property>
</bean>

4 测试code和截图#

  • 4.1 场景一:获取实现了BeanFactory接口类的对象#

ApplicationContext ac = new ClassPathXmlApplicationContext("factoryBean.xml");
// 获取实现了BeanFactory接口类的对象
MyFactoryBean factoryBean = (MyFactoryBean) ac.getBean("&userFactory");
System.out.println(factoryBean);

此时factoryBean 由Spring管理,且存储于一级缓存中,如下图所示。
FactoryBean

  • 4.2 场景二:factoryBean#getObject的返回对象存储于factoryBeanObjectCache缓存中#

测试code

ApplicationContext ac = new ClassPathXmlApplicationContext("factoryBean.xml");
// 获取实现了BeanFactory接口类的对象
MyFactoryBean factoryBean = (MyFactoryBean) ac.getBean("&userFactory");
System.out.println(factoryBean);

User bean2 = (User) ac.getBean("userFactory");
System.out.println(bean2.getUserName()+ " ---- " + bean2.getEmail());

bean2是通过getObjectForBeanInstance(sharedInstance, name, beanName, null); 方法创建,此时,factoryBean 由Spring管理,且存储于一级缓存中,bean2存储于factoryBeanObjectCache 缓存中。如下图所示:
factoryBeanObjectCache

  • 4.3 场景三:factoryBean#getObject的返回对象为单例时,只有一个对象存储于factoryBeanObjectCache缓存中#

当User.isSingleton() 返回true时, bean2 会存入factoryBeanObjectCache缓存中,bean3 会从缓存中获取,代码和截图所示。

ApplicationContext ac = new ClassPathXmlApplicationContext("factoryBean.xml");
// 获取实现了BeanFactory接口类的对象
MyFactoryBean factoryBean = (MyFactoryBean) ac.getBean("&userFactory");
System.out.println(factoryBean);

User bean2 = (User) ac.getBean("userFactory");
System.out.println(bean2.getUserName()+ " ---- " + bean2.getEmail());

User bean3 = (User) ac.getBean("userFactory");
System.out.println(bean3.getUserName()+ " ---- " + bean3.getEmail());

factoryBeanObjectCache

  • 4.3 场景四:factoryBean#getObject的返回对象不为单例时,不由Spring管理,也不存储于factoryBeanObjectCache缓存中#

当User.isSingleton() 返回false时,不是单例对象,bean2,bean3 不会存入factoryBeanObjectCache缓存中,bean2,bean3 都会重新创建,代码和运行截图所示。

package com.gientech.factoryBean;


import org.springframework.beans.factory.FactoryBean;

public class MyFactoryBean implements FactoryBean<User> {

    private String userInfo;

    public String getUserInfo() {
        return userInfo;
    }

    public void setUserInfo(String userInfo) {
        this.userInfo = userInfo;
    }

    @Override
    public User getObject() throws Exception {
        User user = new User();
        String[] arr = userInfo.split(",");
        user.setId(arr[0]);
        user.setUserName(arr[1]);
        user.setEmail(arr[2]);
        user.setPassword(arr[3]);
        return user;
    }

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

    // 此处返回为false
    @Override
    public boolean isSingleton() {
        return false;
    }
}
ApplicationContext ac = new ClassPathXmlApplicationContext("factoryBean.xml");
        // 获取实现了BeanFactory接口类的对象
        MyFactoryBean factoryBean = (MyFactoryBean) ac.getBean("&userFactory");
        System.out.println(factoryBean);

        User bean2 = (User) ac.getBean("userFactory");
        System.out.println(bean2);

        User bean3 = (User) ac.getBean("userFactory");
        System.out.println(bean3);

factoryBeanObjectCache 截图如下图所示:
factoryBeanObjectCache

运行结果如下图所示
factoryBeanObjectCache

作者:zgcy123456

出处:https://www.cnblogs.com/zgcy123456/p/18055443

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   zgcy123456  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示