如果查找属性存在于Resource注释中,如何使Spring执行真正的JNDI查找



我们希望在单元测试中将ejb作为Spring组件进行测试。

使用Resources注释查找如下JNDI值的ejb之一:

@Resource(lookup = "java:global/myapp/portal/url")
private String portalUrl;

问题是,Spring似乎试图按类型查找值,即它在应用程序上下文中查找java.lang.String类型的bean,而不是使用JNDI。

这是我们的代码

背景1:

<bean id="serverMock" class="myapp.JndiServerMock">
</bean>

背景2:

<context:annotation-config />
<context:component-scan base-package="myapp">
    <context:include-filter type="annotation" expression="javax.ejb.Stateless" />
    <context:include-filter type="annotation"
        expression="javax.annotation.Resources" />
</context:component-scan>
<bean
    class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
    <property name="alwaysUseJndiLookup" value="true" />
</bean>
<bean id="clientMock" class="myapp.JndiClientMock">
<bean id="java:global/myapp/portal/url" class="java.lang.String">
    <constructor-arg value="http://localhost:8080" type="java.lang.String"/>
</bean>

JndiServerMock:

JndiServerMock公共类{

public JndiServerMock() throws IllegalStateException, NamingException {
    SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
    builder.bind("java:global/myapp/portal/url", "http://localhost:8080");
    builder.activate();
}

}

JndiClientMock:

JndiClientMock公共类{

public JndiClientMock() throws NamingException {
    Hashtable<String, String> prop = new Hashtable<String, String>();
    prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.springframework.mock.jndi.SimpleNamingContextBuilder");
    InitialContext ic = new InitialContext(prop);
    System.err.println("result = " + ic.lookup("java:global/myapp/portal/url"));
}

}

ExampleBean:

@Stateless公共类ExampleBean {

@Resource(lookup = "java:global/myapp/portal/url")
private String portalUrl;
public ExampleBean() {
    System.err.println("portalUrl = " + portalUrl);
}

}

公共类MainApp {

public static void main(String[] args) {
    System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.springframework.mock.jndi.SimpleNamingContextBuilder");
    ApplicationContext applicationContext = 
        new ClassPathXmlApplicationContext("/spring/firstContext.xml", 
            "/spring/secondContext.xml");
    ExampleBean exampleBean = applicationContext.getBean(ExampleBean.class); 
}

}

如果省略了"java:global/myapp/portal/url" bean定义,则会抛出以下异常:

由以下原因引起:org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualified bean of type [java.lang. lang.]期望至少有1个bean符合此依赖的自动候选资格。依赖注释:{@javax.annotation。资源(shareable=true, lookup=java:global/myapp/portal/url),名称=,描述=,authenticationType=CONTAINER,类型=class java.lang. lang. html对象,mappedName =)}org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException (DefaultListableBeanFactory.java: 1301)org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency (DefaultListableBeanFactory.java: 1047)org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency (DefaultListableBeanFactory.java: 942)org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource (CommonAnnotationBeanPostProcessor.java: 457)org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource (CommonAnnotationBeanPostProcessor.java: 435)org.springframework.context.annotation.CommonAnnotationBeanPostProcessor ResourceElement.getResourceToInject美元(CommonAnnotationBeanPostProcessor.java: 559)org.springframework.beans.factory.annotation.InjectionMetadata InjectedElement.inject美元(InjectionMetadata.java: 169)org.springframework.beans.factory.annotation.InjectionMetadata.inject (InjectionMetadata.java: 88)org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues (CommonAnnotationBeanPostProcessor.java: 305)…13

我认为这里的问题是您如何尝试在Spring配置中设置JNDI条目—这里有一个如何做到这一点的示例。这提供了实现相同目标的其他方法的示例。但是,如果您希望在单元测试中这样做,我认为这里的JUnit部分可能是一种更简洁的方法,但看起来您确实有很多选择!

最新更新