001/*
002 * Copyright 2002-2015 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.aop.aspectj.annotation;
018
019import java.lang.reflect.Method;
020import java.util.List;
021
022import org.aopalliance.aop.Advice;
023
024import org.springframework.aop.Advisor;
025import org.springframework.aop.aspectj.AspectJExpressionPointcut;
026import org.springframework.aop.framework.AopConfigException;
027import org.springframework.lang.Nullable;
028
029/**
030 * Interface for factories that can create Spring AOP Advisors from classes
031 * annotated with AspectJ annotation syntax.
032 *
033 * @author Rod Johnson
034 * @author Juergen Hoeller
035 * @since 2.0
036 * @see AspectMetadata
037 * @see org.aspectj.lang.reflect.AjTypeSystem
038 */
039public interface AspectJAdvisorFactory {
040
041        /**
042         * Determine whether or not the given class is an aspect, as reported
043         * by AspectJ's {@link org.aspectj.lang.reflect.AjTypeSystem}.
044         * <p>Will simply return {@code false} if the supposed aspect is
045         * invalid (such as an extension of a concrete aspect class).
046         * Will return true for some aspects that Spring AOP cannot process,
047         * such as those with unsupported instantiation models.
048         * Use the {@link #validate} method to handle these cases if necessary.
049         * @param clazz the supposed annotation-style AspectJ class
050         * @return whether or not this class is recognized by AspectJ as an aspect class
051         */
052        boolean isAspect(Class<?> clazz);
053
054        /**
055         * Is the given class a valid AspectJ aspect class?
056         * @param aspectClass the supposed AspectJ annotation-style class to validate
057         * @throws AopConfigException if the class is an invalid aspect
058         * (which can never be legal)
059         * @throws NotAnAtAspectException if the class is not an aspect at all
060         * (which may or may not be legal, depending on the context)
061         */
062        void validate(Class<?> aspectClass) throws AopConfigException;
063
064        /**
065         * Build Spring AOP Advisors for all annotated At-AspectJ methods
066         * on the specified aspect instance.
067         * @param aspectInstanceFactory the aspect instance factory
068         * (not the aspect instance itself in order to avoid eager instantiation)
069         * @return a list of advisors for this class
070         */
071        List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory);
072
073        /**
074         * Build a Spring AOP Advisor for the given AspectJ advice method.
075         * @param candidateAdviceMethod the candidate advice method
076         * @param aspectInstanceFactory the aspect instance factory
077         * @param declarationOrder the declaration order within the aspect
078         * @param aspectName the name of the aspect
079         * @return {@code null} if the method is not an AspectJ advice method
080         * or if it is a pointcut that will be used by other advice but will not
081         * create a Spring advice in its own right
082         */
083        @Nullable
084        Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
085                        int declarationOrder, String aspectName);
086
087        /**
088         * Build a Spring AOP Advice for the given AspectJ advice method.
089         * @param candidateAdviceMethod the candidate advice method
090         * @param expressionPointcut the AspectJ expression pointcut
091         * @param aspectInstanceFactory the aspect instance factory
092         * @param declarationOrder the declaration order within the aspect
093         * @param aspectName the name of the aspect
094         * @return {@code null} if the method is not an AspectJ advice method
095         * or if it is a pointcut that will be used by other advice but will not
096         * create a Spring advice in its own right
097         * @see org.springframework.aop.aspectj.AspectJAroundAdvice
098         * @see org.springframework.aop.aspectj.AspectJMethodBeforeAdvice
099         * @see org.springframework.aop.aspectj.AspectJAfterAdvice
100         * @see org.springframework.aop.aspectj.AspectJAfterReturningAdvice
101         * @see org.springframework.aop.aspectj.AspectJAfterThrowingAdvice
102         */
103        @Nullable
104        Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
105                        MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName);
106
107}