看到不少朋友讨论 spring 配置时认为 spring 配置中只能静态的设置一些参数(典型情况如数据库配置, 定时器配置等)导致不方便, 其实 spring 已经提供了非常便利的方式来实现动态配置, 我们要做的只是实现一个自己的 factorybean , 来看一下 factorybean 接口的定义
代码
| /** * interface to be implemented by objects used within a beanfactory * that are themselves factories. if a bean implements this interface, * it is used as a factory, not directly as a bean. * * <p><b>nb: a bean that implements this interface cannot be used * as a normal bean.</b> a factorybean is defined in a bean style, * but the object exposed for bean references is always the object * that it creates. * * <p>factorybeans can support singletons and prototypes, and can * either create objects lazily on demand or eagerly on startup. * * <p>this interface is heavily used within the framework, for * example for the aop proxyfactorybean or jndiobjectfactorybean. * it can be used for application components, but this is not common * outside of infrastructure code. * * @author rod johnson * @author juergen hoeller * @since 08.03.2003 * @see org.springframework.beans.factory.beanfactory * @see org.springframework.aop.framework.proxyfactorybean * @see org.springframework.jndi.jndiobjectfactorybean */ public interface factorybean { /** * return an instance (possibly shared or independent) of the object * managed by this factory. as with a beanfactory, this allows * support for both the singleton and prototype design pattern. * <p>if this method returns <code>null</code>, the factory will consider * the factorybean as not fully initialized and throw a corresponding * factorybeannotinitializedexception. * @return an instance of the bean (should not be <code>null</code>; * a <code>null</code> value will be considered as an indication of * incomplete initialization) * @throws exception in case of creation errors * @see factorybeannotinitializedexception */ object getobject() throws exception; /** * return the type of object that this factorybean creates, or <code>null</code> * if not known in advance. this allows to check for specific types * of beans without instantiating objects, for example on autowiring. * <p>for a singleton, this should try to avoid singleton creation * as far as possible; it should rather estimate the type in advance. * for prototypes, returning a meaningful type here is advisable too. * <p>this method can be called <i>before</i> this factorybean has * been fully initialized. it must not rely on state created during * initialization; of course, it can still use such state if available. * <p><b>note:</b> autowiring will simply ignore factorybeans that return * <code>null</code> here. therefore it is highly recommended to implement * this method properly, using the current state of the factorybean. * @return the type of object that this factorybean creates, * or <code>null</code> if not known at the time of the call * @see listablebeanfactory#getbeansoftype */ class getobjecttype(); /** * is the bean managed by this factory a singleton or a prototype? * that is, will <code>getobject()</code> always return the same object * (a reference that can be cached)? * <p><b>note:</b> if a factorybean indicates to hold a singleton object, * the object returned from <code>getobject()</code> might get cached * by the owning beanfactory. hence, do not return <code>true</code> * unless the factorybean always exposes the same reference. * <p>the singleton status of the factorybean itself will generally * be provided by the owning beanfactory; usually, it has to be * defined as singleton there. * @return if this bean is a singleton * @see #getobject() */ boolean issingleton(); } |
看了以后发现, factorybean 用于在 spring 容器中创建其他的 bean, 我们平时用得最多的 jndiobjectfactorybean, hibernate 的 localsessionfactorybean 都是 factorybean 的具体实现, 既然如此, 读取动态配置就变得易如反掌了, 假如我们要实现动态读取数据库配置的功能, 拿使用率最高的 basicdatasource 为例, 简单的实现一个 basicdatasource factorybean 如下即可
代码
| public class basicdatasourcefactorybean implements factorybean { public object getobject() throws exception { basicdatasource datasource = new basicdatasource(); // 读取外部配置, 设置到 datasource 中 ... return datasource; } public class getobjecttype() { return basicdatasource.class; } public boolean issingleton() { return true; } } |
然后在 spring 中如此声明
代码
| <bean id="datasource" class="basicdatasourcefactorybean "> ... 你的配置来源 </bean> |
就这么简单。
闽公网安备 35060202000074号