带有 Spring 引导的嵌入式 Tomcat JNDI 映射

Embedded Tomcat JNDI Map with Spring Boot

我们正在使用 Glassfish,我们在其中设置了 Map 类型的 JNDI 资源,我们定义了一些 Bean 工厂,之后我们可以在我们的代码中访问(JNDI 查找)这个映射。

我想对使用 Spring 启动的嵌入式 Tomcat 测试做同样的事情,但我不知道如何做。他们到处都只是引用如何添加 JNDI 数据源而不是一些 Hashmap。我试过这样的东西,但我的猜测是完全错误的。

public TomcatEmbeddedServletContainerFactory tomcatFactory() {
     return new TomcatEmbeddedServletContainerFactory() {

        @Override
        protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
                Tomcat tomcat) {
            tomcat.enableNaming();
            return super.getTomcatEmbeddedServletContainer(tomcat);
        }
            @Override
            protected void postProcessContext(Context context) {
                ContextResource resource = new ContextResource();
                resource.setName("jndiname");
                resource.setType(Map.class.getName());
                // for testing only
                resource.setProperty("testproperty", "10");

                context.getNamingResources().addResource(resource);
            }
        };
    }


    @Bean(destroyMethod="")
    public Map jndiDataSource() throws IllegalArgumentException, NamingException {
        JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
        bean.setJndiName("jndiname");
        bean.setProxyInterface(Map.class);
        bean.setLookupOnStartup(false);
        bean.setResourceRef(true);
        bean.afterPropertiesSet();
        return (Map)bean.getObject();
    }

我不知道将对象工厂传递到哪里。嵌入式 Tomcat?

有可能吗?

首先要做的是创建一个 ObjectFactory 实现,它可以 return Map:

public class MapObjectFactory implements ObjectFactory {

    @Override
    public Object getObjectInstance(Object obj, Name name,
            javax.naming.Context nameCtx, Hashtable<?, ?> environment)
            throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        // Configure the map as appropriate
        return map;
    }   
}

然后使用 ContextResource 上的 factory 属性 配置 ObjectFactory:

@Override
protected void postProcessContext(Context context) {
    ContextResource resource = new ContextResource();
    resource.setName("foo/myMap");
    resource.setType(Map.class.getName());
    resource.setProperty("factory", MapObjectFactory.class.getName());
    context.getNamingResources().addResource(resource);
}