mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Polishing
This commit is contained in:
+5
-4
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user