2014-01-08 56 views
8

我使用Jersey 2和Spring,我试图用Spring上下文中的参数初始化我的Jersey应用程序(即派生自ResourceConfig的类)。我有一个我构建的泽西岛应用程序(即单个WAR),我将它部署在不同服务器上具有不同Spring配置的服务器群集上,以启用或禁用服务器的不同部分,例如,一些服务器具有/search资源开启等,这是在泽西岛1.0真的很简单:我只是把,如何使用Spring初始化Jersey应用程序(ResourceConfig)?

<context:component-scan base-package="com.mycompany.resources.search"/> 
在Spring配置有泽西

扫描特定的软件包,并启用JAX-RS资源提供者在里面。

现在在新泽西州2.0春天<context:component-scan ... />不工作,所以资源以编程方式从ResourceConfig衍生启动类注册:

public class MyApplication extends ResourceConfig { 

    public MyApplication() { 
     packages("com.mycompany.resources.search"); 
    } 
} 

到目前为止好,但我需要有条件扫描该软件包,我无法弄清楚如何将任何Spring配置加入到MyApplication类中。我认为,构造函数注入可能的工作:

public class MyApplication extends ResourceConfig { 

    @Autowired 
    public MyApplication(@Qualifier("my-config") MyConfiguration myConfiguration) { 
     if (myConfiguration.isEnabled()) { 
      packages("com.mycompany.resources.search"); 
     } 
    } 
} 

然而HK2抱怨说,它无法找到一个默认的构造函数使用......所以这表明,我认为DI是在玩这一类的建设,但DI不使用Spring。

同样地,使用了Spring bean的生命周期不工作:

public class MyApplication extends ResourceConfig implements InitializingBean { 

    @Autowired 
    private MyConfiguration myConfiguration; 

    public MyApplication() { 
    } 

    @Override 
    public void afterPropertiesSet() throws Exception { 
     if (myConfiguration.isEnabled()) { 
      packages("com.mycompany.resources.search"); 
     } 
    } 
} 

(该afterPropertiesSet方法不叫)

所以现在我被困在:有什么办法使用Spring配置Jersey ResourceConfig应用程序对象?

UPDATE:

我接受了@下面JohnR的答案,但我还会包括我的最终解决我认为这是一个有点清洁。 @ JohnR的回答是让对象初始化两次:首先是Spring,然后是Jersey/HK2。当Spring初始化对象时,将缓存依赖关系到静态成员中,然后当Jersey/HK2稍后初始化它时,可以检索依赖关系。

我落得这样做:

public class MyApplication extends ResourceConfig { 

    public MyApplication() { 
     ApplicationContext rootCtx = ContextLoader.getCurrentWebApplicationContext(); 
     MyConfiguration myConfiguration = rootCtx.getBean(MyConfiguration.class); 

     if (myConfiguration.isEnabled()) { 
      packages("com.mycompany.resources.whatever"); 
     } 
    } 
} 

而不是对象初始化两次,我们让泽西/ HK2初始化,但后来我们检索春天的依赖关系。

这两种解决方案都容易受到时间限制:他们都假设Spring在Jersey/HK2之前初始化。

+0

我遇到了与Jersey 2 + Spring类似的问题。最后,我结束了自己的整合。 [我对这个问题的回答](http://stackoverflow.com/questions/20506644/jersey-spring3-instantiating-spring-managed-bean-null)有帮助吗? –

+0

这是一个很好的答案。非常不幸的是,你必须推出自己的泽西岛/春季桥。可悲的是,我的经历与之类似:泽西岛2和斯普林顿浪费大量时间。我现在起来跑步了,但是如果你流浪了,那么泽西2号桥似乎有一条狭窄的“快乐道路”,还有许多陷阱。 我对任何开始使用Jersey 2和Spring的人的建议:请遵循[示例应用程序](https://github.com/jersey/jersey/tree/master/examples/helloworld-spring-webapp),并且不要尝试做任何不同的事情,因为它不会工作。 –

回答

0

所以现在我卡住了:有什么办法可以配置泽西岛 ResourceConfig应用程序对象使用Spring吗?

我不认为你可以配置泽西从Spring获取你的ResourceConfig作为Spring管理bean。这有点冒险,但你可以做这样的事情。请注意,您与您的ResourceConfig两个实例结束:一个由新泽西州的Spring和其他管理:

public class MyApplication extends ResourceConfig { 

    // static, available to all instances 
    private static MyConfiguration myConfiguration; 

    public MyApplication() { 
     // when Spring creates the first instance of MyApplication, myConfiguration 
     // will be null because the setter wasn't called yet 
     if (myConfiguration != null) 
     { 
      // second instance created by jersey... Spring will have autowired 
      // the first instance, and myConfiguration is static 
      if (myConfiguration.isEnabled()) 
       packages("com.mycompany.resources.search"); 
     } 
    } 

    @Autowired 
    public void setMyConfiguration(MyConfiguration config) 
    { 
     // instance level setter saves to a static variable to make it available for 
     // future instances (i.e. the one created by jersey) 
     MyApplication.myConfiguration = config; 
    } 
} 

再次,这是相当的hackish。你需要确保Spring在Jersey之前被初始化,仔细观察初始化期间可能发生的任何线程问题。

相关问题