【问题标题】:RESTeasy InMemoryClient does not inject @Context UriInfo field into Spring @Transactional BeanRESTeasy InMemoryClient 不会将 @Context UriInfo 字段注入 Spring @Transactional Bean
【发布时间】:2013-08-14 17:19:18
【问题描述】:

我们的测试存在问题,即当资源包装在 TransactionalProxy 中时,字段 UriInfo 未正确注入。 我们尝试使用 SpringResourceFactory,但这也无济于事。

我试图为这个用例提取相关类:


public class InMemoryClientFactory implements FactoryBean<InMemoryClientExecutor>{

    @Inject
    private SessionResource sessionResource;

    @Override
    public InMemoryClientExecutor getObject() throws Exception {
        Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
        Registry registry = dispatcher.getRegistry();
        registry.addSingletonResource(sessionResource);
        final InMemoryClientExecutor inMemoryClientExecutor = new InMemoryClientExecutor(dispatcher);
    }

    @Override
    public Class getObjectType() {
        return InMemoryClientExecutor.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

@Path("session")
public interface SessionResource {

    @GET
    @Path("{sessionId}")
    @Produces({MediaType.APPLICATION_XML})
    Response get(@PathParam("sessionId") String sessionId);

    @DELETE
    @Path("{sessionId}")
    Response delete(@PathParam("sessionId") String sessionId);
}

@Service
@Transactional
public class SessionResourceImpl implements SessionResource {

    @Context
    private UriInfo uriInfo;

    @Override
    public Response get(String sessionId) {
         // uriInfo will be null here
         String url = uriInfo.getBaseUriBuilder().path(SessionResource.class).path(SessionResource.class, "delete").build(sessionId)
                .toString());

        return Response.ok(session).build();

    @Override
    public Response delete(String sessionId) {
         System.out.println("Deleted Session "+1);
    }
}


@ContextConfiguration(locations = ["classpath:/META-INF/testContext.xml"])
@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
public class SessionResourceIT {

    @Inject
    InMemoryRestClientFactory inMemoryClientFactory;

    @Inject
    SessionResource resource;

    @Test
    public void test() {
        SessionResource resource = inMemoryClientFactory.createProxy(SessionResource.class);

        ClientResponse cr = client.get(sessionId);
        assertNotNull(cr.getEntity(String.class));
    }
}

【问题讨论】:

    标签: java spring resteasy in-memory


    【解决方案1】:

    一种可能的解决方法是解开测试的事务代理,只要测试本身使用@Transactional 注释就可以了。我希望有人有比这更好的解决方案。

    
    public class InMemoryClientFactory implements FactoryBean<InMemoryClientExecutor>{
    
        @Inject
        private SessionResource sessionResource;
    
        @Override
        public InMemoryClientExecutor getObject() throws Exception {
            Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
            Registry registry = dispatcher.getRegistry();
            registry.addSingletonResource(unwrapProxy(sessionResource));
            final InMemoryClientExecutor inMemoryClientExecutor = new InMemoryClientExecutor(dispatcher);
        }
    
        @Override
        public Class getObjectType() {
            return InMemoryClientExecutor.class;
        }
    
        @Override
        public boolean isSingleton() {
            return true;
        }
    
        private static Object unwrapProxy(Object bean) throws Exception {
            Object result = bean;
            /*
             * If the given object is a proxy, set the return value as the object
             * being proxied, otherwise return the given object.
             */
            if (AopUtils.isAopProxy(bean) && bean instanceof Advised) {
                Advised advised = (Advised) bean;
                result = advised.getTargetSource().getTarget();
            }
            return result;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-02-19
      • 2019-08-31
      • 1970-01-01
      • 2011-04-20
      • 2020-03-08
      • 2014-12-04
      • 1970-01-01
      • 2012-10-01
      • 1970-01-01
      相关资源
      最近更新 更多