开发者

Is it possible to specify a class name for Spring Framework in an external file?

开发者 https://www.devze.com 2022-12-19 01:56 出处:网络
I have an application built on the Spring Framework that uses an external properties file for some things like database host string, username and password so that we can check the configuration file i

I have an application built on the Spring Framework that uses an external properties file for some things like database host string, username and password so that we can check the configuration file into our repository (it's open source) and not compromise the security of the db. It also is great because developers can keep their own copy of this file and the application will automatically use the configuration on their system rather than having to reco开发者_StackOverflownfigure manually.

I would like to be able to specify a bean in the same manner. We're working with some classes that could change from developer to developer and it would be great if we could allow them to specify this information in a different file so they don't have to mess with the main configuration file.

To give you an idea, we have something like

<property name="url">
  <value>${db.host}</value>
</property>

Where db.host is specified in another file. What we want is something like

<bean name="ourBean" class="${class.weneed}" />

The above syntax doesn't actually work, but that demonstrates what we want to do.

Thanks in advance!

Chris


You can use a FactoryBean for this. This example is a FactoryBean which takes advantage of the ability of Spring to cast a classname to a Class object when injecting properties:

public class MyFactoryBean extends AbstractFactoryBean {

    private Class targetClass;

    public void setTargetClass(Class targetClass) {
        this.targetClass = targetClass;
    }

    @Override
    protected Object createInstance() throws Exception {
        return targetClass.newInstance();
    }

    @Override
    public Class getObjectType() {
        return targetClass;
    }

}

And then:

<bean name="ourBean" class="com.xyz.MyFactoryBean">
   <property name="targetClass" value="${class.weneed}"/>
</bean>

The Spring context will now have a bean called ourBean which is an object of type ${class.weneed}


another option might be to use cocoon-spring-configurator, which is part of Cocoon framework, but can be used on its own without dependening on any other cocoon stuff.
we use this for a lot of our webapps. the general idea is to configure the bean factory based on a runningMode.
it allows you to easily substitute/overwrite properties, but also to override complete bean defitions.
a common use case is to define the beans that your application uses and then have some extra config files (which are never checked into source control), to override some beans to mock some part of the application.


I found that bean created via reflection is not proper spring bean (not registered in spring context and no properties initialized), so here is minor improvement:

@Override
protected Object createInstance() throws Exception {
    AutowireCapableBeabFactory beanFactory = (AutowireCapableBeabFactory ) getBeanFactory();
    return beanFactory.createBean(this.targetClass);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号