Polishing
This commit is contained in:
parent
ea3250c8d6
commit
5e7a8b275d
|
@ -47,6 +47,7 @@ import org.springframework.core.ResolvableType;
|
|||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.annotation.SynthesizingMethodParameter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.objenesis.ObjenesisException;
|
||||
import org.springframework.objenesis.SpringObjenesis;
|
||||
import org.springframework.util.Assert;
|
||||
|
@ -120,6 +121,7 @@ import static java.util.stream.Collectors.*;
|
|||
* </pre>
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 5.0
|
||||
*/
|
||||
public class ResolvableMethod {
|
||||
|
||||
|
@ -133,7 +135,7 @@ public class ResolvableMethod {
|
|||
|
||||
|
||||
private ResolvableMethod(Method method) {
|
||||
Assert.notNull(method, "method is required");
|
||||
Assert.notNull(method, "Method is required");
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
|
@ -202,14 +204,14 @@ public class ResolvableMethod {
|
|||
return new ArgResolver().annotNotPresent(annotationTypes);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ResolvableMethod=" + formatMethod();
|
||||
}
|
||||
|
||||
|
||||
private String formatMethod() {
|
||||
return (this.method().getName() +
|
||||
return (method().getName() +
|
||||
Arrays.stream(this.method.getParameters())
|
||||
.map(this::formatParameter)
|
||||
.collect(joining(",\n\t", "(\n\t", "\n)")));
|
||||
|
@ -262,13 +264,11 @@ public class ResolvableMethod {
|
|||
|
||||
private final List<Predicate<Method>> filters = new ArrayList<>(4);
|
||||
|
||||
|
||||
private Builder(Class<?> objectClass) {
|
||||
Assert.notNull(objectClass, "Class must not be null");
|
||||
this.objectClass = objectClass;
|
||||
}
|
||||
|
||||
|
||||
private void addFilter(String message, Predicate<Method> filter) {
|
||||
this.filters.add(new LabeledPredicate<>(message, filter));
|
||||
}
|
||||
|
@ -394,7 +394,6 @@ public class ResolvableMethod {
|
|||
return new ResolvableMethod(method);
|
||||
}
|
||||
|
||||
|
||||
// Build & resolve shortcuts...
|
||||
|
||||
/**
|
||||
|
@ -448,7 +447,6 @@ public class ResolvableMethod {
|
|||
return returning(returnType).build().returnType();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ResolvableMethod.Builder[\n" +
|
||||
|
@ -462,6 +460,7 @@ public class ResolvableMethod {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Predicate with a descriptive label.
|
||||
*/
|
||||
|
@ -471,7 +470,6 @@ public class ResolvableMethod {
|
|||
|
||||
private final Predicate<T> delegate;
|
||||
|
||||
|
||||
private LabeledPredicate(String label, Predicate<T> delegate) {
|
||||
this.label = label;
|
||||
this.delegate = delegate;
|
||||
|
@ -504,6 +502,7 @@ public class ResolvableMethod {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resolver for method arguments.
|
||||
*/
|
||||
|
@ -511,7 +510,6 @@ public class ResolvableMethod {
|
|||
|
||||
private final List<Predicate<MethodParameter>> filters = new ArrayList<>(4);
|
||||
|
||||
|
||||
@SafeVarargs
|
||||
private ArgResolver(Predicate<MethodParameter>... filter) {
|
||||
this.filters.addAll(Arrays.asList(filter));
|
||||
|
@ -603,17 +601,18 @@ public class ResolvableMethod {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class MethodInvocationInterceptor
|
||||
implements org.springframework.cglib.proxy.MethodInterceptor, MethodInterceptor {
|
||||
|
||||
private Method invokedMethod;
|
||||
|
||||
|
||||
Method getInvokedMethod() {
|
||||
return this.invokedMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) {
|
||||
if (ReflectionUtils.isObjectMethod(method)) {
|
||||
return ReflectionUtils.invokeMethod(method, object, args);
|
||||
|
@ -625,6 +624,7 @@ public class ResolvableMethod {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(org.aopalliance.intercept.MethodInvocation inv) throws Throwable {
|
||||
return intercept(inv.getThis(), inv.getMethod(), inv.getArguments(), null);
|
||||
}
|
||||
|
|
|
@ -3054,41 +3054,41 @@ container and once through the aspect.
|
|||
[[aop-configurable-testing]]
|
||||
==== Unit Testing `@Configurable` Objects
|
||||
|
||||
One of the goals of the `@Configurable` support is to enable independent unit testing of
|
||||
domain objects without the difficulties associated with hard-coded lookups. If
|
||||
`@Configurable` types have not been woven by AspectJ, the annotation has no affect
|
||||
during unit testing. You can set mock or stub property references in the
|
||||
object under test and proceed as normal. If `@Configurable` types have been woven by
|
||||
AspectJ, you can still unit test outside of the container as normal, but you
|
||||
see a warning message each time that you construct an `@Configurable` object indicating
|
||||
that it has not been configured by Spring.
|
||||
One of the goals of the `@Configurable` support is to enable independent unit testing
|
||||
of domain objects without the difficulties associated with hard-coded lookups.
|
||||
If `@Configurable` types have not been woven by AspectJ, the annotation has no affect
|
||||
during unit testing. You can set mock or stub property references in the object under
|
||||
test and proceed as normal. If `@Configurable` types have been woven by AspectJ,
|
||||
you can still unit test outside of the container as normal, but you see a warning
|
||||
message each time that you construct a `@Configurable` object indicating that it has
|
||||
not been configured by Spring.
|
||||
|
||||
|
||||
[[aop-configurable-container]]
|
||||
==== Working with Multiple Application Contexts
|
||||
|
||||
The `AnnotationBeanConfigurerAspect` that is used to implement the `@Configurable` support is an
|
||||
AspectJ singleton aspect. The scope of a singleton aspect is the same as the scope of
|
||||
`static` members: There is one aspect instance per classloader that
|
||||
defines the type. This means that, if you define multiple application contexts within the
|
||||
same classloader hierarchy, you need to consider where to define the
|
||||
`@EnableSpringConfigured` bean and where to place `spring-aspects.jar` on the classpath.
|
||||
The `AnnotationBeanConfigurerAspect` that is used to implement the `@Configurable` support
|
||||
is an AspectJ singleton aspect. The scope of a singleton aspect is the same as the scope
|
||||
of `static` members: There is one aspect instance per classloader that defines the type.
|
||||
This means that, if you define multiple application contexts within the same classloader
|
||||
hierarchy, you need to consider where to define the `@EnableSpringConfigured` bean and
|
||||
where to place `spring-aspects.jar` on the classpath.
|
||||
|
||||
Consider a typical Spring web application configuration that has a shared parent application context
|
||||
that defines common business services, everything needed to support those services, and one child
|
||||
application context for each servlet (which contains definitions particular to that servlet). All
|
||||
of these contexts co-exist within the same classloader hierarchy, and so the
|
||||
`AnnotationBeanConfigurerAspect` can hold a reference to only one of them. In this case,
|
||||
we recommend defining the `@EnableSpringConfigured` bean in the shared (parent)
|
||||
application context. This defines the services that you are likely to want to inject
|
||||
into domain objects. A consequence is that you cannot configure domain objects with
|
||||
references to beans defined in the child (servlet-specific) contexts by using the
|
||||
Consider a typical Spring web application configuration that has a shared parent application
|
||||
context that defines common business services, everything needed to support those services,
|
||||
and one child application context for each servlet (which contains definitions particular
|
||||
to that servlet). All of these contexts co-exist within the same classloader hierarchy,
|
||||
and so the `AnnotationBeanConfigurerAspect` can hold a reference to only one of them.
|
||||
In this case, we recommend defining the `@EnableSpringConfigured` bean in the shared
|
||||
(parent) application context. This defines the services that you are likely to want to
|
||||
inject into domain objects. A consequence is that you cannot configure domain objects
|
||||
with references to beans defined in the child (servlet-specific) contexts by using the
|
||||
@Configurable mechanism (which is probably not something you want to do anyway).
|
||||
|
||||
When deploying multiple web applications within the same container, ensure that each
|
||||
web application loads the types in `spring-aspects.jar` by using its own classloader (for
|
||||
example, by placing `spring-aspects.jar` in `'WEB-INF/lib'`). If `spring-aspects.jar` is
|
||||
added only to the container-wide classpath (and hence loaded by the shared parent
|
||||
web application loads the types in `spring-aspects.jar` by using its own classloader
|
||||
(for example, by placing `spring-aspects.jar` in `'WEB-INF/lib'`). If `spring-aspects.jar`
|
||||
is added only to the container-wide classpath (and hence loaded by the shared parent
|
||||
classloader), all web applications share the same aspect instance (which is probably
|
||||
not what you want).
|
||||
|
||||
|
|
|
@ -3266,7 +3266,7 @@ response body through message conversion (versus view resolution or template ren
|
|||
|
||||
On startup, the infrastructure classes for `@RequestMapping` and `@ExceptionHandler` methods
|
||||
detect Spring beans of type `@ControllerAdvice` and then apply their methods at runtime.
|
||||
Global `@ExceptionHandler` methods (from an `@ControllerAdvice`) are applied _after_ local
|
||||
Global `@ExceptionHandler` methods (from a `@ControllerAdvice`) are applied _after_ local
|
||||
ones (from the `@Controller`). By contrast, global `@ModelAttribute` and `@InitBinder`
|
||||
methods are applied _before_ local ones.
|
||||
|
||||
|
|
Loading…
Reference in New Issue