From ab16053ed4defa2dc009bddb3a22199aea75e42b Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 26 Feb 2016 12:40:00 +0100 Subject: [PATCH] Redistribute AOP Alliance interfaces in spring-aop again (as in Spring 2.x) Issue: SPR-13984 --- build.gradle | 8 --- .../main/java/org/aopalliance/aop/Advice.java | 28 ++++++++ .../org/aopalliance/aop/AspectException.java | 48 +++++++++++++ .../intercept/ConstructorInterceptor.java | 59 ++++++++++++++++ .../intercept/ConstructorInvocation.java | 41 +++++++++++ .../aopalliance/intercept/Interceptor.java | 69 +++++++++++++++++++ .../org/aopalliance/intercept/Invocation.java | 37 ++++++++++ .../org/aopalliance/intercept/Joinpoint.java | 65 +++++++++++++++++ .../intercept/MethodInterceptor.java | 56 +++++++++++++++ .../intercept/MethodInvocation.java | 41 +++++++++++ 10 files changed, 444 insertions(+), 8 deletions(-) create mode 100644 spring-aop/src/main/java/org/aopalliance/aop/Advice.java create mode 100644 spring-aop/src/main/java/org/aopalliance/aop/AspectException.java create mode 100644 spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInterceptor.java create mode 100644 spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInvocation.java create mode 100644 spring-aop/src/main/java/org/aopalliance/intercept/Interceptor.java create mode 100644 spring-aop/src/main/java/org/aopalliance/intercept/Invocation.java create mode 100644 spring-aop/src/main/java/org/aopalliance/intercept/Joinpoint.java create mode 100644 spring-aop/src/main/java/org/aopalliance/intercept/MethodInterceptor.java create mode 100644 spring-aop/src/main/java/org/aopalliance/intercept/MethodInvocation.java diff --git a/build.gradle b/build.gradle index 069248259b..29a356261d 100644 --- a/build.gradle +++ b/build.gradle @@ -202,7 +202,6 @@ configure(allprojects) { project -> "http://portals.apache.org/pluto/portlet-2.0-apidocs/", "http://tiles.apache.org/tiles-request/apidocs/", "http://tiles.apache.org/framework/apidocs/", - "http://aopalliance.sourceforge.net/doc/", "http://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/", "http://ehcache.org/apidocs/", "http://quartz-scheduler.org/api/2.2.0/", @@ -428,7 +427,6 @@ project("spring-aop") { compile(project(":spring-core")) compile(files(project(":spring-core").cglibRepackJar)) compile(files(project(":spring-core").objenesisRepackJar)) - compile("aopalliance:aopalliance:1.0") optional("org.aspectj:aspectjweaver:${aspectjVersion}") optional("commons-pool:commons-pool:1.6") optional("org.apache.commons:commons-pool2:2.4.2") @@ -550,7 +548,6 @@ project("spring-tx") { compile(project(":spring-core")) optional(project(":spring-aop")) optional(project(":spring-context")) // for JCA, @EnableTransactionManagement - optional("aopalliance:aopalliance:1.0") optional("javax.transaction:javax.transaction-api:${jtaVersion}") optional("javax.resource:connector-api:1.5") optional("javax.ejb:ejb-api:${ejbApiVersion}") @@ -617,7 +614,6 @@ project("spring-jms") { compile(project(":spring-tx")) provided("javax.jms:jms-api:1.1-rev-1") optional(project(":spring-oxm")) - optional("aopalliance:aopalliance:1.0") optional("javax.transaction:javax.transaction-api:${jtaVersion}") optional("javax.resource:connector-api:1.5") optional("com.fasterxml.jackson.core:jackson-databind:${jackson2Version}") @@ -710,7 +706,6 @@ project("spring-web") { optional("javax.el:javax.el-api:2.2.5") optional("javax.faces:javax.faces-api:2.2") optional("javax.validation:validation-api:1.0.0.GA") - optional("aopalliance:aopalliance:1.0") optional("org.codehaus.groovy:groovy-all:${groovyVersion}") optional("com.caucho:hessian:4.0.38") optional("commons-fileupload:commons-fileupload:${fileuploadVersion}") @@ -801,7 +796,6 @@ project("spring-orm") { optional(project(":spring-aop")) optional(project(":spring-context")) optional(project(":spring-web")) - optional("aopalliance:aopalliance:1.0") optional("org.eclipse.persistence:javax.persistence:2.0.5") optional("org.eclipse.persistence:org.eclipse.persistence.core:${eclipselinkVersion}") optional("org.eclipse.persistence:org.eclipse.persistence.jpa:${eclipselinkVersion}") { @@ -842,7 +836,6 @@ project("spring-orm-hibernate4") { optional("org.hibernate:hibernate-core:${hibernate4Version}") optional("org.hibernate:hibernate-entitymanager:${hibernate4Version}") optional("javax.servlet:javax.servlet-api:3.0.1") - optional("aopalliance:aopalliance:1.0") testCompile("javax.validation:validation-api:1.1.0.GA") testCompile("org.hibernate:hibernate-validator:${hibval5Version}") testCompile("javax.el:javax.el-api:2.2.5") @@ -862,7 +855,6 @@ project("spring-orm-hibernate5") { optional("org.hibernate:hibernate-entitymanager:${hibernate5Version}") optional("javax.servlet:javax.servlet-api:3.0.1") optional("javax.transaction:javax.transaction-api:${jtaVersion}") - optional("aopalliance:aopalliance:1.0") } } diff --git a/spring-aop/src/main/java/org/aopalliance/aop/Advice.java b/spring-aop/src/main/java/org/aopalliance/aop/Advice.java new file mode 100644 index 0000000000..6dcbc4af25 --- /dev/null +++ b/spring-aop/src/main/java/org/aopalliance/aop/Advice.java @@ -0,0 +1,28 @@ +/* + * Copyright 2002-2016 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. + * 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. + */ + +package org.aopalliance.aop; + +/** + * Tag interface for Advice. Implementations can be any type + * of advice, such as Interceptors. + * + * @author Rod Johnson + * @version $Id: Advice.java,v 1.1 2004/03/19 17:02:16 johnsonr Exp $ + */ +public interface Advice { + +} diff --git a/spring-aop/src/main/java/org/aopalliance/aop/AspectException.java b/spring-aop/src/main/java/org/aopalliance/aop/AspectException.java new file mode 100644 index 0000000000..c634d51a06 --- /dev/null +++ b/spring-aop/src/main/java/org/aopalliance/aop/AspectException.java @@ -0,0 +1,48 @@ +/* + * Copyright 2002-2016 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. + * 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. + */ + +package org.aopalliance.aop; + +/** + * Superclass for all AOP infrastructure exceptions. + * Unchecked, as such exceptions are fatal and end user + * code shouldn't be forced to catch them. + * + * @author Rod Johnson + * @author Bob Lee + * @author Juergen Hoeller + */ +@SuppressWarnings("serial") +public class AspectException extends RuntimeException { + + /** + * Constructor for AspectException. + * @param message the exception message + */ + public AspectException(String message) { + super(message); + } + + /** + * Constructor for AspectException. + * @param message the exception message + * @param cause the root cause, if any + */ + public AspectException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInterceptor.java b/spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInterceptor.java new file mode 100644 index 0000000000..7e0ac706a7 --- /dev/null +++ b/spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInterceptor.java @@ -0,0 +1,59 @@ +/* + * Copyright 2002-2016 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. + * 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. + */ + +package org.aopalliance.intercept; + +/** + * Intercepts the construction of a new object. + * + *

The user should implement the {@link + * #construct(ConstructorInvocation)} method to modify the original + * behavior. E.g. the following class implements a singleton + * interceptor (allows only one unique instance for the intercepted + * class): + * + *

+ * class DebuggingInterceptor implements ConstructorInterceptor {
+ *   Object instance=null;
+ *
+ *   Object construct(ConstructorInvocation i) throws Throwable {
+ *     if(instance==null) {
+ *       return instance=i.proceed();
+ *     } else {
+ *       throw new Exception("singleton does not allow multiple instance");
+ *     }
+ *   }
+ * }
+ * 
+ * + * @author Rod Johnson + */ +public interface ConstructorInterceptor extends Interceptor { + + /** + * Implement this method to perform extra treatments before and + * after the construction of a new object. Polite implementations + * would certainly like to invoke {@link Joinpoint#proceed()}. + * @param invocation the construction joinpoint + * @return the newly created object, which is also the result of + * the call to {@link Joinpoint#proceed()}; might be replaced by + * the interceptor + * @throws Throwable if the interceptors or the target object + * throws an exception + */ + Object construct(ConstructorInvocation invocation) throws Throwable; + +} diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInvocation.java b/spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInvocation.java new file mode 100644 index 0000000000..a453ac32e3 --- /dev/null +++ b/spring-aop/src/main/java/org/aopalliance/intercept/ConstructorInvocation.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002-2016 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. + * 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. + */ + +package org.aopalliance.intercept; + +import java.lang.reflect.Constructor; + +/** + * Description of an invocation to a constuctor, given to an + * interceptor upon constructor-call. + * + *

A constructor invocation is a joinpoint and can be intercepted + * by a constructor interceptor. + * + * @author Rod Johnson + * @see ConstructorInterceptor + */ +public interface ConstructorInvocation extends Invocation { + + /** + * Get the constructor being called. + *

This method is a friendly implementation of the + * {@link Joinpoint#getStaticPart()} method (same result). + * @return the constructor being called + */ + Constructor getConstructor(); + +} diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/Interceptor.java b/spring-aop/src/main/java/org/aopalliance/intercept/Interceptor.java new file mode 100644 index 0000000000..ebdcf7c1dd --- /dev/null +++ b/spring-aop/src/main/java/org/aopalliance/intercept/Interceptor.java @@ -0,0 +1,69 @@ +/* + * Copyright 2002-2016 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. + * 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. + */ + +package org.aopalliance.intercept; + +import org.aopalliance.aop.Advice; + +/** + * This interface represents a generic interceptor. + * + *

A generic interceptor can intercept runtime events that occur + * within a base program. Those events are materialized by (reified + * in) joinpoints. Runtime joinpoints can be invocations, field + * access, exceptions... + * + *

This interface is not used directly. Use the the sub-interfaces + * to intercept specific events. For instance, the following class + * implements some specific interceptors in order to implement a + * debugger: + * + *

+ * class DebuggingInterceptor implements MethodInterceptor, 
+ *     ConstructorInterceptor, FieldInterceptor {
+ *
+ *   Object invoke(MethodInvocation i) throws Throwable {
+ *     debug(i.getMethod(), i.getThis(), i.getArgs());
+ *     return i.proceed();
+ *   }
+ *
+ *   Object construct(ConstructorInvocation i) throws Throwable {
+ *     debug(i.getConstructor(), i.getThis(), i.getArgs());
+ *     return i.proceed();
+ *   }
+ * 
+ *   Object get(FieldAccess fa) throws Throwable {
+ *     debug(fa.getField(), fa.getThis(), null);
+ *     return fa.proceed();
+ *   }
+ *
+ *   Object set(FieldAccess fa) throws Throwable {
+ *     debug(fa.getField(), fa.getThis(), fa.getValueToSet());
+ *     return fa.proceed();
+ *   }
+ *
+ *   void debug(AccessibleObject ao, Object this, Object value) {
+ *     ...
+ *   }
+ * }
+ * 
+ * + * @author Rod Johnson + * @see Joinpoint + */ +public interface Interceptor extends Advice { + +} diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/Invocation.java b/spring-aop/src/main/java/org/aopalliance/intercept/Invocation.java new file mode 100644 index 0000000000..e785afb43b --- /dev/null +++ b/spring-aop/src/main/java/org/aopalliance/intercept/Invocation.java @@ -0,0 +1,37 @@ +/* + * Copyright 2002-2016 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. + * 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. + */ + +package org.aopalliance.intercept; + +/** + * This interface represents an invocation in the program. + * + *

An invocation is a joinpoint and can be intercepted by an + * interceptor. + * + * @author Rod Johnson + */ +public interface Invocation extends Joinpoint { + + /** + * Get the arguments as an array object. + * It is possible to change element values within this + * array to change the arguments. + * @return the argument of the invocation + */ + Object[] getArguments(); + +} diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/Joinpoint.java b/spring-aop/src/main/java/org/aopalliance/intercept/Joinpoint.java new file mode 100644 index 0000000000..9328f3331e --- /dev/null +++ b/spring-aop/src/main/java/org/aopalliance/intercept/Joinpoint.java @@ -0,0 +1,65 @@ +/* + * Copyright 2002-2016 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. + * 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. + */ + +package org.aopalliance.intercept; + +import java.lang.reflect.AccessibleObject; + +/** + * This interface represents a generic runtime joinpoint (in the AOP + * terminology). + * + *

A runtime joinpoint is an event that occurs on a static + * joinpoint (i.e. a location in a the program). For instance, an + * invocation is the runtime joinpoint on a method (static joinpoint). + * The static part of a given joinpoint can be generically retrieved + * using the {@link #getStaticPart()} method. + * + *

In the context of an interception framework, a runtime joinpoint + * is then the reification of an access to an accessible object (a + * method, a constructor, a field), i.e. the static part of the + * joinpoint. It is passed to the interceptors that are installed on + * the static joinpoint. + * + * @author Rod Johnson + * @see Interceptor + */ +public interface Joinpoint { + + /** + * Proceed to the next interceptor in the chain. + *

The implementation and the semantics of this method depends + * on the actual joinpoint type (see the children interfaces). + * @return see the children interfaces' proceed definition + * @throws Throwable if the joinpoint throws an exception + */ + Object proceed() throws Throwable; + + /** + * Return the object that holds the current joinpoint's static part. + *

For instance, the target object for an invocation. + * @return the object (can be null if the accessible object is static) + */ + Object getThis(); + + /** + * Return the static part of this joinpoint. + *

The static part is an accessible object on which a chain of + * interceptors are installed. + */ + AccessibleObject getStaticPart(); + +} diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/MethodInterceptor.java b/spring-aop/src/main/java/org/aopalliance/intercept/MethodInterceptor.java new file mode 100644 index 0000000000..7fa2b87269 --- /dev/null +++ b/spring-aop/src/main/java/org/aopalliance/intercept/MethodInterceptor.java @@ -0,0 +1,56 @@ +/* + * Copyright 2002-2016 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. + * 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. + */ + +package org.aopalliance.intercept; + +/** + * Intercepts calls on an interface on its way to the target. These + * are nested "on top" of the target. + * + *

The user should implement the {@link #invoke(MethodInvocation)} + * method to modify the original behavior. E.g. the following class + * implements a tracing interceptor (traces all the calls on the + * intercepted method(s)): + * + *

+ * class TracingInterceptor implements MethodInterceptor {
+ *   Object invoke(MethodInvocation i) throws Throwable {
+ *     System.out.println("method "+i.getMethod()+" is called on "+
+ *                        i.getThis()+" with args "+i.getArguments());
+ *     Object ret=i.proceed();
+ *     System.out.println("method "+i.getMethod()+" returns "+ret);
+ *     return ret;
+ *   }
+ * }
+ * 
+ * + * @author Rod Johnson + */ +public interface MethodInterceptor extends Interceptor { + + /** + * Implement this method to perform extra treatments before and + * after the invocation. Polite implementations would certainly + * like to invoke {@link Joinpoint#proceed()}. + * @param invocation the method invocation joinpoint + * @return the result of the call to {@link Joinpoint#proceed(); + * might be intercepted by the interceptor + * @throws Throwable if the interceptors or the target object + * throws an exception + */ + Object invoke(MethodInvocation invocation) throws Throwable; + +} diff --git a/spring-aop/src/main/java/org/aopalliance/intercept/MethodInvocation.java b/spring-aop/src/main/java/org/aopalliance/intercept/MethodInvocation.java new file mode 100644 index 0000000000..6314824d76 --- /dev/null +++ b/spring-aop/src/main/java/org/aopalliance/intercept/MethodInvocation.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002-2016 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. + * 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. + */ + +package org.aopalliance.intercept; + +import java.lang.reflect.Method; + +/** + * Description of an invocation to a method, given to an interceptor + * upon method-call. + * + *

A method invocation is a joinpoint and can be intercepted by a + * method interceptor. + * + * @author Rod Johnson + * @see MethodInterceptor + */ +public interface MethodInvocation extends Invocation { + + /** + * Get the method being called. + *

This method is a frienly implementation of the + * {@link Joinpoint#getStaticPart()} method (same result). + * @return the method being called + */ + Method getMethod(); + +}