001 /*
002 * ============================================================================
003 * GNU Lesser General Public License
004 * ============================================================================
005 *
006 * Beanlet - JSE Application Container.
007 * Copyright (C) 2006 Leon van Zantvoort
008 *
009 * This library is free software; you can redistribute it and/or
010 * modify it under the terms of the GNU Lesser General Public
011 * License as published by the Free Software Foundation; either
012 * version 2.1 of the License, or (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017 * Lesser General Public License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this library; if not, write to the Free Software
021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
022 *
023 * Leon van Zantvoort
024 * 243 Acalanes Drive #11
025 * Sunnyvale, CA 94086
026 * USA
027 *
028 * zantvoort@users.sourceforge.net
029 * http://beanlet.org
030 */
031 package org.beanlet;
032
033 import java.lang.annotation.ElementType;
034 import java.lang.annotation.Retention;
035 import java.lang.annotation.RetentionPolicy;
036 import java.lang.annotation.Target;
037
038 /**
039 * <p>Designates a method to intercept invocations on a beanlet. A class that
040 * declares a method marked with the {@code ArroundInvoke} annotation is said to
041 * be an interceptor class. Interceptor classes are instantiated either by their
042 * (typically implicit) sole constructor, or by contructor injection.
043 * Example (A) shows how to implement an interceptor using this annotation.</p>
044 *
045 * <p><h3>Inner Interceptors</h3>
046 * The {@code ArroundInvoke} annotation can be applied on methods of any class,
047 * including classes implementing a beanlet. Such interceptors are so-called
048 * inner interceptors. An inner interceptor is <u>automatically</u>
049 * installed for all business methods of a beanlet. It is placed at the tail of
050 * the interceptor chain. It cannot be excluded by the
051 * {@code ExcludeClassInterceptors} annotation. An example of an inner
052 * interceptor can be found at example (B).</p>
053 *
054 * <p><h3>Hierarchical Interceptors</h3>
055 * Interceptor classes may declare only one interceptor method. However
056 * interceptor methods may be defined on any of its superclasses. The
057 * interceptor methods defined by these superclasses are invoked before the
058 * interceptor method defined by the interceptor class, most general superclass
059 * first. This is demonstrated by example (C).<br>
060 * If a interceptor method is overridden by another method (regardless whether
061 * that method is itself an interceptor method), it will not be invoked. An
062 * example of such an interceptor is listed at (D).<br>
063 * </p>
064 *
065 * <p><h3>Method Constraints</h3>
066 * The method on which the {@code AroundInvoke} annotation is applied MUST
067 * fulfill all of the following criteria:
068 * <ul>
069 * <li>The method MUST have the {@code InterceptorContext} object as parameter.
070 * <li>The return type of the method MUST NOT be {@code void}
071 * <li>The method MAY throw a checked exception.
072 * <li>The method on which {@code AroundInvoke} is applied MAY be
073 * {@code public}, {@code protected}, package private or {@code private}.
074 * <li>The method MUST NOT be {@code static}.
075 * <li>The method MAY be {@code final}.
076 * </ul>
077 * </p>
078 *
079 * <p><h3>Examples</h3>
080 * <b>(A)</b> Example of an interceptor class using the {@code ArroundInvoke}
081 * annotation:
082 * <pre>
083 * public class BaseInterceptor {
084 *
085 * @AroundInvoke
086 * public Object wrap(InvocationContext ctx) throws Exception {
087 * try {
088 * // Run code before the invocation...
089 * return ctx.proceed();
090 * } finally {
091 * // Run code after the invocation...
092 * }
093 * }
094 * }
095 * </pre>
096 *
097 * <b>(B)</b> Example of a beanlet with an inner interceptor:
098 * <pre>
099 * public class ExampleBeanlet {
100 *
101 * @Factory
102 * public Object getInstance() {
103 * return new Object();
104 * }
105 *
106 * @ArroundInvoke
107 * public Object intercept(InvocationContext ctx) throws Exception {
108 * try {
109 * // Run code before the invocation...
110 * return ctx.proceed();
111 * } finally {
112 * // Run code after the invocation...
113 * }
114 * }
115 * }
116 * </pre>
117 *
118 * <b>(C)</b> Example of an interceptor class that extends the interceptor class
119 * listed at example (A). The {@code BaseInterceptor.wrap()} method preceeds
120 * the {@code ExtendedInterceptor.wrapToo()} method in the interceptor chain:
121 * <pre>
122 * public class ExtendedInterceptor extends BaseInterceptor {
123 *
124 * @AroundInvoke
125 * public Object wrapToo(InvocationContext ctx) throws Exception {
126 * try {
127 * // Run code before the invocation...
128 * return ctx.proceed();
129 * } finally {
130 * // Run code after the invocation...
131 * }
132 * }
133 * }
134 * </pre>
135 *
136 * <b>(D)</b> Example of an extended interceptor class of which the interceptor
137 * method overrides the interceptor method of its superclass (listed at (A)).
138 * The {@code BaseInterceptor.wrap()} method is excluded from the interceptor
139 * chain, it is not invoked. The {@code ExtendedInterceptor.wrap()} method
140 * however, is included in the interceptor chain.
141 * <pre>
142 * public class ExtendedInterceptor extends BaseInterceptor {
143 *
144 * @AroundInvoke
145 * public Object wrap(InvocationContext ctx) throws Exception {
146 * try {
147 * // Run code before the invocation...
148 * return ctx.proceed();
149 * } finally {
150 * // Run code after the invocation...
151 * }
152 * }
153 * }
154 * </pre>
155 * </p>
156 *
157 * <p>More information on how to apply interceptors can be found at the
158 * javadoc of the {@link Interceptor} interface.</p>
159 *
160 * {@beanlet.annotation}
161 *
162 * @see Interceptor
163 * @see Interceptors
164 * @author Leon van Zantvoort
165 */
166 @Retention(RetentionPolicy.RUNTIME)
167 @Target(ElementType.METHOD)
168 public @interface AroundInvoke {
169
170 }