Skip to content
This repository was archived by the owner on May 28, 2018. It is now read-only.

Commit bc6a3dd

Browse files
Marek PotociarGerrit Code Review
authored andcommitted
Merge "JERSEY-1708: Implement sub-resource runtime model caching."
2 parents 25fa5d9 + 884d40f commit bc6a3dd

File tree

15 files changed

+1012
-221
lines changed

15 files changed

+1012
-221
lines changed

core-common/src/main/java/org/glassfish/jersey/internal/util/collection/Values.java

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
33
*
4-
* Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
4+
* Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved.
55
*
66
* The contents of this file are subject to the terms of either the GNU
77
* General Public License Version 2 only ("GPL") or the Common Development
@@ -45,6 +45,7 @@
4545
* @author Marek Potociar (marek.potociar at oracle.com)
4646
*/
4747
public final class Values {
48+
4849
private static final LazyValue EMPTY = new LazyValue() {
4950
@Override
5051
public Object get() {
@@ -100,7 +101,7 @@ public static <T, E extends Throwable> UnsafeValue<T, E> emptyUnsafe() {
100101
/**
101102
* Get a new constant {@link Value value provider} whose {@link Value#get() get()}
102103
* method always returns the instance supplied to the {@code value} parameter.
103-
*
104+
* <p/>
104105
* In case the supplied value constant is {@code null}, an {@link #empty() empty} value
105106
* provider is returned.
106107
*
@@ -113,6 +114,7 @@ public static <T> Value<T> of(final T value) {
113114
}
114115

115116
private static class InstanceValue<T> implements Value<T> {
117+
116118
private final T value;
117119

118120
public InstanceValue(final T value) {
@@ -125,9 +127,13 @@ public T get() {
125127
}
126128

127129
@Override
128-
public boolean equals(Object o) {
129-
if (this == o) return true;
130-
if (o == null || getClass() != o.getClass()) return false;
130+
public boolean equals(final Object o) {
131+
if (this == o) {
132+
return true;
133+
}
134+
if (o == null || getClass() != o.getClass()) {
135+
return false;
136+
}
131137

132138
return value.equals(((InstanceValue) o).value);
133139
}
@@ -146,7 +152,7 @@ public String toString() {
146152
/**
147153
* Get a new constant {@link UnsafeValue value provider} whose {@link UnsafeValue#get() get()}
148154
* method always returns the instance supplied to the {@code value} parameter.
149-
*
155+
* <p/>
150156
* In case the supplied value constant is {@code null}, an {@link #emptyUnsafe() empty} value
151157
* provider is returned.
152158
*
@@ -159,6 +165,7 @@ public static <T, E extends Throwable> UnsafeValue<T, E> unsafe(final T value) {
159165
}
160166

161167
private static class InstanceUnsafeValue<T, E extends Throwable> implements UnsafeValue<T, E> {
168+
162169
private final T value;
163170

164171
public InstanceUnsafeValue(final T value) {
@@ -171,9 +178,13 @@ public T get() {
171178
}
172179

173180
@Override
174-
public boolean equals(Object o) {
175-
if (this == o) return true;
176-
if (o == null || getClass() != o.getClass()) return false;
181+
public boolean equals(final Object o) {
182+
if (this == o) {
183+
return true;
184+
}
185+
if (o == null || getClass() != o.getClass()) {
186+
return false;
187+
}
177188

178189
return value.equals(((InstanceUnsafeValue) o).value);
179190
}
@@ -192,11 +203,11 @@ public String toString() {
192203
/**
193204
* Get a new "throwing" {@link UnsafeValue unsafe value provider} whose {@link UnsafeValue#get() get()}
194205
* method always throws the exception supplied to the {@code throwable} parameter.
195-
*
206+
* <p/>
196207
* In case the supplied throwable is {@code null}, an {@link NullPointerException} is thrown.
197208
*
198-
* @param <T> value type.
199-
* @param <E> exception type.
209+
* @param <T> value type.
210+
* @param <E> exception type.
200211
* @param throwable throwable instance to be thrown.
201212
* @return "throwing" unsafe value provider.
202213
* @throws NullPointerException in case the supplied throwable instance is {@code null}.
@@ -210,6 +221,7 @@ public static <T, E extends Throwable> UnsafeValue<T, E> throwing(final E throwa
210221
}
211222

212223
private static class ExceptionValue<T, E extends Throwable> implements UnsafeValue<T, E> {
224+
213225
private final E throwable;
214226

215227
public ExceptionValue(final E throwable) {
@@ -222,9 +234,13 @@ public T get() throws E {
222234
}
223235

224236
@Override
225-
public boolean equals(Object o) {
226-
if (this == o) return true;
227-
if (o == null || getClass() != o.getClass()) return false;
237+
public boolean equals(final Object o) {
238+
if (this == o) {
239+
return true;
240+
}
241+
if (o == null || getClass() != o.getClass()) {
242+
return false;
243+
}
228244

229245
return throwable.equals(((ExceptionValue) o).throwable);
230246
}
@@ -242,7 +258,7 @@ public String toString() {
242258

243259
/**
244260
* Get a new lazily initialized {@link Value value provider}.
245-
*
261+
* <p/>
246262
* The value returned by its {@link Value#get() get()} method is lazily retrieved during a first
247263
* call to the method from the supplied {@code delegate} value provider and is then cached for
248264
* a subsequent retrieval.
@@ -267,7 +283,7 @@ public static <T> LazyValue<T> lazy(final Value<T> delegate) {
267283

268284
/**
269285
* Get a new eagerly initialized {@link Value value provider}.
270-
*
286+
* <p/>
271287
* The value returned by its {@link Value#get() get()} method is eagerly computed from the supplied
272288
* {@code delegate} value provider and is then stored in a final field for a subsequent retrieval.
273289
* <p>
@@ -289,9 +305,10 @@ public static <T> Value<T> eager(final Value<T> delegate) {
289305
}
290306

291307
private static class EagerValue<T> implements Value<T> {
308+
292309
private final T result;
293310

294-
private EagerValue(Value<T> value) {
311+
private EagerValue(final Value<T> value) {
295312
this.result = value.get();
296313
}
297314

@@ -302,6 +319,7 @@ public T get() {
302319
}
303320

304321
private static class LazyValueImpl<T> implements LazyValue<T> {
322+
305323
private final Object lock;
306324
private final Value<T> delegate;
307325

@@ -332,9 +350,13 @@ public boolean isInitialized() {
332350
}
333351

334352
@Override
335-
public boolean equals(Object o) {
336-
if (this == o) return true;
337-
if (o == null || getClass() != o.getClass()) return false;
353+
public boolean equals(final Object o) {
354+
if (this == o) {
355+
return true;
356+
}
357+
if (o == null || getClass() != o.getClass()) {
358+
return false;
359+
}
338360

339361
return delegate.equals(((LazyValueImpl) o).delegate);
340362
}
@@ -352,7 +374,7 @@ public String toString() {
352374

353375
/**
354376
* Get a new lazily initialized {@link UnsafeValue unsafe value provider}.
355-
*
377+
* <p/>
356378
* The value returned by its {@link UnsafeValue#get() get()} method is lazily retrieved during a first
357379
* call to the method from the supplied {@code delegate} value provider and is then cached for
358380
* a subsequent retrieval.
@@ -380,6 +402,7 @@ public static <T, E extends Throwable> LazyUnsafeValue<T, E> lazy(final UnsafeVa
380402
}
381403

382404
private static class LazyUnsafeValueImpl<T, E extends Throwable> implements LazyUnsafeValue<T, E> {
405+
383406
private final Object lock;
384407
private final UnsafeValue<T, E> delegate;
385408

@@ -400,7 +423,7 @@ public T get() throws E {
400423
if (result == null) {
401424
try {
402425
result = Values.unsafe(delegate.get());
403-
} catch (Throwable e) {
426+
} catch (final Throwable e) {
404427
//noinspection unchecked
405428
result = Values.throwing((E) e);
406429
}
@@ -417,9 +440,13 @@ public boolean isInitialized() {
417440
}
418441

419442
@Override
420-
public boolean equals(Object o) {
421-
if (this == o) return true;
422-
if (o == null || getClass() != o.getClass()) return false;
443+
public boolean equals(final Object o) {
444+
if (this == o) {
445+
return true;
446+
}
447+
if (o == null || getClass() != o.getClass()) {
448+
return false;
449+
}
423450

424451
return delegate.equals(((LazyUnsafeValueImpl) o).delegate);
425452
}

core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
import org.glassfish.jersey.internal.inject.Providers;
9090
import org.glassfish.jersey.internal.util.ReflectionHelper;
9191
import org.glassfish.jersey.internal.util.collection.Ref;
92+
import org.glassfish.jersey.message.MessageBodyWorkers;
9293
import org.glassfish.jersey.message.internal.NullOutputStream;
9394
import org.glassfish.jersey.model.ContractProvider;
9495
import org.glassfish.jersey.model.internal.ComponentBag;
@@ -115,6 +116,7 @@
115116
import org.glassfish.jersey.server.model.ModelProcessor;
116117
import org.glassfish.jersey.server.model.ModelValidationException;
117118
import org.glassfish.jersey.server.model.Resource;
119+
import org.glassfish.jersey.server.model.ResourceMethodInvoker;
118120
import org.glassfish.jersey.server.model.ResourceModel;
119121
import org.glassfish.jersey.server.model.internal.ModelErrors;
120122
import org.glassfish.jersey.server.monitoring.ApplicationEvent;
@@ -136,7 +138,6 @@
136138
import jersey.repackaged.com.google.common.collect.Lists;
137139
import jersey.repackaged.com.google.common.collect.Sets;
138140
import jersey.repackaged.com.google.common.util.concurrent.AbstractFuture;
139-
import org.glassfish.jersey.message.MessageBodyWorkers;
140141

141142
/**
142143
* Jersey server-side application handler.
@@ -161,6 +162,7 @@
161162
* @author Jakub Podlesak (jakub.podlesak at oracle.com)
162163
* @author Marek Potociar (marek.potociar at oracle.com)
163164
* @author Libor Kramolis (libor.kramolis at oracle.com)
165+
*
164166
* @see ResourceConfig
165167
* @see javax.ws.rs.core.Configuration
166168
* @see org.glassfish.jersey.server.spi.ContainerProvider
@@ -443,16 +445,16 @@ private void initialize() {
443445
boolean extScopesFound = false;
444446

445447
if (extScopes.length == 1) {
446-
for (ComponentProvider p : componentProviders) {
448+
for (final ComponentProvider p : componentProviders) {
447449
if (p.bind(extScopes[0], new HashSet<Class<?>>(){{add(ExternalRequestScope.class);}})) {
448450
extScopesFound = true;
449451
break;
450452
}
451453
}
452454
} else if (extScopes.length > 1) {
453455
if (LOGGER.isLoggable(Level.WARNING)) {
454-
StringBuilder scopeList = new StringBuilder("\n");
455-
for (Class<ExternalRequestScope> ers : extScopes) {
456+
final StringBuilder scopeList = new StringBuilder("\n");
457+
for (final Class<ExternalRequestScope> ers : extScopes) {
456458
scopeList.append(" ").append(ers.getTypeParameters()[0]).append('\n');
457459
}
458460
LOGGER.warning(LocalizationMessages.WARNING_TOO_MANY_EXTERNAL_REQ_SCOPES(scopeList.toString()));
@@ -516,9 +518,11 @@ private void initialize() {
516518
final JerseyResourceContext jerseyResourceContext = locator.getService(JerseyResourceContext.class);
517519
jerseyResourceContext.setResourceModel(resourceModel);
518520

519-
final RuntimeModelBuilder runtimeModelBuilder = locator.getService(RuntimeModelBuilder.class);
520-
runtimeModelBuilder.setProcessingProviders(processingProviders);
521+
msgBodyWorkers = locator.getService(MessageBodyWorkers.class);
521522

523+
final RuntimeModelBuilder runtimeModelBuilder = new RuntimeModelBuilder(locator, runtimeConfig, msgBodyWorkers,
524+
locator.getService(ResourceMethodInvoker.Builder.class));
525+
runtimeModelBuilder.setProcessingProviders(processingProviders);
522526

523527
// assembly request processing chain
524528
/**
@@ -555,8 +559,6 @@ private void initialize() {
555559
locator.inject(instance);
556560
}
557561

558-
msgBodyWorkers = locator.getService(MessageBodyWorkers.class);
559-
560562
logApplicationInitConfiguration(locator, resourceBag, processingProviders);
561563

562564
if (compositeListener != null) {

core-server/src/main/java/org/glassfish/jersey/server/ServerProperties.java

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
33
*
4-
* Copyright (c) 2012-2014 Oracle and/or its affiliates. All rights reserved.
4+
* Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved.
55
*
66
* The contents of this file are subject to the terms of either the GNU
77
* General Public License Version 2 only ("GPL") or the Common Development
@@ -53,8 +53,9 @@
5353
* Jersey server-side configuration properties.
5454
*
5555
* @author Marek Potociar (marek.potociar at oracle.com)
56-
* @author Martin Matula (martin.matula at oracle.com)
5756
* @author Libor Kramolis (libor.kramolis at oracle.com)
57+
* @author Michal Gajdos (michal.gajdos at oracle.com)
58+
* @author Martin Matula
5859
*/
5960
@PropertiesClass
6061
public final class ServerProperties {
@@ -634,6 +635,62 @@ public final class ServerProperties {
634635
*/
635636
public static final String PROCESSING_RESPONSE_ERRORS_ENABLED = "jersey.config.server.exception.processResponseErrors";
636637

638+
/**
639+
* An integer value that defines the size of cache for sub-resource locator models. The cache is used to provide better
640+
* performance for application that uses JAX-RS sub-resource locators.
641+
* <p>
642+
* The default value is {@value #SUBRESOURCE_LOCATOR_DEFAULT_CACHE_SIZE}.
643+
* </p>
644+
* <p>
645+
* The name of the configuration property is <tt>{@value}</tt>.
646+
* </p>
647+
*
648+
* @see #SUBRESOURCE_LOCATOR_DEFAULT_CACHE_SIZE
649+
* @see #SUBRESOURCE_LOCATOR_CACHE_AGE
650+
* @since 2.16
651+
*/
652+
public static final String SUBRESOURCE_LOCATOR_CACHE_SIZE = "jersey.config.server.subresource.cache.size";
653+
654+
/**
655+
* The default sub-resource locator cache size ({@value}).
656+
*
657+
* @see #SUBRESOURCE_LOCATOR_CACHE_SIZE
658+
* @since 2.16
659+
*/
660+
public static final int SUBRESOURCE_LOCATOR_DEFAULT_CACHE_SIZE = 64;
661+
662+
/**
663+
* An integer value that defines the maximum age (in seconds) for cached for sub-resource locator models. The age of an cache
664+
* entry is defined as the time since the last access (read) to the entry in the cache.
665+
* <p>
666+
* Entry aging is not enabled by default.
667+
* </p>
668+
* <p>
669+
* The name of the configuration property is <tt>{@value}</tt>.
670+
* </p>
671+
*
672+
* @see #SUBRESOURCE_LOCATOR_CACHE_SIZE
673+
* @since 2.16
674+
*/
675+
public static final String SUBRESOURCE_LOCATOR_CACHE_AGE = "jersey.config.server.subresource.cache.age";
676+
677+
/**
678+
* If {@code true} then Jersey will cache {@link org.glassfish.jersey.server.model.Resource Jersey resources} in addition to
679+
* caching sub-resource locator classes and instances (which are cached by default).
680+
* <p/>
681+
* To make sure the caching is effective in this case you need to return same Jersey Resource instances for same input
682+
* parameters from resource method. This means that generating new Jersey Resource instances for same input parameters would
683+
* not have any performance effect and it would only fill-up the cache.
684+
* <p>
685+
* The default value is {@code false}.
686+
* </p>
687+
* <p>
688+
* The name of the configuration property is <tt>{@value}</tt>.
689+
* </p>
690+
*/
691+
public static final String SUBRESOURCE_LOCATOR_CACHE_JERSEY_RESOURCE_ENABLED =
692+
"jersey.config.server.subresource.cache.jersey.resource.enabled";
693+
637694
private ServerProperties() {
638695
// prevents instantiation
639696
}

0 commit comments

Comments
 (0)