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}