Polishing

This commit is contained in:
Juergen Hoeller
2020-09-14 23:46:49 +02:00
parent bb5b12af3b
commit 7056dd599f
5 changed files with 56 additions and 18 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,9 +30,9 @@ import org.springframework.core.convert.converter.Converter;
*/
final class StringToBooleanConverter implements Converter<String, Boolean> {
private static final Set<String> trueValues = new HashSet<String>(4);
private static final Set<String> trueValues = new HashSet<String>(8);
private static final Set<String> falseValues = new HashSet<String>(4);
private static final Set<String> falseValues = new HashSet<String>(8);
static {
trueValues.add("true");
@@ -46,10 +46,11 @@ final class StringToBooleanConverter implements Converter<String, Boolean> {
falseValues.add("0");
}
@Override
public Boolean convert(String source) {
String value = source.trim();
if ("".equals(value)) {
if (value.isEmpty()) {
return null;
}
value = value.toLowerCase();

View File

@@ -715,8 +715,8 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
return;
}
Assert.notNull(name, "'name' must not be null");
String encodedFileName = encodeHeaderFieldParam(filename, charset);
set(CONTENT_DISPOSITION, "form-data; name=\"" + name + '\"' + "; filename*=" + encodedFileName);
String encodedFilename = encodeHeaderFieldParam(filename, charset);
set(CONTENT_DISPOSITION, "form-data; name=\"" + name + '\"' + "; filename*=" + encodedFilename);
}
/**

View File

@@ -2,8 +2,11 @@
= Spring AOP APIs
[[aop-api-introduction]]
== Introduction
The previous chapter described the Spring's support for AOP using
@AspectJ and schema-based aspect definitions. In this chapter we discuss the lower-level
Spring AOP APIs and the AOP support used in Spring 1.2 applications. For new
@@ -18,12 +21,14 @@ in Spring 4.0.
[[aop-api-pointcuts]]
== Pointcut API in Spring
Let's look at how Spring handles the crucial pointcut concept.
[[aop-api-concepts]]
=== Concepts
Spring's pointcut model enables pointcut reuse independent of advice types. It's
possible to target different advice using the same pointcut.
@@ -88,7 +93,6 @@ In this case, the 3-argument matches method will never be invoked.
[TIP]
====
If possible, try to make pointcuts static, allowing the AOP framework to cache the
results of pointcut evaluation when an AOP proxy is created.
====
@@ -97,6 +101,7 @@ results of pointcut evaluation when an AOP proxy is created.
[[aop-api-pointcut-ops]]
=== Operations on pointcuts
Spring supports operations on pointcuts: notably, __union__ and __intersection__.
* Union means the methods that either pointcut matches.
@@ -111,6 +116,7 @@ Spring supports operations on pointcuts: notably, __union__ and __intersection__
[[aop-api-pointcuts-aspectj]]
=== AspectJ expression pointcuts
Since 2.0, the most important type of pointcut used by Spring is
`org.springframework.aop.aspectj.AspectJExpressionPointcut`. This is a pointcut that
uses an AspectJ supplied library to parse an AspectJ pointcut expression string.
@@ -121,12 +127,14 @@ See the previous chapter for a discussion of supported AspectJ pointcut primitiv
[[aop-api-pointcuts-impls]]
=== Convenience pointcut implementations
Spring provides several convenient pointcut implementations. Some can be used out of the
box; others are intended to be subclassed in application-specific pointcuts.
[[aop-api-pointcuts-static]]
==== Static pointcuts
Static pointcuts are based on method and target class, and cannot take into account the
method's arguments. Static pointcuts are sufficient - __and best__ - for most usages.
It's possible for Spring to evaluate a static pointcut only once, when a method is first
@@ -137,14 +145,15 @@ Let's consider some static pointcut implementations included with Spring.
[[aop-api-pointcuts-regex]]
===== Regular expression pointcuts
One obvious way to specify static pointcuts is regular expressions. Several AOP
frameworks besides Spring make this possible.
`org.springframework.aop.support.JdkRegexpMethodPointcut` is a generic regular
expression pointcut, using the regular expression support in JDK 1.4+.
expression pointcut that uses the regular expression support in the JDK.
Using the `JdkRegexpMethodPointcut` class, you can provide a list of pattern Strings. If
any of these is a match, the pointcut will evaluate to true. (So the result is
effectively the union of these pointcuts.)
With the `JdkRegexpMethodPointcut` class, you can provide a list of pattern strings.
If any of these is a match, the pointcut evaluates to `true`. (As a consequence,
the resulting pointcut is effectively the union of the specified patterns.)
The usage is shown below:
@@ -189,12 +198,14 @@ __RegexpMethodPointcutAdvisor__ can be used with any Advice type.
[[aop-api-pointcuts-attribute-driven]]
===== Attribute-driven pointcuts
An important type of static pointcut is a __metadata-driven__ pointcut. This uses the
values of metadata attributes: typically, source-level metadata.
[[aop-api-pointcuts-dynamic]]
==== Dynamic pointcuts
Dynamic pointcuts are costlier to evaluate than static pointcuts. They take into account
method __arguments__, as well as static information. This means that they must be
evaluated with every method invocation; the result cannot be cached, as arguments will
@@ -204,12 +215,14 @@ The main example is the `control flow` pointcut.
[[aop-api-pointcuts-cflow]]
===== Control flow pointcuts
Spring control flow pointcuts are conceptually similar to AspectJ __cflow__ pointcuts,
although less powerful. (There is currently no way to specify that a pointcut executes
below a join point matched by another pointcut.) A control flow pointcut matches the
current call stack. For example, it might fire if the join point was invoked by a method
in the `com.mycompany.web` package, or by the `SomeCaller` class. Control flow pointcuts
are specified using the `org.springframework.aop.support.ControlFlowPointcut` class.
[NOTE]
====
Control flow pointcuts are significantly more expensive to evaluate at runtime than even
@@ -221,6 +234,7 @@ pointcuts.
[[aop-api-pointcuts-superclasses]]
=== Pointcut superclasses
Spring provides useful pointcut superclasses to help you to implement your own pointcuts.
Because static pointcuts are most useful, you'll probably subclass
@@ -246,6 +260,7 @@ You can use custom pointcuts with any advice type in Spring 1.0 RC2 and above.
[[aop-api-pointcuts-custom]]
=== Custom pointcuts
Because pointcuts in Spring AOP are Java classes, rather than language features (as in
AspectJ) it's possible to declare custom pointcuts, whether static or dynamic. Custom
pointcuts in Spring can be arbitrarily complex. However, using the AspectJ pointcut
@@ -262,12 +277,14 @@ for example, "all methods that change instance variables in the target object."
[[aop-api-advice]]
== Advice API in Spring
Let's now look at how Spring AOP handles advice.
[[aop-api-advice-lifecycle]]
=== Advice lifecycles
Each advice is a Spring bean. An advice instance can be shared across all advised
objects, or unique to each advised object. This corresponds to __per-class__ or
__per-instance__ advice.
@@ -285,12 +302,14 @@ It's possible to use a mix of shared and per-instance advice in the same AOP pro
[[aop-api-advice-types]]
=== Advice types in Spring
Spring provides several advice types out of the box, and is extensible to support
arbitrary advice types. Let us look at the basic concepts and standard advice types.
[[aop-api-advice-around]]
==== Interception around advice
The most fundamental advice type in Spring is __interception around advice__.
Spring is compliant with the AOP Alliance interface for around advice using method
@@ -347,6 +366,7 @@ currently define pointcut interfaces.
[[aop-api-advice-before]]
==== Before advice
A simpler advice type is a __before advice__. This does not need a `MethodInvocation`
object, since it will only be called before entering the method.
@@ -395,13 +415,13 @@ An example of a before advice in Spring, which counts all method invocations:
[TIP]
====
Before advice can be used with any pointcut.
====
[[aop-api-advice-throws]]
==== Throws advice
__Throws advice__ is invoked after the return of the join point if the join point threw
an exception. Spring offers typed throws advice. Note that this means that the
`org.springframework.aop.ThrowsAdvice` interface does not contain any methods: It is a
@@ -478,13 +498,13 @@ exception that is incompatible with the target method's signature!__
[TIP]
====
Throws advice can be used with any pointcut.
====
[[aop-api-advice-after-returning]]
==== After Returning advice
An after returning advice in Spring must implement the
__org.springframework.aop.AfterReturningAdvice__ interface, shown below:
@@ -527,13 +547,13 @@ thrown up the interceptor chain instead of the return value.
[TIP]
====
After returning advice can be used with any pointcut.
====
[[aop-api-advice-introduction]]
==== Introduction advice
Spring treats introduction advice as a special kind of interception advice.
Introduction requires an `IntroductionAdvisor`, and an `IntroductionInterceptor`,
@@ -696,6 +716,7 @@ and stateful mixins.
[[aop-api-advisor]]
== Advisor API in Spring
In Spring, an Advisor is an aspect that contains just a single advice object associated
with a pointcut expression.
@@ -714,6 +735,7 @@ chain.
[[aop-pfb]]
== Using the ProxyFactoryBean to create AOP proxies
If you're using the Spring IoC container (an ApplicationContext or BeanFactory) for your
business objects - and you should be! - you will want to use one of Spring's AOP
FactoryBeans. (Remember that a factory bean introduces a layer of indirection, enabling
@@ -733,6 +755,7 @@ options that are preferable if you don't need such control.
[[aop-pfb-1]]
=== Basics
The `ProxyFactoryBean`, like other Spring `FactoryBean` implementations, introduces a
level of indirection. If you define a `ProxyFactoryBean` with name `foo`, what objects
referencing `foo` see is not the `ProxyFactoryBean` instance itself, but an object
@@ -750,6 +773,7 @@ framework), benefiting from all the pluggability provided by Dependency Injectio
[[aop-pfb-2]]
=== JavaBean properties
In common with most `FactoryBean` implementations provided with Spring, the
`ProxyFactoryBean` class is itself a JavaBean. Its properties are used to:
@@ -803,6 +827,7 @@ to be applied. An example of using this feature can be found in <<aop-global-adv
[[aop-pfb-proxy-types]]
=== JDK- and CGLIB-based proxies
This section serves as the definitive documentation on how the `ProxyFactoryBean`
chooses to create one of either a JDK- and CGLIB-based proxy for a particular target
object (that is to be proxied).
@@ -855,6 +880,7 @@ it is significantly less work, and less prone to typos.
[[aop-api-proxying-intf]]
=== Proxying interfaces
Let's look at a simple example of `ProxyFactoryBean` in action. This example involves:
* A __target bean__ that will be proxied. This is the "personTarget" bean definition in
@@ -972,6 +998,7 @@ factory might actually be an __advantage__: for example, in certain test scenari
[[aop-api-proxying-class]]
=== Proxying classes
What if you need to proxy a class, rather than one or more interfaces?
Imagine that in our example above, there was no `Person` interface: we needed to advise
@@ -1006,6 +1033,7 @@ Performance should not be a decisive consideration in this case.
[[aop-global-advisors]]
=== Using 'global' advisors
By appending an asterisk to an interceptor name, all advisors with bean names matching
the part before the asterisk, will be added to the advisor chain. This can come in handy
if you need to add a standard set of 'global' advisors:
@@ -1031,6 +1059,7 @@ if you need to add a standard set of 'global' advisors:
[[aop-concise-proxy]]
== Concise proxy definitions
Especially when defining transactional proxies, you may end up with many similar proxy
definitions. The use of parent and child bean definitions, along with inner bean
definitions, can result in much cleaner and more concise proxy definitions.
@@ -1103,6 +1132,7 @@ pre-instantiate it.
[[aop-prog]]
== Creating AOP proxies programmatically with the ProxyFactory
It's easy to create AOP proxies programmatically using Spring. This enables you to use
Spring AOP without dependency on Spring IoC.
@@ -1135,7 +1165,6 @@ AdvisedSupport is the superclass of both ProxyFactory and ProxyFactoryBean.
[TIP]
====
Integrating AOP proxy creation with the IoC framework is best practice in most
applications. We recommend that you externalize configuration from Java code with AOP,
as in general.
@@ -1146,6 +1175,7 @@ as in general.
[[aop-api-advised]]
== Manipulating advised objects
However you create AOP proxies, you can manipulate them using the
`org.springframework.aop.framework.Advised` interface. Any AOP proxy can be cast to this
interface, whichever other interfaces it implements. This interface includes the
@@ -1238,6 +1268,7 @@ required.
[[aop-autoproxy]]
== Using the "auto-proxy" facility
So far we've considered explicit creation of AOP proxies using a `ProxyFactoryBean` or
similar factory bean.
@@ -1259,12 +1290,14 @@ There are two ways to do this:
[[aop-autoproxy-choices]]
=== Autoproxy bean definitions
The `org.springframework.aop.framework.autoproxy` package provides the following
standard auto-proxy creators.
[[aop-api-autoproxy]]
==== BeanNameAutoProxyCreator
The `BeanNameAutoProxyCreator` class is a `BeanPostProcessor` that automatically creates
AOP proxies for beans with names matching literal values or wildcards.
@@ -1299,6 +1332,7 @@ the above example), the pointcuts may apply differently to different beans.
[[aop-api-autoproxy-default]]
==== DefaultAdvisorAutoProxyCreator
A more general and extremely powerful auto proxy creator is
`DefaultAdvisorAutoProxyCreator`. This will automagically apply eligible advisors in the
current context, without the need to include specific bean names in the auto-proxy
@@ -1500,6 +1534,7 @@ Note that both `lockMixin` and `lockableAdvisor` are defined as prototypes.
[[aop-targetsource]]
== Using TargetSources
Spring offers the concept of a __TargetSource__, expressed in the
`org.springframework.aop.TargetSource` interface. This interface is responsible for
returning the "target object" implementing the join point. The `TargetSource`
@@ -1518,7 +1553,6 @@ Let's look at the standard target sources provided with Spring, and how you can
[TIP]
====
When using a custom target source, your target will usually need to be a prototype
rather than a singleton bean definition. This allows Spring to create a new target
instance when required.
@@ -1528,6 +1562,7 @@ instance when required.
[[aop-ts-swap]]
=== Hot swappable target sources
The `org.springframework.aop.target.HotSwappableTargetSource` exists to allow the target
of an AOP proxy to be switched while allowing callers to keep their references to it.
@@ -1571,6 +1606,7 @@ arbitrary advice.
[[aop-ts-pool]]
=== Pooling target sources
Using a pooling target source provides a similar programming model to stateless session
EJBs, in which a pool of identical instances is maintained, with method invocations
going to free objects in the pool.
@@ -1665,6 +1701,7 @@ used by any auto-proxy creator.
[[aop-ts-prototype]]
=== Prototype target sources
Setting up a "prototype" target source is similar to a pooling TargetSource. In this
case, a new instance of the target will be created on every method invocation. Although
the cost of creating a new object isn't high in a modern JVM, the cost of wiring up the

View File

@@ -1357,7 +1357,7 @@ join point, unless you specify otherwise the order of execution is undefined. Yo
control the order of execution by specifying precedence. This is done in the normal
Spring way by either implementing the `org.springframework.core.Ordered` interface in
the aspect class or annotating it with the `Order` annotation. Given two aspects, the
aspect returning the lower value from `Ordered.getValue()` (or the annotation value) has
aspect returning the lower value from `Ordered.getOrder()` (or the annotation value) has
the higher precedence.
When two pieces of advice defined in __the same__ aspect both need to run at the same

View File

@@ -38,7 +38,7 @@ information on using the `BeanFactory` instead of the `ApplicationContext,` refe
In Spring, the objects that form the backbone of your application and that are managed
by the Spring IoC __container__ are called __beans__. A bean is an object that is
instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a
instantiated, assembled, and managed by a Spring IoC container. Otherwise, a
bean is simply one of many objects in your application. Beans, and the __dependencies__
among them, are reflected in the __configuration metadata__ used by a container.