001/*
002 * Copyright 2002-2019 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.autoproxy;
018
019import java.lang.reflect.Constructor;
020import java.util.ArrayList;
021import java.util.Arrays;
022import java.util.Collections;
023import java.util.List;
024import java.util.Map;
025import java.util.Set;
026import java.util.concurrent.ConcurrentHashMap;
027
028import org.aopalliance.aop.Advice;
029import org.apache.commons.logging.Log;
030import org.apache.commons.logging.LogFactory;
031
032import org.springframework.aop.Advisor;
033import org.springframework.aop.Pointcut;
034import org.springframework.aop.TargetSource;
035import org.springframework.aop.framework.AopInfrastructureBean;
036import org.springframework.aop.framework.ProxyFactory;
037import org.springframework.aop.framework.ProxyProcessorSupport;
038import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry;
039import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
040import org.springframework.aop.target.SingletonTargetSource;
041import org.springframework.beans.BeansException;
042import org.springframework.beans.PropertyValues;
043import org.springframework.beans.factory.BeanFactory;
044import org.springframework.beans.factory.BeanFactoryAware;
045import org.springframework.beans.factory.FactoryBean;
046import org.springframework.beans.factory.config.ConfigurableBeanFactory;
047import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
048import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
049import org.springframework.lang.Nullable;
050import org.springframework.util.Assert;
051import org.springframework.util.StringUtils;
052
053/**
054 * {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
055 * that wraps each eligible bean with an AOP proxy, delegating to specified interceptors
056 * before invoking the bean itself.
057 *
058 * <p>This class distinguishes between "common" interceptors: shared for all proxies it
059 * creates, and "specific" interceptors: unique per bean instance. There need not be any
060 * common interceptors. If there are, they are set using the interceptorNames property.
061 * As with {@link org.springframework.aop.framework.ProxyFactoryBean}, interceptors names
062 * in the current factory are used rather than bean references to allow correct handling
063 * of prototype advisors and interceptors: for example, to support stateful mixins.
064 * Any advice type is supported for {@link #setInterceptorNames "interceptorNames"} entries.
065 *
066 * <p>Such auto-proxying is particularly useful if there's a large number of beans that
067 * need to be wrapped with similar proxies, i.e. delegating to the same interceptors.
068 * Instead of x repetitive proxy definitions for x target beans, you can register
069 * one single such post processor with the bean factory to achieve the same effect.
070 *
071 * <p>Subclasses can apply any strategy to decide if a bean is to be proxied, e.g. by type,
072 * by name, by definition details, etc. They can also return additional interceptors that
073 * should just be applied to the specific bean instance. A simple concrete implementation is
074 * {@link BeanNameAutoProxyCreator}, identifying the beans to be proxied via given names.
075 *
076 * <p>Any number of {@link TargetSourceCreator} implementations can be used to create
077 * a custom target source: for example, to pool prototype objects. Auto-proxying will
078 * occur even if there is no advice, as long as a TargetSourceCreator specifies a custom
079 * {@link org.springframework.aop.TargetSource}. If there are no TargetSourceCreators set,
080 * or if none matches, a {@link org.springframework.aop.target.SingletonTargetSource}
081 * will be used by default to wrap the target bean instance.
082 *
083 * @author Juergen Hoeller
084 * @author Rod Johnson
085 * @author Rob Harrop
086 * @since 13.10.2003
087 * @see #setInterceptorNames
088 * @see #getAdvicesAndAdvisorsForBean
089 * @see BeanNameAutoProxyCreator
090 * @see DefaultAdvisorAutoProxyCreator
091 */
092@SuppressWarnings("serial")
093public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
094                implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
095
096        /**
097         * Convenience constant for subclasses: Return value for "do not proxy".
098         * @see #getAdvicesAndAdvisorsForBean
099         */
100        @Nullable
101        protected static final Object[] DO_NOT_PROXY = null;
102
103        /**
104         * Convenience constant for subclasses: Return value for
105         * "proxy without additional interceptors, just the common ones".
106         * @see #getAdvicesAndAdvisorsForBean
107         */
108        protected static final Object[] PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS = new Object[0];
109
110
111        /** Logger available to subclasses. */
112        protected final Log logger = LogFactory.getLog(getClass());
113
114        /** Default is global AdvisorAdapterRegistry. */
115        private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
116
117        /**
118         * Indicates whether or not the proxy should be frozen. Overridden from super
119         * to prevent the configuration from becoming frozen too early.
120         */
121        private boolean freezeProxy = false;
122
123        /** Default is no common interceptors. */
124        private String[] interceptorNames = new String[0];
125
126        private boolean applyCommonInterceptorsFirst = true;
127
128        @Nullable
129        private TargetSourceCreator[] customTargetSourceCreators;
130
131        @Nullable
132        private BeanFactory beanFactory;
133
134        private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
135
136        private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);
137
138        private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16);
139
140        private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);
141
142
143        /**
144         * Set whether or not the proxy should be frozen, preventing advice
145         * from being added to it once it is created.
146         * <p>Overridden from the super class to prevent the proxy configuration
147         * from being frozen before the proxy is created.
148         */
149        @Override
150        public void setFrozen(boolean frozen) {
151                this.freezeProxy = frozen;
152        }
153
154        @Override
155        public boolean isFrozen() {
156                return this.freezeProxy;
157        }
158
159        /**
160         * Specify the {@link AdvisorAdapterRegistry} to use.
161         * <p>Default is the global {@link AdvisorAdapterRegistry}.
162         * @see org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry
163         */
164        public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) {
165                this.advisorAdapterRegistry = advisorAdapterRegistry;
166        }
167
168        /**
169         * Set custom {@code TargetSourceCreators} to be applied in this order.
170         * If the list is empty, or they all return null, a {@link SingletonTargetSource}
171         * will be created for each bean.
172         * <p>Note that TargetSourceCreators will kick in even for target beans
173         * where no advices or advisors have been found. If a {@code TargetSourceCreator}
174         * returns a {@link TargetSource} for a specific bean, that bean will be proxied
175         * in any case.
176         * <p>{@code TargetSourceCreators} can only be invoked if this post processor is used
177         * in a {@link BeanFactory} and its {@link BeanFactoryAware} callback is triggered.
178         * @param targetSourceCreators the list of {@code TargetSourceCreators}.
179         * Ordering is significant: The {@code TargetSource} returned from the first matching
180         * {@code TargetSourceCreator} (that is, the first that returns non-null) will be used.
181         */
182        public void setCustomTargetSourceCreators(TargetSourceCreator... targetSourceCreators) {
183                this.customTargetSourceCreators = targetSourceCreators;
184        }
185
186        /**
187         * Set the common interceptors. These must be bean names in the current factory.
188         * They can be of any advice or advisor type Spring supports.
189         * <p>If this property isn't set, there will be zero common interceptors.
190         * This is perfectly valid, if "specific" interceptors such as matching
191         * Advisors are all we want.
192         */
193        public void setInterceptorNames(String... interceptorNames) {
194                this.interceptorNames = interceptorNames;
195        }
196
197        /**
198         * Set whether the common interceptors should be applied before bean-specific ones.
199         * Default is "true"; else, bean-specific interceptors will get applied first.
200         */
201        public void setApplyCommonInterceptorsFirst(boolean applyCommonInterceptorsFirst) {
202                this.applyCommonInterceptorsFirst = applyCommonInterceptorsFirst;
203        }
204
205        @Override
206        public void setBeanFactory(BeanFactory beanFactory) {
207                this.beanFactory = beanFactory;
208        }
209
210        /**
211         * Return the owning {@link BeanFactory}.
212         * May be {@code null}, as this post-processor doesn't need to belong to a bean factory.
213         */
214        @Nullable
215        protected BeanFactory getBeanFactory() {
216                return this.beanFactory;
217        }
218
219
220        @Override
221        @Nullable
222        public Class<?> predictBeanType(Class<?> beanClass, String beanName) {
223                if (this.proxyTypes.isEmpty()) {
224                        return null;
225                }
226                Object cacheKey = getCacheKey(beanClass, beanName);
227                return this.proxyTypes.get(cacheKey);
228        }
229
230        @Override
231        @Nullable
232        public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) {
233                return null;
234        }
235
236        @Override
237        public Object getEarlyBeanReference(Object bean, String beanName) {
238                Object cacheKey = getCacheKey(bean.getClass(), beanName);
239                this.earlyProxyReferences.put(cacheKey, bean);
240                return wrapIfNecessary(bean, beanName, cacheKey);
241        }
242
243        @Override
244        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
245                Object cacheKey = getCacheKey(beanClass, beanName);
246
247                if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
248                        if (this.advisedBeans.containsKey(cacheKey)) {
249                                return null;
250                        }
251                        if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
252                                this.advisedBeans.put(cacheKey, Boolean.FALSE);
253                                return null;
254                        }
255                }
256
257                // Create proxy here if we have a custom TargetSource.
258                // Suppresses unnecessary default instantiation of the target bean:
259                // The TargetSource will handle target instances in a custom fashion.
260                TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
261                if (targetSource != null) {
262                        if (StringUtils.hasLength(beanName)) {
263                                this.targetSourcedBeans.add(beanName);
264                        }
265                        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
266                        Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
267                        this.proxyTypes.put(cacheKey, proxy.getClass());
268                        return proxy;
269                }
270
271                return null;
272        }
273
274        @Override
275        public boolean postProcessAfterInstantiation(Object bean, String beanName) {
276                return true;
277        }
278
279        @Override
280        public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
281                return pvs;
282        }
283
284        @Override
285        public Object postProcessBeforeInitialization(Object bean, String beanName) {
286                return bean;
287        }
288
289        /**
290         * Create a proxy with the configured interceptors if the bean is
291         * identified as one to proxy by the subclass.
292         * @see #getAdvicesAndAdvisorsForBean
293         */
294        @Override
295        public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
296                if (bean != null) {
297                        Object cacheKey = getCacheKey(bean.getClass(), beanName);
298                        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
299                                return wrapIfNecessary(bean, beanName, cacheKey);
300                        }
301                }
302                return bean;
303        }
304
305
306        /**
307         * Build a cache key for the given bean class and bean name.
308         * <p>Note: As of 4.2.3, this implementation does not return a concatenated
309         * class/name String anymore but rather the most efficient cache key possible:
310         * a plain bean name, prepended with {@link BeanFactory#FACTORY_BEAN_PREFIX}
311         * in case of a {@code FactoryBean}; or if no bean name specified, then the
312         * given bean {@code Class} as-is.
313         * @param beanClass the bean class
314         * @param beanName the bean name
315         * @return the cache key for the given class and name
316         */
317        protected Object getCacheKey(Class<?> beanClass, @Nullable String beanName) {
318                if (StringUtils.hasLength(beanName)) {
319                        return (FactoryBean.class.isAssignableFrom(beanClass) ?
320                                        BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
321                }
322                else {
323                        return beanClass;
324                }
325        }
326
327        /**
328         * Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
329         * @param bean the raw bean instance
330         * @param beanName the name of the bean
331         * @param cacheKey the cache key for metadata access
332         * @return a proxy wrapping the bean, or the raw bean instance as-is
333         */
334        protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
335                if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
336                        return bean;
337                }
338                if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
339                        return bean;
340                }
341                if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
342                        this.advisedBeans.put(cacheKey, Boolean.FALSE);
343                        return bean;
344                }
345
346                // Create proxy if we have advice.
347                Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
348                if (specificInterceptors != DO_NOT_PROXY) {
349                        this.advisedBeans.put(cacheKey, Boolean.TRUE);
350                        Object proxy = createProxy(
351                                        bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
352                        this.proxyTypes.put(cacheKey, proxy.getClass());
353                        return proxy;
354                }
355
356                this.advisedBeans.put(cacheKey, Boolean.FALSE);
357                return bean;
358        }
359
360        /**
361         * Return whether the given bean class represents an infrastructure class
362         * that should never be proxied.
363         * <p>The default implementation considers Advices, Advisors and
364         * AopInfrastructureBeans as infrastructure classes.
365         * @param beanClass the class of the bean
366         * @return whether the bean represents an infrastructure class
367         * @see org.aopalliance.aop.Advice
368         * @see org.springframework.aop.Advisor
369         * @see org.springframework.aop.framework.AopInfrastructureBean
370         * @see #shouldSkip
371         */
372        protected boolean isInfrastructureClass(Class<?> beanClass) {
373                boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
374                                Pointcut.class.isAssignableFrom(beanClass) ||
375                                Advisor.class.isAssignableFrom(beanClass) ||
376                                AopInfrastructureBean.class.isAssignableFrom(beanClass);
377                if (retVal && logger.isTraceEnabled()) {
378                        logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
379                }
380                return retVal;
381        }
382
383        /**
384         * Subclasses should override this method to return {@code true} if the
385         * given bean should not be considered for auto-proxying by this post-processor.
386         * <p>Sometimes we need to be able to avoid this happening, e.g. if it will lead to
387         * a circular reference or if the existing target instance needs to be preserved.
388         * This implementation returns {@code false} unless the bean name indicates an
389         * "original instance" according to {@code AutowireCapableBeanFactory} conventions.
390         * @param beanClass the class of the bean
391         * @param beanName the name of the bean
392         * @return whether to skip the given bean
393         * @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#ORIGINAL_INSTANCE_SUFFIX
394         */
395        protected boolean shouldSkip(Class<?> beanClass, String beanName) {
396                return AutoProxyUtils.isOriginalInstance(beanName, beanClass);
397        }
398
399        /**
400         * Create a target source for bean instances. Uses any TargetSourceCreators if set.
401         * Returns {@code null} if no custom TargetSource should be used.
402         * <p>This implementation uses the "customTargetSourceCreators" property.
403         * Subclasses can override this method to use a different mechanism.
404         * @param beanClass the class of the bean to create a TargetSource for
405         * @param beanName the name of the bean
406         * @return a TargetSource for this bean
407         * @see #setCustomTargetSourceCreators
408         */
409        @Nullable
410        protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
411                // We can't create fancy target sources for directly registered singletons.
412                if (this.customTargetSourceCreators != null &&
413                                this.beanFactory != null && this.beanFactory.containsBean(beanName)) {
414                        for (TargetSourceCreator tsc : this.customTargetSourceCreators) {
415                                TargetSource ts = tsc.getTargetSource(beanClass, beanName);
416                                if (ts != null) {
417                                        // Found a matching TargetSource.
418                                        if (logger.isTraceEnabled()) {
419                                                logger.trace("TargetSourceCreator [" + tsc +
420                                                                "] found custom TargetSource for bean with name '" + beanName + "'");
421                                        }
422                                        return ts;
423                                }
424                        }
425                }
426
427                // No custom TargetSource found.
428                return null;
429        }
430
431        /**
432         * Create an AOP proxy for the given bean.
433         * @param beanClass the class of the bean
434         * @param beanName the name of the bean
435         * @param specificInterceptors the set of interceptors that is
436         * specific to this bean (may be empty, but not null)
437         * @param targetSource the TargetSource for the proxy,
438         * already pre-configured to access the bean
439         * @return the AOP proxy for the bean
440         * @see #buildAdvisors
441         */
442        protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
443                        @Nullable Object[] specificInterceptors, TargetSource targetSource) {
444
445                if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
446                        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
447                }
448
449                ProxyFactory proxyFactory = new ProxyFactory();
450                proxyFactory.copyFrom(this);
451
452                if (!proxyFactory.isProxyTargetClass()) {
453                        if (shouldProxyTargetClass(beanClass, beanName)) {
454                                proxyFactory.setProxyTargetClass(true);
455                        }
456                        else {
457                                evaluateProxyInterfaces(beanClass, proxyFactory);
458                        }
459                }
460
461                Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
462                proxyFactory.addAdvisors(advisors);
463                proxyFactory.setTargetSource(targetSource);
464                customizeProxyFactory(proxyFactory);
465
466                proxyFactory.setFrozen(this.freezeProxy);
467                if (advisorsPreFiltered()) {
468                        proxyFactory.setPreFiltered(true);
469                }
470
471                return proxyFactory.getProxy(getProxyClassLoader());
472        }
473
474        /**
475         * Determine whether the given bean should be proxied with its target class rather than its interfaces.
476         * <p>Checks the {@link AutoProxyUtils#PRESERVE_TARGET_CLASS_ATTRIBUTE "preserveTargetClass" attribute}
477         * of the corresponding bean definition.
478         * @param beanClass the class of the bean
479         * @param beanName the name of the bean
480         * @return whether the given bean should be proxied with its target class
481         * @see AutoProxyUtils#shouldProxyTargetClass
482         */
483        protected boolean shouldProxyTargetClass(Class<?> beanClass, @Nullable String beanName) {
484                return (this.beanFactory instanceof ConfigurableListableBeanFactory &&
485                                AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName));
486        }
487
488        /**
489         * Return whether the Advisors returned by the subclass are pre-filtered
490         * to match the bean's target class already, allowing the ClassFilter check
491         * to be skipped when building advisors chains for AOP invocations.
492         * <p>Default is {@code false}. Subclasses may override this if they
493         * will always return pre-filtered Advisors.
494         * @return whether the Advisors are pre-filtered
495         * @see #getAdvicesAndAdvisorsForBean
496         * @see org.springframework.aop.framework.Advised#setPreFiltered
497         */
498        protected boolean advisorsPreFiltered() {
499                return false;
500        }
501
502        /**
503         * Determine the advisors for the given bean, including the specific interceptors
504         * as well as the common interceptor, all adapted to the Advisor interface.
505         * @param beanName the name of the bean
506         * @param specificInterceptors the set of interceptors that is
507         * specific to this bean (may be empty, but not null)
508         * @return the list of Advisors for the given bean
509         */
510        protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
511                // Handle prototypes correctly...
512                Advisor[] commonInterceptors = resolveInterceptorNames();
513
514                List<Object> allInterceptors = new ArrayList<>();
515                if (specificInterceptors != null) {
516                        allInterceptors.addAll(Arrays.asList(specificInterceptors));
517                        if (commonInterceptors.length > 0) {
518                                if (this.applyCommonInterceptorsFirst) {
519                                        allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
520                                }
521                                else {
522                                        allInterceptors.addAll(Arrays.asList(commonInterceptors));
523                                }
524                        }
525                }
526                if (logger.isTraceEnabled()) {
527                        int nrOfCommonInterceptors = commonInterceptors.length;
528                        int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
529                        logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
530                                        " common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
531                }
532
533                Advisor[] advisors = new Advisor[allInterceptors.size()];
534                for (int i = 0; i < allInterceptors.size(); i++) {
535                        advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
536                }
537                return advisors;
538        }
539
540        /**
541         * Resolves the specified interceptor names to Advisor objects.
542         * @see #setInterceptorNames
543         */
544        private Advisor[] resolveInterceptorNames() {
545                BeanFactory bf = this.beanFactory;
546                ConfigurableBeanFactory cbf = (bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) bf : null);
547                List<Advisor> advisors = new ArrayList<>();
548                for (String beanName : this.interceptorNames) {
549                        if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) {
550                                Assert.state(bf != null, "BeanFactory required for resolving interceptor names");
551                                Object next = bf.getBean(beanName);
552                                advisors.add(this.advisorAdapterRegistry.wrap(next));
553                        }
554                }
555                return advisors.toArray(new Advisor[0]);
556        }
557
558        /**
559         * Subclasses may choose to implement this: for example,
560         * to change the interfaces exposed.
561         * <p>The default implementation is empty.
562         * @param proxyFactory a ProxyFactory that is already configured with
563         * TargetSource and interfaces and will be used to create the proxy
564         * immediately after this method returns
565         */
566        protected void customizeProxyFactory(ProxyFactory proxyFactory) {
567        }
568
569
570        /**
571         * Return whether the given bean is to be proxied, what additional
572         * advices (e.g. AOP Alliance interceptors) and advisors to apply.
573         * @param beanClass the class of the bean to advise
574         * @param beanName the name of the bean
575         * @param customTargetSource the TargetSource returned by the
576         * {@link #getCustomTargetSource} method: may be ignored.
577         * Will be {@code null} if no custom target source is in use.
578         * @return an array of additional interceptors for the particular bean;
579         * or an empty array if no additional interceptors but just the common ones;
580         * or {@code null} if no proxy at all, not even with the common interceptors.
581         * See constants DO_NOT_PROXY and PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS.
582         * @throws BeansException in case of errors
583         * @see #DO_NOT_PROXY
584         * @see #PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS
585         */
586        @Nullable
587        protected abstract Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName,
588                        @Nullable TargetSource customTargetSource) throws BeansException;
589
590}