As we all know, AOP (aspect-oriented Programming), section-oriented Programming, is one of the three features of Spring framework. It is based on an implementation of the Java/J2EE AOP standard published by the AOP Alliance organization. AOP Alliance writes interfaces for a number of AOP-related operations by encapsulating Java’s Reflect related interfaces and classes. The Spring-AOP package is a concrete implementation of these operational interfaces.
For some unknown reason, Javadoc could not be downloaded for version 1.0 of Spring-AOP, nor could the aop Alliance source code used at the time be found. So the following analysis is using spring- AOP 5.2.12.RELEASE version of the source code.
The source code contains two parts: one is the specification of aopalliance organization, one is the concrete implementation of springframework to AOP.
In this article, the AOP specification will be analyzed.
The following figure shows all of aOPAlliance’s classes and interfaces, including the (formalist) AOP package and the Intercept package that defines some of the interfaces.
Aop package
The AOP package is a broad definition of AOP, including the Advice interface and AspectException exception classes.
Advice interface
Advice:
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 {}Copy the code
The Advice interface is used to flag suggestions without any internal methods.
Suggest that this interface is some suggestion for an AOP implementation by inheriting the Advice interface. Why not use class inheritance? Because the main purpose of the Advice interface is to do aOP-related definitions, classes are not intended to do definition conventions like interfaces, even abstract classes.)
AspectException class
Again, here is the source code for AspectException:
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); }}Copy the code
AspectException is defined as the parent class of all the base exceptions in AOP. Since AspectException is inherited from RuntimeExceotion, RuntimeException and its subclasses are unchecked (unchecked) in Java exceptions. (If the exception is thrown in a method or constructor without being caught, there is no need to pass the exception to the caller using the throws clause, and even if you do not catch the calling code of the method that threw the exception, it will pass compilation detection. An AspectException will be caught by the JVM and will stop the current thread. Therefore, there is no need for the calling code to forcibly catch and handle the exception.
In short, this is an exception base class designed to prevent users from doing anything illegal when implementing an AOP framework.
Intercept package
The Intercept package includes the well-known JoinPoint interface (which is nothing like JoinPoint in AspectJ), Advice based Interceptor interface specification and JoinPoint based Invocation interface specification
Joinpoint interface
The following is the joinPoint source code in aOPAlliance:
package org.aopalliance.intercept;
import java.lang.reflect.AccessibleObject;
/** * This interface represents a generic runtime joinpoint (in the AOP * terminology). * * <p>A runtime joinpoint is an <i>event</i> 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.
*
* <p>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.
* <p>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(a) throws Throwable;
/**
* Return the object that holds the current joinpoint's static part.
* <p>For instance, the target object for an invocation.
* @return the object (can be null if the accessible object is static)
*/
Object getThis(a);
/** * Return the static part of this joinpoint. * The static part is an accessible object on which a chain of * interceptors are installed. */
AccessibleObject getStaticPart(a);
}
Copy the code
Joinpoint is a static (fixed) place, such as a joinpoint added to a method. You can then manipulate the method of the connection (or something else) by intercepting it with an interceptor to get the current join point. Proceed () — proceed to the next interceptor in the interceptor chain; GetThis () — gets the static part of the current access method (such as the called object), and returns NULL if the available object is static; GetStaticPart () – Gets a static object that getThis() can’t get with an interceptor chain. AccessibleObject is an object type in Java reflection that allows reflection to make objects accessible (by masking Java’s permission checks) that are not otherwise accessible and perform operations.
Interceptor interface
The Interceptor interface inherits from the Advice interface.
package org.aopalliance.intercept;
import org.aopalliance.aop.Advice;
/**
* This interface represents a generic interceptor.
*
* <p>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...
*
* <p>This interface is not used directly. Use the sub-interfaces
* to intercept specific events. For instance, the following class
* implements some specific interceptors in order to implement a
* debugger:
*
* <pre class=code>
* class DebuggingInterceptor implements MethodInterceptor,
* ConstructorInterceptor {
*
* 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();
* }
*
* void debug(AccessibleObject ao, Object this, Object value) {
* ...
* }
* }
* </pre>
*
* @author Rod Johnson
* @see Joinpoint
*/
public interface Interceptor extends Advice {}Copy the code
Obviously, this interface is a protocol description interface. There is no method specification in it, but it tells us that Interceptor is a thing that can specify the events of the Interceptor program run by invocations, filed Access, exceptions and so on. To use an Interceptor, you need to inherit the Interceptor interface and specify the Interceptor method specification. Interceptor interfaces for constructors and methods are also provided.
ConstructorInterceptor interface
This interface is based on the Interceptor interface constructor Interceptor interface implementation, the following source:
package org.aopalliance.intercept;
/**
* Intercepts the construction of a new object.
*
* <p>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):
*
* <pre class=code>
* 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");
* }
* }
* }
* </pre>
*
* @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;
}
Copy the code
This interface provides a construct method that, depending on the implementation of the method, can perform additional processing before and after the constructor call to create a new object.
MethodInterceptor interfaces
This interface is based on the Interceptor interface method Interceptor interface implementation, the following is the source:
package org.aopalliance.intercept;
/**
* Intercepts calls on an interface on its way to the target. These
* are nested "on top" of the target.
*
* <p>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)):
*
* <pre class=code>
* 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;
* }
* }
* </pre>
*
* @author Rod Johnson
*/
@FunctionalInterface
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;
}
Copy the code
This interface provides an Invoke method that, based on the different implementation of the method, can perform additional processing before and after the invocation (of the method at the access point).
Invocation interface
The Invocation interface is derived from JoinPoint.
package org.aopalliance.intercept;
/** * This interface represents an invocation in the program. * * <p>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();
}
Copy the code
It’s just a kind of joinpoint call, and there’s a getArguments method inside that can get joinpoint parameters and modify them. Specific use, or need to cooperate with interceptor to use. Because AOP is a way of getting into the body of a program through interception and reflection.
ConstructorInvocation interface
The Invocation constructor is based on the Invocation interface.
package org.aopalliance.intercept;
import java.lang.reflect.Constructor;
/** * Description of an invocation to a constructor, given to an * interceptor upon constructor-call. * * <p>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.
* <p>This method is a friendly implementation of the
* {@link Joinpoint#getStaticPart()} method (same result).
* @return the constructor being called
*/Constructor<? > getConstructor(); }Copy the code
This interface provides the getConstructor method for intercepting the called constructor in the constructor’s interceptor, which is shielded from Java permission checking.
The MethodInvocation interface
The Invocation interface is based on the Invocation interface.
package org.aopalliance.intercept;
import java.lang.reflect.Method;
/**
* Description of an invocation to a method, given to an interceptor
* upon method-call.
*
* <p>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.
* <p>This method is a friendly implementation of the
* {@link Joinpoint#getStaticPart()} method (same result).
* @return the method being called
*/
Method getMethod(a);
}
Copy the code
This interface provides the getMethod method used to intercept the called method in the method’s interceptor. This interception also shields Java permission checking.
Above is to spring- AOP package org. aopAlliance package source analysis, I hope to bring you help. If there is any improper expression, welcome to correct.