Khu*_*ush 21 java spring dependency-injection spring-mvc
只需要社区评估的东西.以下是一段代码,它是一个创建特定类型实例的简单工厂.该方法将在上下文中将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;
}
}
Run Code Online (Sandbox Code Playgroud)
FLEX Sync工厂已在IoC容器中配置为单例.因此,要创建新的同步管理器,请执行以下操作:
flexSyncFactory.createSyncService(userName, password, SyncType.FULL);
Run Code Online (Sandbox Code Playgroud)
我使用的是Spring 3.1.请查看并提供宝贵的反馈意见.
亲切的问候.
Bij*_*men 24
这纯粹是我的观点,不是专家观点:
Spring提供了两种自定义修改应用程序上下文的机制 - 使用允许修改现有bean定义或添加新bean定义的BeanFactoryPostProcessor,以及允许修改bean实例(将它们包装在代理等周围)的BeanPostProcessors.
Spring没有提供在运行时动态添加bean定义或bean实例的任何其他本机方式,但是就像你通过获取底层bean工厂实例并添加bean定义一样,这是一种方法.它有效,但存在风险:
如果用新类型覆盖现有bean名称会发生什么情况,如何处理已经注入此bean的位置.此外,如果现有的bean名称被完全不同的类型覆盖会发生什么!
这个新注册的bean不会有任何自动装入的字段,也不会注入其他bean - 所以bean工厂本质上只是作为一个注册表来保存bean,而不是真正的依赖注入功能!
如果refresh()在应用程序上下文中调用a,则将覆盖辅助bean工厂并创建一个新工厂,因此将直接针对bean工厂注册的任何bean实例都将丢失.
如果目标纯粹是为了创建Spring自动装配的bean,那么我会选择像@Configurable这样的东西.如果上述风险可以接受,您的方法也应该有效.
小智 11
这对我有用:http: //random-thoughts-vortex.blogspot.com/2009/03/create-dynamically-spring-beans.html
声明一个专用的Spring上下文bean,它将实现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
}
Run Code Online (Sandbox Code Playgroud)
让Spring通过在XML配置文件中声明bean来将此bean加载到它的上下文中:
<bean id="appContext" class="my.package.MyContextWrapper">
</bean>
Run Code Online (Sandbox Code Playgroud)
现在可以通过引用它来将此bean加载到应用程序的任何其他bean中:
<bean id="myBeanFactory" class="my.package.MyBeanFactory">
<property name="springContext" ref="appContext">
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
使用GenericBeanDefinition加载bean定义:
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);
Run Code Online (Sandbox Code Playgroud)
Bean在会话范围中创建,并将存储在用户会话中.属性auto wire candidate告诉spring是否应该由Spring自动处理bean的依赖项,如setter或getter或构造函数参数.属性lazy init告诉Spring是否应该在需要时实例化这个bean.
要获取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.
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
46831 次 |
| 最近记录: |