From ab290a78d9b14a9e6c76cd91fa9ce7c541823ffa Mon Sep 17 00:00:00 2001 From: Johannes Schnatterer Date: Thu, 21 Jun 2018 11:54:54 +0200 Subject: [PATCH] User Root Resource: Use CDI Provider for subresources. Resources are request scoped and we need only one sub resource per request. That is, injecting all subresources (and their transitive inejctions)in the constructor builds a lot of objects that are never used. Solution: Inject provider, that lazily inject the needed subresources on demand. --- .../api/v2/resources/UserRootResource.java | 12 +++++----- .../scm/api/v2/resources/MockProvider.java | 22 +++++++++++++++++++ .../v2/resources/UserRootResourceTest.java | 9 ++++---- 3 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 scm-webapp/src/test/java/sonia/scm/api/v2/resources/MockProvider.java diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserRootResource.java index 4895b9211b..87b776ca66 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/UserRootResource.java @@ -2,28 +2,30 @@ package sonia.scm.api.v2.resources; import com.google.inject.Inject; +import javax.inject.Provider; import javax.ws.rs.Path; @Path(UserRootResource.USERS_PATH_V2) public class UserRootResource { public static final String USERS_PATH_V2 = "v2/users/"; - private final UserCollectionResource userCollectionResource; - private final UserResource userResource; + private final Provider userCollectionResource; + private final Provider userResource; @Inject - public UserRootResource(UserCollectionResource userCollectionResource, UserResource userResource) { + public UserRootResource(Provider userCollectionResource, + Provider userResource) { this.userCollectionResource = userCollectionResource; this.userResource = userResource; } @Path("") public UserCollectionResource getUserCollectionResource() { - return userCollectionResource; + return userCollectionResource.get(); } @Path("{id}") public UserResource getUserResource() { - return userResource; + return userResource.get(); } } diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MockProvider.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MockProvider.java new file mode 100644 index 0000000000..bf84e4fe15 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/MockProvider.java @@ -0,0 +1,22 @@ +package sonia.scm.api.v2.resources; + +import javax.inject.Provider; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * A mockito implementation of CDI {@link javax.inject.Provider}. + */ +class MockProvider { + + private MockProvider() {} + + static Provider of(I instance) { + @SuppressWarnings("unchecked") // Can't make mockito return typed provider + Provider provider = mock(Provider.class); + when(provider.get()).thenReturn(instance); + return provider; + } + +} diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserRootResourceTest.java index 55eb2c0be1..4064432a72 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/UserRootResourceTest.java @@ -64,8 +64,6 @@ public class UserRootResourceTest { @InjectMocks private UserToUserDtoMapperImpl userToDtoMapper; - private UserCollectionToDtoMapper userCollectionToDtoMapper; - private ArgumentCaptor userCaptor = ArgumentCaptor.forClass(User.class); @Before @@ -76,10 +74,11 @@ public class UserRootResourceTest { when(userManager.get("Neo")).thenReturn(dummyUser); doNothing().when(userManager).create(userCaptor.capture()); - userCollectionToDtoMapper = new UserCollectionToDtoMapper(userToDtoMapper, uriInfoStore); - UserCollectionResource userCollectionResource = new UserCollectionResource(userManager, dtoToUserMapper, userToDtoMapper, userCollectionToDtoMapper); + UserCollectionToDtoMapper userCollectionToDtoMapper = new UserCollectionToDtoMapper(userToDtoMapper, uriInfoStore); + UserCollectionResource userCollectionResource = new UserCollectionResource(userManager, dtoToUserMapper, userToDtoMapper, + userCollectionToDtoMapper); UserResource userResource = new UserResource(dtoToUserMapper, userToDtoMapper, userManager); - UserRootResource userRootResource = new UserRootResource(userCollectionResource, userResource); + UserRootResource userRootResource = new UserRootResource(MockProvider.of(userCollectionResource), MockProvider.of(userResource)); dispatcher.getRegistry().addSingletonResource(userRootResource); when(uriInfo.getBaseUri()).thenReturn(URI.create("/"));