package com.foo; 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 quite 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 binding = Injections.newFactoryBinder( new SpringLookup(ctx, bean) ); binding.to(bean.type); Injections.addBinding(binding, config); } config.commit(); } private static Set resourceBeans(ApplicationContext ctx) { Set 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 { 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) { } } }