Skip to content

Commit 9f49d24

Browse files
rwinchrstoyanchev
authored andcommitted
Split files
1 parent ac69a5d commit 9f49d24

File tree

391 files changed

+62477
-62392
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

391 files changed

+62477
-62392
lines changed

framework-docs/modules/ROOT/pages/core/aop-api.adoc

Lines changed: 0 additions & 1751 deletions
Large diffs are not rendered by default.

framework-docs/modules/ROOT/pages/core/aop-api/advice.adoc

Lines changed: 538 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
[[aop-api-advised]]
2+
= Manipulating Advised Objects
3+
4+
However you create AOP proxies, you can manipulate them BY using the
5+
`org.springframework.aop.framework.Advised` interface. Any AOP proxy can be cast to this
6+
interface, no matter which other interfaces it implements. This interface includes the
7+
following methods:
8+
9+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
10+
.Java
11+
----
12+
Advisor[] getAdvisors();
13+
14+
void addAdvice(Advice advice) throws AopConfigException;
15+
16+
void addAdvice(int pos, Advice advice) throws AopConfigException;
17+
18+
void addAdvisor(Advisor advisor) throws AopConfigException;
19+
20+
void addAdvisor(int pos, Advisor advisor) throws AopConfigException;
21+
22+
int indexOf(Advisor advisor);
23+
24+
boolean removeAdvisor(Advisor advisor) throws AopConfigException;
25+
26+
void removeAdvisor(int index) throws AopConfigException;
27+
28+
boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException;
29+
30+
boolean isFrozen();
31+
----
32+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
33+
.Kotlin
34+
----
35+
fun getAdvisors(): Array<Advisor>
36+
37+
@Throws(AopConfigException::class)
38+
fun addAdvice(advice: Advice)
39+
40+
@Throws(AopConfigException::class)
41+
fun addAdvice(pos: Int, advice: Advice)
42+
43+
@Throws(AopConfigException::class)
44+
fun addAdvisor(advisor: Advisor)
45+
46+
@Throws(AopConfigException::class)
47+
fun addAdvisor(pos: Int, advisor: Advisor)
48+
49+
fun indexOf(advisor: Advisor): Int
50+
51+
@Throws(AopConfigException::class)
52+
fun removeAdvisor(advisor: Advisor): Boolean
53+
54+
@Throws(AopConfigException::class)
55+
fun removeAdvisor(index: Int)
56+
57+
@Throws(AopConfigException::class)
58+
fun replaceAdvisor(a: Advisor, b: Advisor): Boolean
59+
60+
fun isFrozen(): Boolean
61+
----
62+
63+
The `getAdvisors()` method returns an `Advisor` for every advisor, interceptor, or
64+
other advice type that has been added to the factory. If you added an `Advisor`, the
65+
returned advisor at this index is the object that you added. If you added an
66+
interceptor or other advice type, Spring wrapped this in an advisor with a
67+
pointcut that always returns `true`. Thus, if you added a `MethodInterceptor`, the advisor
68+
returned for this index is a `DefaultPointcutAdvisor` that returns your
69+
`MethodInterceptor` and a pointcut that matches all classes and methods.
70+
71+
The `addAdvisor()` methods can be used to add any `Advisor`. Usually, the advisor holding
72+
pointcut and advice is the generic `DefaultPointcutAdvisor`, which you can use with
73+
any advice or pointcut (but not for introductions).
74+
75+
By default, it is possible to add or remove advisors or interceptors even once a proxy
76+
has been created. The only restriction is that it is impossible to add or remove an
77+
introduction advisor, as existing proxies from the factory do not show the interface
78+
change. (You can obtain a new proxy from the factory to avoid this problem.)
79+
80+
The following example shows casting an AOP proxy to the `Advised` interface and examining and
81+
manipulating its advice:
82+
83+
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
84+
.Java
85+
----
86+
Advised advised = (Advised) myObject;
87+
Advisor[] advisors = advised.getAdvisors();
88+
int oldAdvisorCount = advisors.length;
89+
System.out.println(oldAdvisorCount + " advisors");
90+
91+
// Add an advice like an interceptor without a pointcut
92+
// Will match all proxied methods
93+
// Can use for interceptors, before, after returning or throws advice
94+
advised.addAdvice(new DebugInterceptor());
95+
96+
// Add selective advice using a pointcut
97+
advised.addAdvisor(new DefaultPointcutAdvisor(mySpecialPointcut, myAdvice));
98+
99+
assertEquals("Added two advisors", oldAdvisorCount + 2, advised.getAdvisors().length);
100+
----
101+
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
102+
.Kotlin
103+
----
104+
val advised = myObject as Advised
105+
val advisors = advised.advisors
106+
val oldAdvisorCount = advisors.size
107+
println("$oldAdvisorCount advisors")
108+
109+
// Add an advice like an interceptor without a pointcut
110+
// Will match all proxied methods
111+
// Can use for interceptors, before, after returning or throws advice
112+
advised.addAdvice(DebugInterceptor())
113+
114+
// Add selective advice using a pointcut
115+
advised.addAdvisor(DefaultPointcutAdvisor(mySpecialPointcut, myAdvice))
116+
117+
assertEquals("Added two advisors", oldAdvisorCount + 2, advised.advisors.size)
118+
----
119+
120+
NOTE: It is questionable whether it is advisable (no pun intended) to modify advice on a
121+
business object in production, although there are, no doubt, legitimate usage cases.
122+
However, it can be very useful in development (for example, in tests). We have sometimes
123+
found it very useful to be able to add test code in the form of an interceptor or other
124+
advice, getting inside a method invocation that we want to test. (For example, the advice can
125+
get inside a transaction created for that method, perhaps to run SQL to check that
126+
a database was correctly updated, before marking the transaction for roll back.)
127+
128+
Depending on how you created the proxy, you can usually set a `frozen` flag. In that
129+
case, the `Advised` `isFrozen()` method returns `true`, and any attempts to modify
130+
advice through addition or removal results in an `AopConfigException`. The ability
131+
to freeze the state of an advised object is useful in some cases (for example, to
132+
prevent calling code removing a security interceptor).
133+
134+
135+
136+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[[aop-api-advisor]]
2+
= The Advisor API in Spring
3+
4+
In Spring, an Advisor is an aspect that contains only a single advice object associated
5+
with a pointcut expression.
6+
7+
Apart from the special case of introductions, any advisor can be used with any advice.
8+
`org.springframework.aop.support.DefaultPointcutAdvisor` is the most commonly used
9+
advisor class. It can be used with a `MethodInterceptor`, `BeforeAdvice`, or
10+
`ThrowsAdvice`.
11+
12+
It is possible to mix advisor and advice types in Spring in the same AOP proxy. For
13+
example, you could use an interception around advice, throws advice, and before advice in
14+
one proxy configuration. Spring automatically creates the necessary interceptor
15+
chain.
16+
17+
18+
19+
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
[[aop-autoproxy]]
2+
= Using the "auto-proxy" facility
3+
4+
So far, we have considered explicit creation of AOP proxies by using a `ProxyFactoryBean` or
5+
similar factory bean.
6+
7+
Spring also lets us use "`auto-proxy`" bean definitions, which can automatically
8+
proxy selected bean definitions. This is built on Spring's "`bean post processor`"
9+
infrastructure, which enables modification of any bean definition as the container loads.
10+
11+
In this model, you set up some special bean definitions in your XML bean definition file
12+
to configure the auto-proxy infrastructure. This lets you declare the targets
13+
eligible for auto-proxying. You need not use `ProxyFactoryBean`.
14+
15+
There are two ways to do this:
16+
17+
* By using an auto-proxy creator that refers to specific beans in the current context.
18+
* A special case of auto-proxy creation that deserves to be considered separately:
19+
auto-proxy creation driven by source-level metadata attributes.
20+
21+
22+
23+
[[aop-autoproxy-choices]]
24+
== Auto-proxy Bean Definitions
25+
26+
This section covers the auto-proxy creators provided by the
27+
`org.springframework.aop.framework.autoproxy` package.
28+
29+
30+
[[aop-api-autoproxy]]
31+
=== `BeanNameAutoProxyCreator`
32+
33+
The `BeanNameAutoProxyCreator` class is a `BeanPostProcessor` that automatically creates
34+
AOP proxies for beans with names that match literal values or wildcards. The following
35+
example shows how to create a `BeanNameAutoProxyCreator` bean:
36+
37+
[source,xml,indent=0,subs="verbatim,quotes"]
38+
----
39+
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
40+
<property name="beanNames" value="jdk*,onlyJdk"/>
41+
<property name="interceptorNames">
42+
<list>
43+
<value>myInterceptor</value>
44+
</list>
45+
</property>
46+
</bean>
47+
----
48+
49+
As with `ProxyFactoryBean`, there is an `interceptorNames` property rather than a list
50+
of interceptors, to allow correct behavior for prototype advisors. Named "`interceptors`"
51+
can be advisors or any advice type.
52+
53+
As with auto-proxying in general, the main point of using `BeanNameAutoProxyCreator` is
54+
to apply the same configuration consistently to multiple objects, with minimal volume of
55+
configuration. It is a popular choice for applying declarative transactions to multiple
56+
objects.
57+
58+
Bean definitions whose names match, such as `jdkMyBean` and `onlyJdk` in the preceding
59+
example, are plain old bean definitions with the target class. An AOP proxy is
60+
automatically created by the `BeanNameAutoProxyCreator`. The same advice is applied
61+
to all matching beans. Note that, if advisors are used (rather than the interceptor in
62+
the preceding example), the pointcuts may apply differently to different beans.
63+
64+
65+
[[aop-api-autoproxy-default]]
66+
=== `DefaultAdvisorAutoProxyCreator`
67+
68+
A more general and extremely powerful auto-proxy creator is
69+
`DefaultAdvisorAutoProxyCreator`. This automagically applies eligible advisors in the
70+
current context, without the need to include specific bean names in the auto-proxy
71+
advisor's bean definition. It offers the same merit of consistent configuration and
72+
avoidance of duplication as `BeanNameAutoProxyCreator`.
73+
74+
Using this mechanism involves:
75+
76+
* Specifying a `DefaultAdvisorAutoProxyCreator` bean definition.
77+
* Specifying any number of advisors in the same or related contexts. Note that these
78+
must be advisors, not interceptors or other advice. This is necessary,
79+
because there must be a pointcut to evaluate, to check the eligibility of each advice
80+
to candidate bean definitions.
81+
82+
The `DefaultAdvisorAutoProxyCreator` automatically evaluates the pointcut contained
83+
in each advisor, to see what (if any) advice it should apply to each business object
84+
(such as `businessObject1` and `businessObject2` in the example).
85+
86+
This means that any number of advisors can be applied automatically to each business
87+
object. If no pointcut in any of the advisors matches any method in a business object,
88+
the object is not proxied. As bean definitions are added for new business objects,
89+
they are automatically proxied if necessary.
90+
91+
Auto-proxying in general has the advantage of making it impossible for callers or
92+
dependencies to obtain an un-advised object. Calling `getBean("businessObject1")` on this
93+
`ApplicationContext` returns an AOP proxy, not the target business object. (The "`inner
94+
bean`" idiom shown earlier also offers this benefit.)
95+
96+
The following example creates a `DefaultAdvisorAutoProxyCreator` bean and the other
97+
elements discussed in this section:
98+
99+
[source,xml,indent=0,subs="verbatim,quotes"]
100+
----
101+
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
102+
103+
<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
104+
<property name="transactionInterceptor" ref="transactionInterceptor"/>
105+
</bean>
106+
107+
<bean id="customAdvisor" class="com.mycompany.MyAdvisor"/>
108+
109+
<bean id="businessObject1" class="com.mycompany.BusinessObject1">
110+
<!-- Properties omitted -->
111+
</bean>
112+
113+
<bean id="businessObject2" class="com.mycompany.BusinessObject2"/>
114+
----
115+
116+
The `DefaultAdvisorAutoProxyCreator` is very useful if you want to apply the same advice
117+
consistently to many business objects. Once the infrastructure definitions are in place,
118+
you can add new business objects without including specific proxy configuration.
119+
You can also easily drop in additional aspects (for example, tracing or
120+
performance monitoring aspects) with minimal change to configuration.
121+
122+
The `DefaultAdvisorAutoProxyCreator` offers support for filtering (by using a naming
123+
convention so that only certain advisors are evaluated, which allows the use of multiple,
124+
differently configured, AdvisorAutoProxyCreators in the same factory) and ordering.
125+
Advisors can implement the `org.springframework.core.Ordered` interface to ensure
126+
correct ordering if this is an issue. The `TransactionAttributeSourceAdvisor` used in the
127+
preceding example has a configurable order value. The default setting is unordered.
128+
129+
130+
131+
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
[[aop-concise-proxy]]
2+
= Concise Proxy Definitions
3+
4+
Especially when defining transactional proxies, you may end up with many similar proxy
5+
definitions. The use of parent and child bean definitions, along with inner bean
6+
definitions, can result in much cleaner and more concise proxy definitions.
7+
8+
First, we create a parent, template, bean definition for the proxy, as follows:
9+
10+
[source,xml,indent=0,subs="verbatim,quotes"]
11+
----
12+
<bean id="txProxyTemplate" abstract="true"
13+
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
14+
<property name="transactionManager" ref="transactionManager"/>
15+
<property name="transactionAttributes">
16+
<props>
17+
<prop key="*">PROPAGATION_REQUIRED</prop>
18+
</props>
19+
</property>
20+
</bean>
21+
----
22+
23+
This is never instantiated itself, so it can actually be incomplete. Then, each proxy
24+
that needs to be created is a child bean definition, which wraps the target of the
25+
proxy as an inner bean definition, since the target is never used on its own anyway.
26+
The following example shows such a child bean:
27+
28+
[source,xml,indent=0,subs="verbatim,quotes"]
29+
----
30+
<bean id="myService" parent="txProxyTemplate">
31+
<property name="target">
32+
<bean class="org.springframework.samples.MyServiceImpl">
33+
</bean>
34+
</property>
35+
</bean>
36+
----
37+
38+
You can override properties from the parent template. In the following example,
39+
we override the transaction propagation settings:
40+
41+
[source,xml,indent=0,subs="verbatim,quotes"]
42+
----
43+
<bean id="mySpecialService" parent="txProxyTemplate">
44+
<property name="target">
45+
<bean class="org.springframework.samples.MySpecialServiceImpl">
46+
</bean>
47+
</property>
48+
<property name="transactionAttributes">
49+
<props>
50+
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
51+
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
52+
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
53+
<prop key="store*">PROPAGATION_REQUIRED</prop>
54+
</props>
55+
</property>
56+
</bean>
57+
----
58+
59+
Note that in the parent bean example, we explicitly marked the parent bean definition as
60+
being abstract by setting the `abstract` attribute to `true`, as described
61+
<<beans-child-bean-definitions, previously>>, so that it may not actually ever be
62+
instantiated. Application contexts (but not simple bean factories), by default,
63+
pre-instantiate all singletons. Therefore, it is important (at least for singleton beans)
64+
that, if you have a (parent) bean definition that you intend to use only as a template,
65+
and this definition specifies a class, you must make sure to set the `abstract`
66+
attribute to `true`. Otherwise, the application context actually tries to
67+
pre-instantiate it.
68+
69+
70+
71+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[[aop-extensibility]]
2+
= Defining New Advice Types
3+
4+
Spring AOP is designed to be extensible. While the interception implementation strategy
5+
is presently used internally, it is possible to support arbitrary advice types in
6+
addition to the interception around advice, before, throws advice, and
7+
after returning advice.
8+
9+
The `org.springframework.aop.framework.adapter` package is an SPI package that lets
10+
support for new custom advice types be added without changing the core framework.
11+
The only constraint on a custom `Advice` type is that it must implement the
12+
`org.aopalliance.aop.Advice` marker interface.
13+
14+
See the {api-spring-framework}/aop/framework/adapter/package-summary.html[`org.springframework.aop.framework.adapter`]
15+
javadoc for further information.

0 commit comments

Comments
 (0)