注册博奥维夫 /原型/ 在执行期间 Spring

你只需要在社区中欣赏一些事情。 下面是代码的片段,这是一个简单的出厂创建特定类型的实例。 该方法将在上下文中注册Bob作为原型并返回实例。 这是我第一次在执行期间配置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;

}

}


在容器中配置了同步循环工厂 IoC 作为 singleton. 因此,要创建一个新的同步管理器,我执行以下操作:


flexSyncFactory.createSyncService/userName, password, SyncType.FULL/;


我用 Spring 3.1. 请审核并提供您有价值的评论。

尊重地。
已邀请:

董宝中

赞同来自:

这是一个纯粹的意见,而不是专家意见:

Spring 提供了两个机制,用于自定义应用程序上下文使用
http://static.springsource.org ... .html
, 这允许您更改现有定义 bean 或添加新定义 bean, 和 BeanPostProcessors
http://static.springsource.org ... .html
这允许您更改实例 bean/将它们转换为代理服务器等。/.

Spring 不提供任何其他方法可以在执行期间动态添加Bean定义或Bean实例,但正如您已完成的那样,已收到Bean Factory的基本实例并添加Bean定义,这是其中一种方式。 它有效,但有风险:

如果使用新类型倒带现有组件名称,则会发生什么,因为处理了该组件的位置。 此外,如果现有组件名称将被完全不同的类型覆盖,会发生什么!

此最近注册的Bob不会自动连接到它的任何字段,也将输入其他豆类 - 因此,实际上,豆类工厂仅作为存储鲍勃的注册表,而不是注入依赖性的函数!

如果一个
refresh//

在应用程序的上下文中调用,Beans的备份因子将被覆盖并创建新的,因此直接注册Bean Factore的Bean的所有副本将丢失。

如果目标仅仅用于创建自动连接的豆类 Spring, 我会选择类似的东西
http://static.springsource.org ... .html
. 如果上述风险是可接受的,那么您的方法应该工作。

奔跑吧少年

赞同来自:

它为我工作:
http://random-thoughts-vortex. ... .html
声明一个选定的上下文组件 Spring, 它将实现接口 ApplicationContextAware 和 BeanFactoryPostProcessor:


public class MyContextWrapper implements ApplicationContextAware,
BeanFactoryPostProcessor {

private ApplicationContext appContext;
private ConfigurableListableBeanFactory factory;

public void postProcessBeanFactory/ConfigurableListableBeanFactory factory/
throws BeansException {
this.factory = factory;
}
public void setApplicationContext/ApplicationContext c/
throws BeansException {
this.appContext = c;
}

//setters and getters

}


让我们 spring 在上下文中载入此组件,请在配置文件中声明它 XML:


<bean class="my.package.MyContextWrapper" id="appContext">
</bean>


现在,通过联系它可以将此组件下载到应用程序的任何其他组件:


<bean class="my.package.MyBeanFactory" id="myBeanFactory">
<property name="springContext" ref="appContext">
</property>
</bean>


使用 GenericBeanDefinition 要下载Bob的定义:


BeanDefinitionRegistry registry = //BeanDefinitionRegistry /factory/;

GenericBeanDefinition beanDefinition = new GenericBeanDefinition//;
beanDefinition.setBeanClass/MyBeanClass.class/;
beanDefinition.setLazyInit/false/;
beanDefinition.setAbstract/false/;
beanDefinition.setAutowireCandidate/true/;
beanDefinition.setScope/"session"/;

registry.registerBeanDefinition/"dynamicBean",beanDefinition/;


Bob在会话区域中创建,并将存储在用户会话中。 财产 auto wire candidate 举报 spring, 应该是组件依赖项,如 setter 或者 getter, 或者自动处理的构造函数参数 Spring. 初始化的懒惰属性说 Spring 如果必须在必要时使用此组件。

获取描述符 Spring bean, 使用应用程序上下文 Spring 通过以下方式:


Object bean= 
getApplicationContext//.getBean/"dynamicBean"/;
if/bean instanceof MyBeanClass/{
MyBeanClass myBean = /MyBeanClass/ bean;

// do with the bean what ever you have to do.
}

石油百科

赞同来自:

你的决定看起来不错。 我相信我们也可以通过创建实现接口的鲍勃来实现这一目标 BeanNameAware 和 FactoryBean, 然后在创建上下文之前设置值。


xxxxBean.beansByName.put/"synTable", synTable/;
ApplicationContext context = new ClassPathXmlApplicationContext/"beans.xml"/;
assert externalDataSource == context.getBean/"synTable"/;


这是鲍巴的实施


public class xxxxBean implements BeanNameAware, FactoryBean {

public static Map<string, object=""> beans = new HashMap<string, object="">//;

private String beanName;

@Override
public void setBeanName/String beanName/ {
this.beanName = beanName;
}

@Override
public Object getObject// {
return beans.get/beanName/;
}

@Override
public Class<? > getObjectType// {
return beans.get/beanName/.getClass//;
}

@Override
public boolean isSingleton// {
return true;
}

}


</string,></string,>

要回复问题请先登录注册