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

只需要一些由社区评估的东西。以下是一段代码,这是一个创建特定类型实例的简单工厂。该方法将在上下文中将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之类的东西。如果上述风险可以接受,那么你的方法也应该可行。

以上是 在Spring的运行时注册bean(原型) 的全部内容, 来源链接: utcz.com/qa/420789.html

回到顶部