blob: ba12387da32c1e8ad957ab7c7b6a7acc21065f5b [file] [log] [blame]
//////////////////////
* Licensed 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.
//////////////////////
[[core-api-sideeffect,SideEffect]]
= SideEffect =
SideEffects have no equivalent in Aspect Oriented Programming. They are executed AFTER the method invocation, and
they are potentially concurrent with the method invocation itself. The SideEffect receives the incoming method arguments
and can query the result of the method call by accessing the +next+ field. SideEffects can NOT influence the method
call in any way, and both return values from the SideEffect, as well as any exceptions thrown, will be ignored.
To create a sideeffect, you need to create a class that,
* implements the Mixin Type (Typed SideEffects) or java.lang.reflect.InvocationHandler (Generic SideEffects),
* extend SideEffectOf (Typed Concerns) or GenericSideEffect (Generic SideEffects) [1]
You are allowed to modify both the in-arguments as well as the returned value, including throw exceptions if that is
suitable, perhaps for post condition checks.
== Applicability ==
SideEffects are applied to composite types in several ways;
* @SideEffects annotation on the Mixin Type.
* withSideEffects() assembly instruction at bootstrap.
* @SideEffects annotation of custom annotations to be applied to either Mixin Types or methods on Mixin Types.
* @SideEffects annotation directly on a method.
== Typed SideEffect ==
As mentioned above, side effects that implements the _Mixin Type_ are called *Typed SideEffects*.
A Typed SideEffect doesn't have to implement all the methods in the Mixin Type. By making the class abstract and only
implementing the methods of interest, Polygeneâ„¢ runtime will subclass the side effect (otherwise not valid for the
JVM/compiler), but the generated methods will never be invoked.
== Generic SideEffect ==
Generic SideEffects implement the +java.lang.reflect.InvocationHandler+ and can potentially serve any method it is
applied to. Generic SideEffects will be added to all methods that the AppliesToFilter evaluates to true. By default,
that is all methods.
AppliesToFilters is a mechanism to limit, or direct, which methods that the concern should be added to. You have full
control over this selection process, via several mechanisms.
* @AppliesTo annotation can be put on the side effect, with either;
* an interface for which the methods should be wrapped, or
* an AppliesToFilter implementation that is consulted during building the invocation stack, or
* an annotation type that must be given on the method.
* SideEffects are added only to composites that declares the SideEffect, either in
* the Composite Type, or
* on any method of the Composite Type, or
* on an annotation that is in turn declared on a Composite Type method
* during assembly in the withSideEffects() method.
== Invocation Order ==
The invocation order of SideEffects is UNDEFINED, and one MUST NOT rely on SideEffects executing in any particular order.
They MAY be concurrent and outside the thread that executed the method, so the SideEffect can also not depend on
the UnitOfWork that may be observed as present.
To be clear; the method call to the SideEffect is NOT its own Polygene-controlled invocation stack, and any annotations
on the SideEffect methods will be ignored (or it is a bug). That means that IF the SideEffect needs a UnitOfWork it
either needs to manage one explicitly or call out to a service that has the @UnitOfWorkPropagation annotation.