Skip to content

Instantly share code, notes, and snippets.

@matthauck
Last active August 29, 2015 14:03
Show Gist options
  • Save matthauck/ae2565d0f2afde56b3a1 to your computer and use it in GitHub Desktop.
Save matthauck/ae2565d0f2afde56b3a1 to your computer and use it in GitHub Desktop.

Revisions

  1. matthauck revised this gist Aug 7, 2014. 3 changed files with 41 additions and 0 deletions.
    24 changes: 24 additions & 0 deletions JerseyConfig.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    package com.foo;

    import javax.inject.Inject;

    import org.glassfish.hk2.api.ServiceLocator;
    import org.glassfish.jersey.server.ResourceConfig;
    import org.springframework.context.ApplicationContext;

    public class JerseyConfig extends ResourceConfig {

    @Inject
    public JerseyConfig(ServiceLocator locator) {
    // Integrate spring w/ jersey
    ApplicationContext ctx = JerseySpringBridge.getApplicationContext(locator);

    JerseySpringBridge.integrate(ctx, locator);

    // register(SomeFeature.class);
    // ...
    // packages("com.foo.something");
    // ...
    }
    }

    2 changes: 2 additions & 0 deletions JerseySpringBridge.java
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    package com.foo;

    import javax.servlet.ServletContext;
    import javax.ws.rs.Path;

    15 changes: 15 additions & 0 deletions web.xml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@

    <!-- ... -->

    <servlet>
    <servlet-name>jersey</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

    <init-param>
    <param-name>javax.ws.rs.Application</param-name>
    <param-value>com.foo.JerseyConfig</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- ... -->
  2. matthauck revised this gist Jul 4, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion JerseySpringBridge.java
    Original file line number Diff line number Diff line change
    @@ -14,7 +14,7 @@

    /**
    * implement the spring integration ourselves since jersey's spring3 module
    * requires integration with hk2's injection system and is horrendously slow
    * requires integration with hk2's injection system and is quite slow
    *
    * @author mhauck
    */
  3. matthauck created this gist Jul 4, 2014.
    96 changes: 96 additions & 0 deletions JerseySpringBridge.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,96 @@
    import javax.servlet.ServletContext;
    import javax.ws.rs.Path;

    import java.util.HashSet;
    import java.util.Set;

    import org.glassfish.hk2.api.DynamicConfiguration;
    import org.glassfish.hk2.api.Factory;
    import org.glassfish.hk2.api.ServiceLocator;
    import org.glassfish.hk2.utilities.binding.ServiceBindingBuilder;
    import org.glassfish.jersey.internal.inject.Injections;
    import org.springframework.context.ApplicationContext;
    import org.springframework.web.context.support.WebApplicationContextUtils;

    /**
    * implement the spring integration ourselves since jersey's spring3 module
    * requires integration with hk2's injection system and is horrendously slow
    *
    * @author mhauck
    */
    public class JerseySpringBridge {

    public static ApplicationContext getApplicationContext(ServiceLocator locator) {
    return WebApplicationContextUtils.getWebApplicationContext(
    locator.getService(ServletContext.class)
    );
    }


    /**
    * Integrate spring w/ jersey/hk2
    */
    public static void integrate(ApplicationContext ctx, ServiceLocator locator) {
    DynamicConfiguration config = Injections.getConfiguration(locator);

    for (ResourceBean bean : resourceBeans(ctx)) {
    ServiceBindingBuilder<Object> binding = Injections.newFactoryBinder(
    new SpringLookup(ctx, bean)
    );
    binding.to(bean.type);
    Injections.addBinding(binding, config);
    }

    config.commit();
    }

    private static Set<ResourceBean> resourceBeans(ApplicationContext ctx) {
    Set<ResourceBean> resources = new HashSet<>();
    for (String beanName : ctx.getBeanDefinitionNames()) {
    Class<?> beanType = ctx.getType(beanName);
    if (isResource(beanType)) {
    resources.add(new ResourceBean(beanName, beanType));
    }
    }

    return resources;
    }

    protected static boolean isResource(Class<?> type) {
    return type.isAnnotationPresent(Path.class);
    }

    private static class ResourceBean {

    final String name;
    final Class<?> type;

    public ResourceBean(String name, Class<?> type) {
    this.name = name;
    this.type = type;
    }
    }

    private static class SpringLookup implements Factory<Object> {

    private ResourceBean resource;
    private ApplicationContext ctx;

    SpringLookup(ApplicationContext ctx, ResourceBean resource) {
    this.ctx = ctx;
    this.resource = resource;
    }

    @Override
    public Object provide() {
    return ctx.getBean(resource.name, resource.type);
    }

    @Override
    public void dispose(Object instance) {

    }

    }

    }