001/*
002 * Copyright 2002-2018 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.framework;
018
019import org.aopalliance.aop.Advice;
020
021import org.springframework.aop.Advisor;
022import org.springframework.aop.TargetClassAware;
023import org.springframework.aop.TargetSource;
024
025/**
026 * Interface to be implemented by classes that hold the configuration
027 * of a factory of AOP proxies. This configuration includes the
028 * Interceptors and other advice, Advisors, and the proxied interfaces.
029 *
030 * <p>Any AOP proxy obtained from Spring can be cast to this interface to
031 * allow manipulation of its AOP advice.
032 *
033 * @author Rod Johnson
034 * @author Juergen Hoeller
035 * @since 13.03.2003
036 * @see org.springframework.aop.framework.AdvisedSupport
037 */
038public interface Advised extends TargetClassAware {
039
040        /**
041         * Return whether the Advised configuration is frozen,
042         * in which case no advice changes can be made.
043         */
044        boolean isFrozen();
045
046        /**
047         * Are we proxying the full target class instead of specified interfaces?
048         */
049        boolean isProxyTargetClass();
050
051        /**
052         * Return the interfaces proxied by the AOP proxy.
053         * <p>Will not include the target class, which may also be proxied.
054         */
055        Class<?>[] getProxiedInterfaces();
056
057        /**
058         * Determine whether the given interface is proxied.
059         * @param intf the interface to check
060         */
061        boolean isInterfaceProxied(Class<?> intf);
062
063        /**
064         * Change the {@code TargetSource} used by this {@code Advised} object.
065         * <p>Only works if the configuration isn't {@linkplain #isFrozen frozen}.
066         * @param targetSource new TargetSource to use
067         */
068        void setTargetSource(TargetSource targetSource);
069
070        /**
071         * Return the {@code TargetSource} used by this {@code Advised} object.
072         */
073        TargetSource getTargetSource();
074
075        /**
076         * Set whether the proxy should be exposed by the AOP framework as a
077         * {@link ThreadLocal} for retrieval via the {@link AopContext} class.
078         * <p>It can be necessary to expose the proxy if an advised object needs
079         * to invoke a method on itself with advice applied. Otherwise, if an
080         * advised object invokes a method on {@code this}, no advice will be applied.
081         * <p>Default is {@code false}, for optimal performance.
082         */
083        void setExposeProxy(boolean exposeProxy);
084
085        /**
086         * Return whether the factory should expose the proxy as a {@link ThreadLocal}.
087         * <p>It can be necessary to expose the proxy if an advised object needs
088         * to invoke a method on itself with advice applied. Otherwise, if an
089         * advised object invokes a method on {@code this}, no advice will be applied.
090         * <p>Getting the proxy is analogous to an EJB calling {@code getEJBObject()}.
091         * @see AopContext
092         */
093        boolean isExposeProxy();
094
095        /**
096         * Set whether this proxy configuration is pre-filtered so that it only
097         * contains applicable advisors (matching this proxy's target class).
098         * <p>Default is "false". Set this to "true" if the advisors have been
099         * pre-filtered already, meaning that the ClassFilter check can be skipped
100         * when building the actual advisor chain for proxy invocations.
101         * @see org.springframework.aop.ClassFilter
102         */
103        void setPreFiltered(boolean preFiltered);
104
105        /**
106         * Return whether this proxy configuration is pre-filtered so that it only
107         * contains applicable advisors (matching this proxy's target class).
108         */
109        boolean isPreFiltered();
110
111        /**
112         * Return the advisors applying to this proxy.
113         * @return a list of Advisors applying to this proxy (never {@code null})
114         */
115        Advisor[] getAdvisors();
116
117        /**
118         * Add an advisor at the end of the advisor chain.
119         * <p>The Advisor may be an {@link org.springframework.aop.IntroductionAdvisor},
120         * in which new interfaces will be available when a proxy is next obtained
121         * from the relevant factory.
122         * @param advisor the advisor to add to the end of the chain
123         * @throws AopConfigException in case of invalid advice
124         */
125        void addAdvisor(Advisor advisor) throws AopConfigException;
126
127        /**
128         * Add an Advisor at the specified position in the chain.
129         * @param advisor the advisor to add at the specified position in the chain
130         * @param pos position in chain (0 is head). Must be valid.
131         * @throws AopConfigException in case of invalid advice
132         */
133        void addAdvisor(int pos, Advisor advisor) throws AopConfigException;
134
135        /**
136         * Remove the given advisor.
137         * @param advisor the advisor to remove
138         * @return {@code true} if the advisor was removed; {@code false}
139         * if the advisor was not found and hence could not be removed
140         */
141        boolean removeAdvisor(Advisor advisor);
142
143        /**
144         * Remove the advisor at the given index.
145         * @param index the index of advisor to remove
146         * @throws AopConfigException if the index is invalid
147         */
148        void removeAdvisor(int index) throws AopConfigException;
149
150        /**
151         * Return the index (from 0) of the given advisor,
152         * or -1 if no such advisor applies to this proxy.
153         * <p>The return value of this method can be used to index into the advisors array.
154         * @param advisor the advisor to search for
155         * @return index from 0 of this advisor, or -1 if there's no such advisor
156         */
157        int indexOf(Advisor advisor);
158
159        /**
160         * Replace the given advisor.
161         * <p><b>Note:</b> If the advisor is an {@link org.springframework.aop.IntroductionAdvisor}
162         * and the replacement is not or implements different interfaces, the proxy will need
163         * to be re-obtained or the old interfaces won't be supported and the new interface
164         * won't be implemented.
165         * @param a the advisor to replace
166         * @param b the advisor to replace it with
167         * @return whether it was replaced. If the advisor wasn't found in the
168         * list of advisors, this method returns {@code false} and does nothing.
169         * @throws AopConfigException in case of invalid advice
170         */
171        boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException;
172
173        /**
174         * Add the given AOP Alliance advice to the tail of the advice (interceptor) chain.
175         * <p>This will be wrapped in a DefaultPointcutAdvisor with a pointcut that always
176         * applies, and returned from the {@code getAdvisors()} method in this wrapped form.
177         * <p>Note that the given advice will apply to all invocations on the proxy,
178         * even to the {@code toString()} method! Use appropriate advice implementations
179         * or specify appropriate pointcuts to apply to a narrower set of methods.
180         * @param advice the advice to add to the tail of the chain
181         * @throws AopConfigException in case of invalid advice
182         * @see #addAdvice(int, Advice)
183         * @see org.springframework.aop.support.DefaultPointcutAdvisor
184         */
185        void addAdvice(Advice advice) throws AopConfigException;
186
187        /**
188         * Add the given AOP Alliance Advice at the specified position in the advice chain.
189         * <p>This will be wrapped in a {@link org.springframework.aop.support.DefaultPointcutAdvisor}
190         * with a pointcut that always applies, and returned from the {@link #getAdvisors()}
191         * method in this wrapped form.
192         * <p>Note: The given advice will apply to all invocations on the proxy,
193         * even to the {@code toString()} method! Use appropriate advice implementations
194         * or specify appropriate pointcuts to apply to a narrower set of methods.
195         * @param pos index from 0 (head)
196         * @param advice the advice to add at the specified position in the advice chain
197         * @throws AopConfigException in case of invalid advice
198         */
199        void addAdvice(int pos, Advice advice) throws AopConfigException;
200
201        /**
202         * Remove the Advisor containing the given advice.
203         * @param advice the advice to remove
204         * @return {@code true} of the advice was found and removed;
205         * {@code false} if there was no such advice
206         */
207        boolean removeAdvice(Advice advice);
208
209        /**
210         * Return the index (from 0) of the given AOP Alliance Advice,
211         * or -1 if no such advice is an advice for this proxy.
212         * <p>The return value of this method can be used to index into
213         * the advisors array.
214         * @param advice the AOP Alliance advice to search for
215         * @return index from 0 of this advice, or -1 if there's no such advice
216         */
217        int indexOf(Advice advice);
218
219        /**
220         * As {@code toString()} will normally be delegated to the target,
221         * this returns the equivalent for the AOP proxy.
222         * @return a string description of the proxy configuration
223         */
224        String toProxyConfigString();
225
226}