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:
parent
a07dc80d72
commit
3c3e8e6a8b
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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.
|
* "interceptorNames" property.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
* @author Sam Brannen
|
||||||
* @since 10.10.2003
|
* @since 10.10.2003
|
||||||
* @see #setBeanNames
|
* @see #setBeanNames
|
||||||
* @see #isMatch
|
* @see #isMatch
|
||||||
|
@ -46,6 +47,8 @@ import org.springframework.util.StringUtils;
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
|
public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
|
||||||
|
|
||||||
|
private static final String[] NO_ALIASES = new String[0];
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private List<String> beanNames;
|
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
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
protected Object[] getAdvicesAndAdvisorsForBean(
|
protected Object[] getAdvicesAndAdvisorsForBean(
|
||||||
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
|
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) {
|
if (this.beanNames != null) {
|
||||||
|
boolean isFactoryBean = FactoryBean.class.isAssignableFrom(beanClass);
|
||||||
for (String mappedName : this.beanNames) {
|
for (String mappedName : this.beanNames) {
|
||||||
if (FactoryBean.class.isAssignableFrom(beanClass)) {
|
if (isFactoryBean) {
|
||||||
if (!mappedName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
|
if (!mappedName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mappedName = mappedName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
|
mappedName = mappedName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
|
||||||
}
|
}
|
||||||
if (isMatch(beanName, mappedName)) {
|
if (isMatch(beanName, mappedName)) {
|
||||||
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
|
return true;
|
||||||
}
|
}
|
||||||
BeanFactory beanFactory = getBeanFactory();
|
}
|
||||||
if (beanFactory != null) {
|
|
||||||
String[] aliases = beanFactory.getAliases(beanName);
|
BeanFactory beanFactory = getBeanFactory();
|
||||||
for (String alias : aliases) {
|
String[] aliases = (beanFactory != null ? beanFactory.getAliases(beanName) : NO_ALIASES);
|
||||||
if (isMatch(alias, mappedName)) {
|
for (String alias : aliases) {
|
||||||
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
|
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,
|
* <p>The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches,
|
||||||
* as well as direct equality. Can be overridden in subclasses.
|
* as well as direct equality. Can be overridden in subclasses.
|
||||||
* @param beanName the bean name to check
|
* @param beanName the bean name to check
|
||||||
|
|
|
@ -155,6 +155,16 @@ class BeanNameAutoProxyCreatorTests {
|
||||||
assertThat(((Advised)testBean).isFrozen()).isTrue();
|
assertThat(((Advised)testBean).isFrozen()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void customTargetSourceCreatorsApplyOnlyToConfiguredBeanNames() {
|
||||||
|
ITestBean lazy1 = beanFactory.getBean("lazy1", ITestBean.class);
|
||||||
|
ITestBean alias1 = beanFactory.getBean("lazy1alias", ITestBean.class);
|
||||||
|
ITestBean lazy2 = beanFactory.getBean("lazy2", ITestBean.class);
|
||||||
|
assertThat(AopUtils.isAopProxy(lazy1)).isTrue();
|
||||||
|
assertThat(AopUtils.isAopProxy(alias1)).isTrue();
|
||||||
|
assertThat(AopUtils.isAopProxy(lazy2)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void jdkAssertions(ITestBean tb, int nopInterceptorCount) {
|
private void jdkAssertions(ITestBean tb, int nopInterceptorCount) {
|
||||||
NopInterceptor nop = (NopInterceptor) beanFactory.getBean("nopInterceptor");
|
NopInterceptor nop = (NopInterceptor) beanFactory.getBean("nopInterceptor");
|
||||||
|
|
|
@ -104,4 +104,28 @@
|
||||||
<property name="name" value="noproxy" />
|
<property name="name" value="noproxy" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="lazy1" class="org.springframework.beans.testfixture.beans.TestBean" lazy-init="true">
|
||||||
|
<property name="name" value="lazy1" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<alias name="lazy1" alias="lazy1alias"/>
|
||||||
|
|
||||||
|
<bean id="lazy2" class="org.springframework.beans.testfixture.beans.TestBean" lazy-init="true">
|
||||||
|
<property name="name" value="lazy2" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="lazyBeanNameAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
|
||||||
|
<property name="beanNames" value="lazy1" />
|
||||||
|
<property name="customTargetSourceCreators">
|
||||||
|
<bean class="org.springframework.aop.framework.autoproxy.target.LazyInitTargetSourceCreator" />
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="lazyAliasBeanNameAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
|
||||||
|
<property name="beanNames" value="lazy1alias" />
|
||||||
|
<property name="customTargetSourceCreators">
|
||||||
|
<bean class="org.springframework.aop.framework.autoproxy.target.LazyInitTargetSourceCreator" />
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
|
Loading…
Reference in New Issue