You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2022/07/11 11:20:28 UTC

[juneau] branch jbFixRestNpe updated: New @RestBean/@RestMethodBean annotations

This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch jbFixRestNpe
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/jbFixRestNpe by this push:
     new f1a6642ff New @RestBean/@RestMethodBean annotations
f1a6642ff is described below

commit f1a6642ff8ddb5797384d99e92ea1f66745ac5ec
Author: JamesBognar <ja...@salesforce.com>
AuthorDate: Mon Jul 11 07:20:06 2022 -0400

    New @RestBean/@RestMethodBean annotations
---
 .../apache/juneau/cp/BeanCreateMethodFinder.java   |  39 +++++---
 .../java/org/apache/juneau/rest/RestContext.java   | 107 ++++++++++-----------
 .../java/org/apache/juneau/rest/RestOpContext.java |  94 +++++++++++-------
 .../apache/juneau/rest/annotation/RestBean.java    |  34 +++++++
 .../juneau/rest/annotation/RestMethodBean.java     |  44 +++++++++
 .../java/org/apache/juneau/cp/BeanStore_Test.java  |  16 +--
 6 files changed, 223 insertions(+), 111 deletions(-)

diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreateMethodFinder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreateMethodFinder.java
index cbfef3580..766a4a9aa 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreateMethodFinder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BeanCreateMethodFinder.java
@@ -116,7 +116,7 @@ public class BeanCreateMethodFinder<T> {
 	}
 
 	/**
-	 * Find the method matching the specified name and optionally having the specified required parameters present.
+	 * Find the method matching the specified predicate.
 	 *
 	 * <p>
 	 * In order for the method to be used, it must adhere to the following restrictions:
@@ -136,18 +136,16 @@ public class BeanCreateMethodFinder<T> {
 	 *
 	 * See {@link BeanStore#createMethodFinder(Class, Object)} for usage.
 	 *
-	 * @param methodName The method name.
-	 * @param requiredParams Optional required parameters.
+	 * @param filter The predicate to apply.
 	 * @return This object.
 	 */
-	public BeanCreateMethodFinder<T> find(String methodName, Class<?>...requiredParams) {
+	public BeanCreateMethodFinder<T> find(Predicate<MethodInfo> filter) {
 		if (method == null) {
 			method = ClassInfo.of(resourceClass).getPublicMethod(
 				x -> x.isNotDeprecated()
 				&& x.hasReturnType(beanType)
-				&& x.hasName(methodName)
 				&& x.hasNoAnnotation(BeanIgnore.class)
-				&& x.hasAllArgs(requiredParams)
+				&& filter.test(x)
 				&& beanStore.hasAllParams(x)
 				&& (x.isStatic() || resource != null)
 			);
@@ -158,14 +156,33 @@ public class BeanCreateMethodFinder<T> {
 	}
 
 	/**
-	 * Identical to {@link #find(String, Class...)} but named for fluent-style calls.
+	 * Shortcut for calling <c>find(<jv>x</jv> -&gt; <jv>x</jv>.hasName(<jv>methodName</jv>))</c>.
 	 *
-	 * @param methodName The method name.
-	 * @param requiredParams Optional required parameters.
+	 * @param methodName The method name to match.
 	 * @return This object.
 	 */
-	public BeanCreateMethodFinder<T> thenFind(String methodName, Class<?>...requiredParams) {
-		return find(methodName, requiredParams);
+	public BeanCreateMethodFinder<T> find(String methodName) {
+		return find(x -> x.hasName(methodName));
+	}
+
+	/**
+	 * Identical to {@link #find(Predicate)} but named for fluent-style calls.
+	 *
+	 * @param filter The predicate to apply.
+	 * @return This object.
+	 */
+	public BeanCreateMethodFinder<T> thenFind(Predicate<MethodInfo> filter) {
+		return find(filter);
+	}
+
+	/**
+	 * Identical to {@link #find(Predicate)} but named for fluent-style calls.
+	 *
+	 * @param methodName The method name to match.
+	 * @return This object.
+	 */
+	public BeanCreateMethodFinder<T> thenFind(String methodName) {
+		return find(methodName);
 	}
 
 	/**
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index 0e6fdc2ad..30b2f5c52 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -710,14 +710,14 @@ public class RestContext extends Context {
 			// Replace with builder from:  public [static] VarResolver.Builder createVarResolver(<args>)
 			beanStore
 				.createMethodFinder(VarResolver.Builder.class)
-				.find("createVarResolver")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] VarResolver createVarResolver(<args>)
 			beanStore
 				.createMethodFinder(VarResolver.class)
 				.addBean(VarResolver.Builder.class, v.get())
-				.find("createVarResolver")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -778,7 +778,7 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(VarList.class)
 				.addBean(VarList.class, v.get())
-				.find("createVars")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			return v.get();
@@ -888,7 +888,7 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(Config.class)
 				.addBean(Config.class, v.get())
-				.find("createConfig")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			return v.get();
@@ -986,7 +986,7 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(Logger.class)
 				.addBean(Logger.class, v.get())
-				.find("createLogger")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			return v.get();
@@ -1079,14 +1079,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(ThrownStore.Builder.class)
 				.addBean(ThrownStore.Builder.class, v.get())
-				.find("createThrownStore")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] ThrownStore createThrownStore(<args>)
 			beanStore
 				.createMethodFinder(ThrownStore.class)
 				.addBean(ThrownStore.Builder.class, v.get())
-				.find("createThrownStore")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -1183,14 +1183,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(EncoderSet.Builder.class)
 				.addBean(EncoderSet.Builder.class, v.get())
-				.find("createEncoders")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] EncoderSet createEncoders(<args>)
 			beanStore
 				.createMethodFinder(EncoderSet.class)
 				.addBean(EncoderSet.Builder.class, v.get())
-				.find("createEncoders")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -1265,14 +1265,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(SerializerSet.Builder.class)
 				.addBean(SerializerSet.Builder.class, v.get())
-				.find("createSerializers")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] SerializerSet createSerializers(<args>)
 			beanStore
 				.createMethodFinder(SerializerSet.class)
 				.addBean(SerializerSet.Builder.class, v.get())
-				.find("createSerializers")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -1347,14 +1347,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(ParserSet.Builder.class)
 				.addBean(ParserSet.Builder.class, v.get())
-				.find("createParsers")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] ParserSet createParsers(<args>)
 			beanStore
 				.createMethodFinder(ParserSet.class)
 				.addBean(ParserSet.Builder.class, v.get())
-				.find("createParsers")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -1428,14 +1428,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(MethodExecStore.Builder.class)
 				.addBean(MethodExecStore.Builder.class, v.get())
-				.find("createMethodExecStore")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] MethodExecStore createThrownStore(<args>)
 			beanStore
 				.createMethodFinder(MethodExecStore.class)
 				.addBean(MethodExecStore.Builder.class, v.get())
-				.find("createMethodExecStore")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -1576,14 +1576,14 @@ public class RestContext extends Context {
 			// Replace with builder from:  public [static] Messages.Builder createMessages(<args>)
 			beanStore
 				.createMethodFinder(Messages.Builder.class)
-				.find("createMessages")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] Messages createMessages(<args>)
 			beanStore
 				.createMethodFinder(Messages.class)
 				.addBean(Messages.Builder.class, v.get())
-				.find("createMessages")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -1763,14 +1763,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(ResponseProcessorList.Builder.class)
 				.addBean(ResponseProcessorList.Builder.class, v.get())
-				.find("createResponseProcessors")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] ResponseProcessorList createResponseProcessors(<args>)
 			beanStore
 				.createMethodFinder(ResponseProcessorList.class)
 				.addBean(ResponseProcessorList.Builder.class, v.get())
-				.find("createResponseProcessors")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -1921,7 +1921,7 @@ public class RestContext extends Context {
 			// Replace with bean from:  public [static] CallLogger createCallLogger(<args>)
 			beanStore
 				.createMethodFinder(CallLogger.class)
-				.find("createCallLogger")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> creator.impl(x));
 
 			return creator;
@@ -2015,16 +2015,9 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(BeanContext.Builder.class)
 				.addBean(BeanContext.Builder.class, v.get())
-				.find("createBeanContext")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
-			// Replace with builder from:  public [static] BeanContext createBeanContext(<args>)
-			beanStore
-				.createMethodFinder(BeanContext.class)
-				.addBean(BeanContext.Builder.class, v.get())
-				.find("createBeanContext")
-				.run(x -> v.get().impl(x));
-
 			return v.get();
 		}
 
@@ -2127,14 +2120,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(HttpPartSerializer.Creator.class)
 				.addBean(HttpPartSerializer.Creator.class, v.get())
-				.find("createPartSerializer")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] HttpPartSerializer createPartSerializer(<args>)
 			beanStore
 				.createMethodFinder(HttpPartSerializer.class)
 				.addBean(HttpPartSerializer.Creator.class, v.get())
-				.find("createPartSerializer")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -2239,14 +2232,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(HttpPartParser.Creator.class)
 				.addBean(HttpPartParser.Creator.class, v.get())
-				.find("createPartParser")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] HttpPartParser createPartParser(<args>)
 			beanStore
 				.createMethodFinder(HttpPartParser.class)
 				.addBean(HttpPartParser.Creator.class, v.get())
-				.find("createPartParser")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -2334,14 +2327,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(JsonSchemaGenerator.Builder.class)
 				.addBean(JsonSchemaGenerator.Builder.class, v.get())
-				.find("createJsonSchemaGenerator")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] JsonSchemaGenerator createJsonSchemaGenerator(<args>)
 			beanStore
 				.createMethodFinder(JsonSchemaGenerator.class)
 				.addBean(JsonSchemaGenerator.Builder.class, v.get())
-				.find("createJsonSchemaGenerator")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -2522,7 +2515,7 @@ public class RestContext extends Context {
 			// Replace with bean from:  public [static] FileFinder createFileFinder(<args>)
 			beanStore
 				.createMethodFinder(FileFinder.class)
-				.find("createFileFinder")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> creator.impl(x));
 
 			return creator;
@@ -2675,7 +2668,7 @@ public class RestContext extends Context {
 			// Replace with bean from:  public [static] StaticFiles createStaticFiles(<args>)
 			beanStore
 				.createMethodFinder(StaticFiles.class)
-				.find("createStaticFiles")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> creator.impl(x));
 
 			return creator;
@@ -2834,14 +2827,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(HeaderList.Builder.class)
 				.addBean(HeaderList.Builder.class, v.get())
-				.find("createDefaultRequestHeaders")
+				.find(x -> x.hasAnnotation(RestBean.class) && x.getAnnotation(RestBean.class).name().equals("defaultRequestHeaders"))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] HeaderList createDefaultRequestHeaders(<args>)
 			beanStore
 				.createMethodFinder(HeaderList.class)
 				.addBean(HeaderList.Builder.class, v.get())
-				.find("createDefaultRequestHeaders")
+				.find(x -> x.hasAnnotation(RestBean.class) && x.getAnnotation(RestBean.class).name().equals("defaultRequestHeaders"))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -2966,14 +2959,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(HeaderList.Builder.class)
 				.addBean(HeaderList.Builder.class, v.get())
-				.find("createDefaultResponseHeaders")
+				.find(x -> x.hasAnnotation(RestBean.class) && x.getAnnotation(RestBean.class).name().equals("defaultResponseHeaders"))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] HeaderList createDefaultResponseHeaders(<args>)
 			beanStore
 				.createMethodFinder(HeaderList.class)
 				.addBean(HeaderList.Builder.class, v.get())
-				.find("createDefaultResponseHeaders")
+				.find(x -> x.hasAnnotation(RestBean.class) && x.getAnnotation(RestBean.class).name().equals("defaultResponseHeaders"))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -3094,14 +3087,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(NamedAttributeList.Builder.class)
 				.addBean(NamedAttributeList.Builder.class, v.get())
-				.find("createDefaultRequestAttributes")
+				.find(x -> x.hasAnnotation(RestBean.class) && x.getAnnotation(RestBean.class).name().equals("defaultRequestAttributes"))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] NamedAttributeList createDefaultRequestAttributes(<args>)
 			beanStore
 				.createMethodFinder(NamedAttributeList.class)
 				.addBean(NamedAttributeList.Builder.class, v.get())
-				.find("createDefaultRequestAttributes")
+				.find(x -> x.hasAnnotation(RestBean.class) && x.getAnnotation(RestBean.class).name().equals("defaultRequestAttributes"))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -3286,14 +3279,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(RestOpArgList.Builder.class)
 				.addBean(RestOpArgList.Builder.class, v.get())
-				.find("createRestOpArgs")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] RestOpArgList createRestOpArgs(<args>)
 			beanStore
 				.createMethodFinder(RestOpArgList.class)
 				.addBean(RestOpArgList.Builder.class, v.get())
-				.find("createRestOpArgs")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -3381,7 +3374,7 @@ public class RestContext extends Context {
 			// Replace with bean from:  public [static] DebugEnablement createDebugEnablement(<args>)
 			beanStore
 				.createMethodFinder(DebugEnablement.class)
-				.find("createDebugEnablement")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> creator.impl(x));
 
 			return creator;
@@ -3444,7 +3437,7 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(MethodList.class)
 				.addBean(MethodList.class, v.get())
-				.find("createStartCallMethods")
+				.find(x -> x.hasAnnotation(RestBean.class) && x.getAnnotation(RestBean.class).name().equals("startCallMethods"))
 				.run(x -> v.set(x));
 
 			return v.get();
@@ -3507,7 +3500,7 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(MethodList.class)
 				.addBean(MethodList.class, v.get())
-				.find("createEndCallMethods")
+				.find(x -> x.hasAnnotation(RestBean.class) && x.getAnnotation(RestBean.class).name().equals("endCallMethods"))
 				.run(x -> v.set(x));
 
 			return v.get();
@@ -3570,7 +3563,7 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(MethodList.class)
 				.addBean(MethodList.class, v.get())
-				.find("createPostInitMethods")
+				.find(x -> x.hasAnnotation(RestBean.class) && x.getAnnotation(RestBean.class).name().equals("postInitMethods"))
 				.run(x -> v.set(x));
 
 			return v.get();
@@ -3633,7 +3626,7 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(MethodList.class)
 				.addBean(MethodList.class, v.get())
-				.find("createPostInitChildFirstMethods")
+				.find(x -> x.hasAnnotation(RestBean.class) && x.getAnnotation(RestBean.class).name().equals("postInitChildFirstMethods"))
 				.run(x -> v.set(x));
 
 			return v.get();
@@ -3696,7 +3689,7 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(MethodList.class)
 				.addBean(MethodList.class, v.get())
-				.find("createDestroyMethods")
+				.find(x -> x.hasAnnotation(RestBean.class) && x.getAnnotation(RestBean.class).name().equals("destroyMethods"))
 				.run(x -> v.set(x));
 
 			return v.get();
@@ -3762,7 +3755,7 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(MethodList.class)
 				.addBean(MethodList.class, v.get())
-				.find("createPreCallMethods")
+				.find(x -> x.hasAnnotation(RestBean.class) && x.getAnnotation(RestBean.class).name().equals("preCallMethods"))
 				.run(x -> v.set(x));
 
 			return v.get();
@@ -3828,7 +3821,7 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(MethodList.class)
 				.addBean(MethodList.class, v.get())
-				.find("createPostCallMethods")
+				.find(x -> x.hasAnnotation(RestBean.class) && x.getAnnotation(RestBean.class).name().equals("postCallMethods"))
 				.run(x -> v.set(x));
 
 			return v.get();
@@ -3947,14 +3940,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(RestOperations.Builder.class)
 				.addBean(RestOperations.Builder.class, v.get())
-				.find("createRestOperations")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] RestOperations createRestOperations(<args>)
 			beanStore
 				.createMethodFinder(RestOperations.class)
 				.addBean(RestOperations.Builder.class, v.get())
-				.find("createRestOperations")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -4047,14 +4040,14 @@ public class RestContext extends Context {
 			beanStore
 				.createMethodFinder(RestChildren.Builder.class)
 				.addBean(RestChildren.Builder.class, v.get())
-				.find("createRestChildren")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] RestChildren createRestChildren(<args>)
 			beanStore
 				.createMethodFinder(RestChildren.class)
 				.addBean(RestChildren.Builder.class, v.get())
-				.find("createRestChildren")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -4143,7 +4136,7 @@ public class RestContext extends Context {
 			// Replace with bean from:  public [static] SwaggerProvider createSwaggerProvider(<args>)
 			beanStore
 				.createMethodFinder(SwaggerProvider.class)
-				.find("createSwaggerProvider")
+				.find(x -> x.hasAnnotation(RestBean.class))
 				.run(x -> creator.impl(x));
 
 			return creator;
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
index b301c738a..d4072bce8 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
@@ -308,14 +308,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 				.of(beanStore, resource)
 				.addBean(BeanContext.Builder.class, v.get())
 				.createMethodFinder(BeanContext.Builder.class, resource)
-				.find("createBeanContext", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.set(x));
 
 			BeanStore
 				.of(beanStore, resource)
 				.addBean(BeanContext.Builder.class, v.get())
 				.createMethodFinder(BeanContext.class, resource)
-				.find("createBeanContext", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -384,14 +384,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 				.of(beanStore, resource)
 				.addBean(EncoderSet.Builder.class, v.get())
 				.createMethodFinder(EncoderSet.Builder.class, resource)
-				.find("createEncoders", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.set(x));
 
 			BeanStore
 				.of(beanStore, resource)
 				.addBean(EncoderSet.Builder.class, v.get())
 				.createMethodFinder(EncoderSet.class, resource)
-				.find("createEncoders", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -460,14 +460,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 				.of(beanStore, resource)
 				.addBean(SerializerSet.Builder.class, v.get())
 				.createMethodFinder(SerializerSet.Builder.class, resource)
-				.find("createSerializers", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.set(x));
 
 			BeanStore
 				.of(beanStore, resource)
 				.addBean(SerializerSet.Builder.class, v.get())
 				.createMethodFinder(SerializerSet.class, resource)
-				.find("createSerializers", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -536,14 +536,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 				.of(beanStore, resource)
 				.addBean(ParserSet.Builder.class, v.get())
 				.createMethodFinder(ParserSet.Builder.class, resource)
-				.find("createParsers", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.set(x));
 
 			BeanStore
 				.of(beanStore, resource)
 				.addBean(ParserSet.Builder.class, v.get())
 				.createMethodFinder(ParserSet.class, resource)
-				.find("createParsers", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -612,14 +612,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 				.of(beanStore, resource)
 				.addBean(HttpPartSerializer.Creator.class, v.get())
 				.createMethodFinder(HttpPartSerializer.Creator.class, resource)
-				.find("createPartSerializer", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.set(x));
 
 			BeanStore
 				.of(beanStore, resource)
 				.addBean(HttpPartSerializer.Creator.class, v.get())
 				.createMethodFinder(HttpPartSerializer.class, resource)
-				.find("createPartSerializer", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -688,14 +688,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 				.of(beanStore, resource)
 				.addBean(HttpPartParser.Creator.class, v.get())
 				.createMethodFinder(HttpPartParser.Creator.class, resource)
-				.find("createPartParser", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.set(x));
 
 			BeanStore
 				.of(beanStore, resource)
 				.addBean(HttpPartParser.Creator.class, v.get())
 				.createMethodFinder(HttpPartParser.class, resource)
-				.find("createPartParser", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -764,14 +764,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 				.of(beanStore, resource)
 				.addBean(JsonSchemaGenerator.Builder.class, v.get())
 				.createMethodFinder(JsonSchemaGenerator.Builder.class, resource)
-				.find("createJsonSchemaGenerator", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.set(x));
 
 			BeanStore
 				.of(beanStore, resource)
 				.addBean(JsonSchemaGenerator.Builder.class, v.get())
 				.createMethodFinder(JsonSchemaGenerator.class, resource)
-				.find("createJsonSchemaGenerator", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -917,14 +917,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 			beanStore
 				.createMethodFinder(RestConverterList.Builder.class)
 				.addBean(RestConverterList.Builder.class, v.get())
-				.find("createConverters")
+				.find(x -> matches(x))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] RestConverterList createConverters(<args>)
 			beanStore
 				.createMethodFinder(RestConverterList.class)
 				.addBean(RestConverterList.Builder.class, v.get())
-				.find("createConverters")
+				.find(x -> matches(x))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -1019,14 +1019,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 			beanStore
 				.createMethodFinder(RestGuardList.Builder.class)
 				.addBean(RestGuardList.Builder.class, v.get())
-				.find("createGuards")
+				.find(x -> matches(x))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] RestGuardList createGuards(<args>)
 			beanStore
 				.createMethodFinder(RestGuardList.class)
 				.addBean(RestGuardList.Builder.class, v.get())
-				.find("createGuards")
+				.find(x -> matches(x))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -1162,14 +1162,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 			beanStore
 				.createMethodFinder(RestMatcherList.Builder.class)
 				.addBean(RestMatcherList.Builder.class, v.get())
-				.find("createMatchers")
+				.find(x -> matches(x))
 				.run(x -> v.set(x));
 
 			// Replace with bean from:  public [static] RestMatcherList createMatchers(<args>)
 			beanStore
 				.createMethodFinder(RestMatcherList.class)
 				.addBean(RestMatcherList.Builder.class, v.get())
-				.find("createMatchers")
+				.find(x -> matches(x))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -1235,7 +1235,7 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 			beanStore
 				.createMethodFinder(UrlPathMatcherList.class, resource().get())
 				.addBean(UrlPathMatcherList.class, v.get())
-				.find("createPathMatchers", Method.class)
+				.find(x -> matches(x))
 				.run(x -> v.set(x));
 
 			return v.get();
@@ -1309,14 +1309,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 				.of(beanStore, resource)
 				.addBean(HeaderList.Builder.class, v.get())
 				.createMethodFinder(HeaderList.Builder.class, resource)
-				.find("createDefaultRequestHeaders", Method.class)
+				.find(x -> matches(x, "defaultRequestHeaders"))
 				.run(x -> v.set(x));
 
 			BeanStore
 				.of(beanStore, resource)
 				.addBean(HeaderList.Builder.class, v.get())
 				.createMethodFinder(HeaderList.class, resource)
-				.find("createDefaultRequestHeaders", Method.class)
+				.find(x -> matches(x, "defaultRequestHeaders"))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -1380,14 +1380,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 				.of(beanStore, resource)
 				.addBean(HeaderList.Builder.class, v.get())
 				.createMethodFinder(HeaderList.Builder.class, resource)
-				.find("createDefaultResponseHeaders", Method.class)
+				.find(x -> matches(x, "defaultResponseHeaders"))
 				.run(x -> v.set(x));
 
 			BeanStore
 				.of(beanStore, resource)
 				.addBean(HeaderList.Builder.class, v.get())
 				.createMethodFinder(HeaderList.class, resource)
-				.find("createDefaultResponseHeaders", Method.class)
+				.find(x -> matches(x, "defaultResponseHeaders"))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -1451,14 +1451,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 				.of(beanStore, resource)
 				.addBean(NamedAttributeList.Builder.class, v.get())
 				.createMethodFinder(NamedAttributeList.Builder.class, resource)
-				.find("createDefaultRequestAttributes", Method.class)
+				.find(x -> matches(x, "defaultRequestAttributes"))
 				.run(x -> v.set(x));
 
 			BeanStore
 				.of(beanStore, resource)
 				.addBean(NamedAttributeList.Builder.class, v.get())
 				.createMethodFinder(NamedAttributeList.class, resource)
-				.find("createDefaultRequestAttributes", Method.class)
+				.find(x -> matches(x, "defaultRequestAttributes"))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -1522,16 +1522,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 				.of(beanStore, resource)
 				.addBean(PartList.Builder.class, v.get())
 				.createMethodFinder(PartList.Builder.class, resource)
-				.find("createDefaultRequestQueryData", Method.class)
-				.thenFind("createDefaultRequestQueryData")
+				.find(x -> matches(x, "defaultRequestQueryData"))
 				.run(x -> v.set(x));
 
 			BeanStore
 				.of(beanStore, resource)
 				.addBean(PartList.Builder.class, v.get())
 				.createMethodFinder(PartList.class, resource)
-				.find("createDefaultRequestQueryData", Method.class)
-				.thenFind("createDefaultRequestQueryData")
+				.find(x -> matches(x, "defaultRequestQueryData"))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -1595,16 +1593,14 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 				.of(beanStore, resource)
 				.addBean(PartList.Builder.class, v.get())
 				.createMethodFinder(PartList.Builder.class, resource)
-				.find("createDefaultRequestFormData", Method.class)
-				.thenFind("createDefaultRequestFormData")
+				.find(x -> matches(x, "defaultRequestFormData"))
 				.run(x -> v.set(x));
 
 			BeanStore
 				.of(beanStore, resource)
 				.addBean(PartList.Builder.class, v.get())
 				.createMethodFinder(PartList.class, resource)
-				.find("createDefaultRequestFormData", Method.class)
-				.thenFind("createDefaultRequestFormData")
+				.find(x -> matches(x, "defaultRequestFormData"))
 				.run(x -> v.get().impl(x));
 
 			return v.get();
@@ -2174,6 +2170,34 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		// Helper methods.
 		//-----------------------------------------------------------------------------------------------------------------
 
+		private boolean matches(MethodInfo annotated) {
+			RestMethodBean a = annotated.getAnnotation(RestMethodBean.class);
+			if (a != null) {
+				for (String n : a.method()) {
+					if ("*".equals(n))
+						return true;
+					if (restMethod.getName().equals(n))
+						return true;
+				}
+			}
+			return false;
+		}
+
+		private boolean matches(MethodInfo annotated, String beanName) {
+			RestMethodBean a = annotated.getAnnotation(RestMethodBean.class);
+			if (a != null) {
+				if (! a.name().equals(beanName))
+					return false;
+				for (String n : a.method()) {
+					if ("*".equals(n))
+						return true;
+					if (restMethod.getName().equals(n))
+						return true;
+				}
+			}
+			return false;
+		}
+
 		private String joinnlFirstNonEmptyArray(String[]...s) {
 			for (String[] ss : s)
 				if (ss.length > 0)
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestBean.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestBean.java
new file mode 100644
index 000000000..6fec8b199
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestBean.java
@@ -0,0 +1,34 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.rest.annotation;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.lang.annotation.*;
+
+/**
+ * TODO
+ */
+@Target({METHOD})
+@Retention(RUNTIME)
+@Inherited
+public @interface RestBean {
+
+	/**
+	 * The bean name to use to distinguish beans of the same type for different purposes.
+	 *
+	 * @return The bean name to use to distinguish beans of the same type for different purposes.
+	 */
+	String name() default "";
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodBean.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodBean.java
new file mode 100644
index 000000000..fe9c505af
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestMethodBean.java
@@ -0,0 +1,44 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.rest.annotation;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.lang.annotation.*;
+
+/**
+ * TODO
+ */
+@Target({METHOD})
+@Retention(RUNTIME)
+@Inherited
+public @interface RestMethodBean {
+
+	/**
+	 * The short names of the methods that this annotation applies to.
+	 * 
+	 * <p>
+	 * Can use <js>"*"</js> to apply to all methods.
+	 *
+	 * @return The short names of the methods that this annotation applies to.
+	 */
+	String[] method() default {};
+
+	/**
+	 * The bean name to use to distinguish beans of the same type for different purposes.
+	 *
+	 * @return The bean name to use to distinguish beans of the same type for different purposes.
+	 */
+	String name() default "";
+}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/cp/BeanStore_Test.java b/juneau-utest/src/test/java/org/apache/juneau/cp/BeanStore_Test.java
index 60a8c9e7c..ae278522f 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/cp/BeanStore_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/cp/BeanStore_Test.java
@@ -726,14 +726,14 @@ public class BeanStore_Test {
 		b1p.add(A1.class, null);
 		assertString(b1c.createMethodFinder(String.class).find("createC1").thenFind("createC2").run()).is("createC1");
 		assertString(b1c.createMethodFinder(String.class).find("createC2").thenFind("createC1").run()).is("createC2");
-		assertString(b1c.createMethodFinder(String.class).find("createC1", A1.class).thenFind("createC2", A1.class).run()).is("createC1");
-		assertString(b1c.createMethodFinder(String.class).find("createC2", A1.class).thenFind("createC1", A1.class).run()).is("createC1");
+		assertString(b1c.createMethodFinder(String.class).find(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).run()).is("createC1");
+		assertString(b1c.createMethodFinder(String.class).find(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).run()).is("createC1");
 
 		b1p.clear();
 		assertString(b1c.createMethodFinder(String.class).addBean(A1.class, null).find("createC1").thenFind("createC2").run()).is("createC1");
 		assertString(b1c.createMethodFinder(String.class).addBean(A1.class, null).find("createC2").thenFind("createC1").run()).is("createC2");
-		assertString(b1c.createMethodFinder(String.class).addBean(A1.class, null).find("createC1", A1.class).thenFind("createC2", A1.class).run()).is("createC1");
-		assertString(b1c.createMethodFinder(String.class).addBean(A1.class, null).find("createC2", A1.class).thenFind("createC1", A1.class).run()).is("createC1");
+		assertString(b1c.createMethodFinder(String.class).addBean(A1.class, null).find(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).run()).is("createC1");
+		assertString(b1c.createMethodFinder(String.class).addBean(A1.class, null).find(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).run()).is("createC1");
 
 		assertString(b1c.createMethodFinder(String.class).withDefault("X").run()).is("X");
 		assertString(b1c.createMethodFinder(String.class).withDefault(()->"X").run()).is("X");
@@ -759,14 +759,14 @@ public class BeanStore_Test {
 		b1p.add(A1.class, null);
 		assertString(b1c.createMethodFinder(String.class).find("createC1").thenFind("createC2").run()).is("createC1");
 		assertString(b1c.createMethodFinder(String.class).find("createC2").thenFind("createC1").run()).is("createC2");
-		assertString(b1c.createMethodFinder(String.class).find("createC1", A1.class).thenFind("createC2", A1.class).run()).is("createC1");
-		assertString(b1c.createMethodFinder(String.class).find("createC2", A1.class).thenFind("createC1", A1.class).run()).is("createC1");
+		assertString(b1c.createMethodFinder(String.class).find(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).run()).is("createC1");
+		assertString(b1c.createMethodFinder(String.class).find(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).run()).is("createC1");
 
 		b1p.clear();
 		assertString(b1c.createMethodFinder(String.class).addBean(A1.class, null).find("createC1").thenFind("createC2").run()).is("createC1");
 		assertString(b1c.createMethodFinder(String.class).addBean(A1.class, null).find("createC2").thenFind("createC1").run()).is("createC2");
-		assertString(b1c.createMethodFinder(String.class).addBean(A1.class, null).find("createC1", A1.class).thenFind("createC2", A1.class).run()).is("createC1");
-		assertString(b1c.createMethodFinder(String.class).addBean(A1.class, null).find("createC2", A1.class).thenFind("createC1", A1.class).run()).is("createC1");
+		assertString(b1c.createMethodFinder(String.class).addBean(A1.class, null).find(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).run()).is("createC1");
+		assertString(b1c.createMethodFinder(String.class).addBean(A1.class, null).find(x2->x2.hasName("createC2") && x2.hasAllArgs(A1.class)).thenFind(x2->x2.hasName("createC1") && x2.hasAllArgs(A1.class)).run()).is("createC1");
 
 		assertString(b1c.createMethodFinder(String.class).withDefault("X").run()).is("X");
 		assertString(b1c.createMethodFinder(String.class).withDefault(()->"X").run()).is("X");