如何使用基于注释的配置(即:JavaConfig)在 Spring 中定义远程 EJB Bean

How to define Remote EJBs Beans in Spring using annotation-based configuration (ie: JavaConfig)

我正在尝试找出使用 JavaConfig(基于注释的配置)在 Spring 4.x 中定义 Remote EJB 3 bean 的最佳方法。

我查看了 Spring Docs for <jee:remote-slsb> 并拼凑了一个功能配置,但它很糟糕:

@Bean
public LoginManager getLoginManager(){
    SimpleRemoteStatelessSessionProxyFactoryBean factory = new SimpleRemoteStatelessSessionProxyFactoryBean();
    String beanName = "jndi.ejb3.LoginManager";
    factory.setJndiName(beanName);
    factory.setBusinessInterface(LoginManager.class);
    Properties p = new Properties();
    p.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory" );
    p.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces" );
    p.setProperty("java.naming.provider.url", "jnp:localhost:1099");
    factory.setJndiEnvironment(p);
    try {
        factory.afterPropertiesSet();
    } catch (NamingException e1) {
        e1.printStackTrace();
    }
    return (LoginManager) factory.getObject();
}

我不应该在 bean 定义中调用 afterPropertiesSet(),我本以为 getObject() 应该被 Spring 自动调用。此外,这还意味着为我要加载的每个 Remote EJB 定义工厂,这似乎不对。我会有 liked/expected 一种方法,我可以定义一个可重用的工厂,并为每个 bean 创建将 Interface/JNDI 名称传递给它,但这不起作用。

spring docs表示:

Also, with @Bean methods, you will typically choose to use programmatic JNDI lookups: either using Spring’s JndiTemplate/JndiLocatorDelegate helpers or straight JNDI InitialContext usage, but not the JndiObjectFactoryBean variant which would force you to declare the return type as the FactoryBean type instead of the actual target type, making it harder to use for cross-reference calls in other @Bean methods that intend to refer to the provided resource here.

所以现在我很困惑该怎么办。

EJB Specific spring docs也推荐使用SimpleRemoteStatelessSessionProxyFactoryBean:

Defining explicit <jee:local-slsb> / <jee:remote-slsb> lookups simply provides consistent and more explicit EJB access configuration.

那么我该如何干净地做到这一点?

您不需要显式调用 afterProperties 方法,因为这是 spring bean 生命周期的一部分。此外,如果您将 bean 声明为工厂 bean,spring 将在需要时自动使用 getObject 获取真实对象。这是修改后的代码

    @Bean
public FactoryBean getLoginManagerFactory(){
    SimpleRemoteStatelessSessionProxyFactoryBean factory = new SimpleRemoteStatelessSessionProxyFactoryBean();
    String beanName = "jndi.ejb3.LoginManager";
    factory.setJndiName(beanName);
    factory.setBusinessInterface(LoginManager.class);
    Properties p = new Properties();
    p.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory" );
    p.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces" );
    p.setProperty("java.naming.provider.url", "jnp:localhost:1099");
    factory.setJndiEnvironment(p);
return factory;
}