当前位置: 首页 > 面试题库 >

在Spring的运行时注册bean(原型)

常源
2023-03-14
问题内容

只需要一些由社区评估的东西。以下是一段代码,这是一个创建特定类型实例的简单工厂。该方法将在上下文中将bean注册为原型并返回实例。这是我第一次在运行时配置bean。您能否评价并提供反馈?先感谢您。

package au.com.flexcontacts.flexoperations;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.AbstractApplicationContext;

import au.com.flexcontacts.exceptions.SyncClassCreactionError;

/**
 * @author khushroo.mistry
 * Class purpose: Simple Factory to create an 
 * instance of SynchroniseContactsService and register it in the Spring IoC.
 */
public final class FLEXSyncFactory implements ApplicationContextAware {

    private static AbstractApplicationContext context;


    /**
     * @param username
     * @param password
     * @param syncType
     * @return the correct service class
     * @throws SyncClassCreactionError
     * The method registers the classes dynamically into the Spring IoC
     */
    public final SynchroniseContactsService createSyncService(String username, String password, SyncType syncType) throws SyncClassCreactionError {

        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory();

        try {

            //Register the bean in the IoC
            BeanDefinition bdb = new GenericBeanDefinition();
            bdb.setBeanClassName(syncType.getClassName());
            bdb.setScope("prototype");
            ConstructorArgumentValues constructor = bdb.getConstructorArgumentValues();
            constructor.addIndexedArgumentValue(0, username);
            constructor.addIndexedArgumentValue(1, password);
            beanFactory.registerBeanDefinition(syncType.getInstanceName(), bdb);

            //Return instance of bean
            return (SynchroniseContactsService) beanFactory.getBean(syncType.getInstanceName());
        } catch (Exception e) {
            e.printStackTrace();
            throw new SyncClassCreactionError("Error: Illegal Handler");
        }

    }

    public void setApplicationContext(ApplicationContext applicationContext)
    throws BeansException {
        context = (AbstractApplicationContext) applicationContext;

    }

}

FLEX Sync工厂已在IoC容器中配置为单例。因此,要创建新的同步管理器,请执行以下操作:

flexSyncFactory.createSyncService(userName, password, SyncType.FULL);

我正在使用Spring 3.1。请查看并提供您宝贵的反馈意见。

亲切的问候。


问题答案:

这纯粹是我的观点,不是专家的观点:

Spring提供了两种用于自定义修改应用程序上下文的机制-
使用BeanFactoryPostProcessor允许修改现有的Bean定义或添加新的Bean定义,以及BeanPostProcessors允许修改Bean实例(将它们环绕在代理等周围)。

Spring没有提供任何其他本机方式来在运行时动态添加Bean定义或Bean实例,但是就像您已经掌握了底层Bean工厂实例并添加Bean定义一样,这是一种方法。它有效,但是存在风险:

  • 如果用新类型覆盖现有的Bean名称,会发生什么情况,如何处理已注入该Bean的位置。而且,如果现有的bean名称被完全不同的类型覆盖,会发生什么!

  • 这个新注册的bean将不会自动插入任何字段,也不会注入到其他bean中-因此,本质上,bean工厂纯粹是作为保存bean的注册表,并不是真正的依赖注入功能

  • 如果refresh()在应用程序上下文中调用a,则支持Bean工厂将被覆盖并创建一个新的bean,因此直接向该bean工厂注册的所有bean实例都将丢失。

如果目标是纯粹创建由Spring自动装配的bean,那么我会选择@Configurable之类的东西。如果上述风险可以接受,那么您的方法也应该可行。



 类似资料:
  • 只需要社区评估的东西。下面是一段代码,这是一个创建特定类型实例的简单工厂。该方法将在上下文中注册bean作为原型并返回实例。这是我第一次在运行时配置bean。你能好心评估并提供反馈吗?事先谢谢你。 FLEX Sync工厂已在IoC容器中配置为单例。因此,要创建一个新的同步管理器,我需要执行以下操作: 我使用的是Spring 3.1。请回顾并提供宝贵的反馈。 亲切的问候。

  • 我正在搜索一个在运行时注册@RestController的解决方案。我目前正在向

  • 我有一个具有两个endpoint的服务: 公共endpoint:任何人都可以访问它,并打开用户帐户(注册) 受保护endpoint:只有注册用户才能访问它,将授权头用作HTTP POST请求的一部分 用例: 用户首先到达公共endpoint并通过HTTP POST打开帐户,该JSON包含。然后服务生成密码,并将其作为JSON响应传递回用户。 用户从服务中拿回密码后,他应该使用这个(连同他的)通过在

  • 我知道ApplicationContext扩展点,如ApplicationContext事件和BeanFactoryPostProcessor。 我手头的问题是,在创建了一些bean之后,我需要添加bean,我想这会丢弃BeanFactoryPostProcessor选项,因为在应用程序上下文开始注册bean之前会发生这种情况。 我尝试在上下文刷新后添加一个singletonBean:

  • 问题内容: 我想知道以下情况是否可能。出于测试目的,我希望在应用程序上下文中为不同的测试声明不同的模拟类。这些是使用Jersey REST客户端的验收测试。有没有办法在运行时动态声明bean?Spring是否有API允许在加载上下文后更改应用程序上下文? 问题答案: 关于第一个问题,你可以在运行时通过BeanDefinitionRegistry.registerBeanDefinition()方法

  • 问题内容: 我试图将服务注入到正在使用Jersey的Rest类中。 无论我尝试如何或以何种方式插入此类,似乎在运行时都显示为null。查看日志文件表明,在初始化Web应用程序时正在调用setJsonTestService,并且此时它不为null。但是,当稍后通过对此类的PUT请求访问它时,它为null。 我完全困惑。 该类如下所示: 有任何想法吗? 更新: web.xml(泽西) 问题答案: 尝试