Only proxy supported beans in BeanNameAutoProxyCreator
Prior to this commit, if a BeanNameAutoProxyCreator was configured with a custom TargetSourceCreator, the TargetSourceCreator was applied to all beans in the ApplicationContext. Thus, the list of supported beanNames was effectively ignored when applying any TargetSourceCreator. Consequently, if a TargetSourceCreator returned a non-null TargetSource for a given bean, the BeanNameAutoProxyCreator proxied the bean even if the bean name had not been configured in the beanNames list. This commit addresses this issue by ensuring that a custom TargetSourceCreator is only applied to beans whose names match the configured beanNames list in a BeanNameAutoProxyCreator. Closes gh-24915
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,6 +37,7 @@ import org.springframework.util.StringUtils;
|
||||
* "interceptorNames" property.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 10.10.2003
|
||||
* @see #setBeanNames
|
||||
* @see #isMatch
|
||||
@@ -46,6 +47,8 @@ import org.springframework.util.StringUtils;
|
||||
@SuppressWarnings("serial")
|
||||
public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
|
||||
|
||||
private static final String[] NO_ALIASES = new String[0];
|
||||
|
||||
@Nullable
|
||||
private List<String> beanNames;
|
||||
|
||||
@@ -72,40 +75,70 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
|
||||
|
||||
|
||||
/**
|
||||
* Identify as bean to proxy if the bean name is in the configured list of names.
|
||||
* Delegate to {@link AbstractAutoProxyCreator#getCustomTargetSource(Class, String)}
|
||||
* if the bean name matches one of the names in the configured list of supported
|
||||
* names, returning {@code null} otherwise.
|
||||
* @since 5.3
|
||||
* @see #setBeanNames(String...)
|
||||
*/
|
||||
@Override
|
||||
protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
|
||||
return (isSupportedBeanName(beanClass, beanName) ?
|
||||
super.getCustomTargetSource(beanClass, beanName) : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify as a bean to proxy if the bean name matches one of the names in
|
||||
* the configured list of supported names.
|
||||
* @see #setBeanNames(String...)
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
protected Object[] getAdvicesAndAdvisorsForBean(
|
||||
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
|
||||
|
||||
return (isSupportedBeanName(beanClass, beanName) ?
|
||||
PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS : DO_NOT_PROXY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the bean name for the given bean class matches one of the names
|
||||
* in the configured list of supported names.
|
||||
* @param beanClass the class of the bean to advise
|
||||
* @param beanName the name of the bean
|
||||
* @return {@code true} if the given bean name is supported
|
||||
* @see #setBeanNames(String...)
|
||||
*/
|
||||
private boolean isSupportedBeanName(Class<?> beanClass, String beanName) {
|
||||
if (this.beanNames != null) {
|
||||
boolean isFactoryBean = FactoryBean.class.isAssignableFrom(beanClass);
|
||||
for (String mappedName : this.beanNames) {
|
||||
if (FactoryBean.class.isAssignableFrom(beanClass)) {
|
||||
if (isFactoryBean) {
|
||||
if (!mappedName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
|
||||
continue;
|
||||
}
|
||||
mappedName = mappedName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
|
||||
}
|
||||
if (isMatch(beanName, mappedName)) {
|
||||
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
|
||||
return true;
|
||||
}
|
||||
BeanFactory beanFactory = getBeanFactory();
|
||||
if (beanFactory != null) {
|
||||
String[] aliases = beanFactory.getAliases(beanName);
|
||||
for (String alias : aliases) {
|
||||
if (isMatch(alias, mappedName)) {
|
||||
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
|
||||
}
|
||||
}
|
||||
|
||||
BeanFactory beanFactory = getBeanFactory();
|
||||
String[] aliases = (beanFactory != null ? beanFactory.getAliases(beanName) : NO_ALIASES);
|
||||
for (String alias : aliases) {
|
||||
for (String mappedName : this.beanNames) {
|
||||
if (isMatch(alias, mappedName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return DO_NOT_PROXY;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if the given bean name matches the mapped name.
|
||||
* Determine if the given bean name matches the mapped name.
|
||||
* <p>The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches,
|
||||
* as well as direct equality. Can be overridden in subclasses.
|
||||
* @param beanName the bean name to check
|
||||
|
||||
Reference in New Issue
Block a user