Author: limpbizkit
Date: Fri Jun 19 01:04:42 2009
New Revision: 1018
Modified:
wiki/AOP.wiki
Log:
Edited wiki page through web user interface.
Modified: wiki/AOP.wiki
==============================================================================
--- wiki/AOP.wiki (original)
+++ wiki/AOP.wiki Fri Jun 19 01:04:42 2009
@@ -8,14 +8,66 @@
[http://aopalliance.sourceforge.net/doc/org/aopalliance/intercept/MethodInterceptor.html
MethodInterceptors] are executed whenever a matching method is invoked.
They have the opportunity to inspect the call: the method, its arguments,
and the receiving instance. They can perform their cross-cutting logic and
then delegate to the underlying method. Finally, they may inspect the
return value or exception and return. Since interceptors may be applied to
many methods and will receive many calls, the intercepting method should be
efficient and unintrusive.
-==Example: Forbidding a method during weekends==
-
-We'll define an interceptor that forbids code from running on weekends.
-
-
-
-
-AOP alliance
-Injecting interceptors
+==Example: Forbidding method calls on weekends==
+To illustrate how method interceptors work with Guice, we'll forbid calls
to our pizza billing system on weekends. The delivery guys only work Monday
thru Friday so we'll prevent pizza from being ordered when it can't be
delivered! This example is structurally similar to use of AOP for
authorization.
+To mark select methods as weekdays-only, we define an annotation:
+{{{
+...@retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD)
+...@interface NotOnWeekends {}
+}}}
+...and apply it to the methods that need to be intercepted:
+{{{
+public class RealBillingService implements BillingService {
+
+ @NotOnWeekends
+ public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) {
+ ...
+ }
+}
+}}}
+Next, we define the interceptor by implementing the
`org.aopalliance.intercept.MethodInterceptor` interface. When we need to
call through to the underlying method, we do so by calling
`invocation.proceed()`:
+{{{
+public class WeekendBlocker implements MethodInterceptor {
+ public Object invoke(MethodInvocation invocation) throws Throwable {
+ Calendar today = new GregorianCalendar();
+ if (today.getDisplayName(DAY_OF_WEEK, LONG, ENGLISH).startsWith("S")) {
+ throw new IllegalStateException(
+ invocation.getMethod().getName() + " not allowed on weekends!");
+ }
+ return invocation.proceed();
+ }
+}
+}}}
+Finally, we configure everything. This is where we create matchers for the
classes and methods to be intercepted. In this case we match any class, but
only the methods with our `...@notonweekends` annotation:
+{{{
+public class NotOnWeekendsModule extends AbstractModule {
+ protected void configure() {
+ bindInterceptor(Matchers.any(),
Matchers.annotatedWith(NotOnWeekends.class),
+ new WeekendBlocker());
+ }
+}
+}}}
+Putting it all together, (and waiting until Saturday), we see the method
is intercepted and our order is rejected:
+{{{
+Exception in thread "main" java.lang.IllegalStateException: chargeOrder
not allowed on weekends!
+ at com.publicobject.pizza.WeekendBlocker.invoke(WeekendBlocker.java:65)
+ at
com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:64)
+ at
com.google.inject.internal.InterceptorStackCallback.intercept(InterceptorStackCallback.java:44)
+ at
com.publicobject.pizza.RealBillingService$$EnhancerByGuice$$49ed77ce.chargeOrder(<generated>)
+ at com.publicobject.pizza.WeekendExample.main(WeekendExample.java:47)}}}
+}}}
+
+==Limitations==
+Behind the scenes, method interception is implemented by generating
bytecode at runtime. Guice dynamically creates a subclass that applies
interceptors by overriding methods. If you are on a platform that doesn't
support bytecode generation (such as Android), you should use [OptionalAOP
Guice without AOP support].
+
+This approach imposes limits on what can be interception:
+ * Classes must be public or package-private.
+ * Classes must be non-final
+ * Methods must be public, package-private or protected
+ * Methods must be non-final
+ * Instances must be created by Guice by an `...@inject`-annotated or
no-argument constructor
+It is not possible to use method interception on instances that aren't
constructed by Guice.
+==AOP Alliance==
+The method interceptor API implemented by Guice is a part of a public
specification called [http://aopalliance.sourceforge.net/ AOP Alliance].
This makes it possible to use the same interceptors across a variety of
other frameworks.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"google-guice-dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/google-guice-dev?hl=en
-~----------~----~----~----~------~----~------~--~---