Skip to content

BeanNameAutoProxyCreator proxies the wrong beans when custom TargetSourceCreator specified  #24915

Closed
@kennymacleod

Description

@kennymacleod

Spring 5.1.8 (but also probably earlier versions)

Short version: if you use BeanNameAutoProxyCreator with a custom TargetSourceCreator, you'll get proxies created for all of your beans, not just the ones listed in the beanNames property.

Longer version: BeanNameAutoProxyCreator allows you to specify the beanNames for which you want proxies to be created. It also allows you to specify one of more TargetSourceCreators. However, the TargetSourceCreator will be asked to create TargetSource for every bean in the context, not just the beans listed in beanNames.

To reproduce the problem, I created a simple context with 2 beans and a unit test (see below). The context contains a BeanNameAutoProxyCreator and specifies that only beanA should be proxied. Both beanA and beanB are declared as lazy-init, and I've specified a LazyInitTargetSourceCreator to be used (the lazy-init-ness isn't particularly important, it's just an off-the-shelf implementation of TargetSourceCreator that demonstrates the problem).

The unit test asserts that BeanA is a proxy and beanB is not, but then fails because both beans have been proxied.

This is at the very least unexpected and confusing (and should be documented), and is probably a bug. The TargetSourceCreator is being asked for a TargetSource for every bean in the context, without checking for which beans should be candidates for being proxied.

<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="beanA" class="test.BeanNameAutoProxyBugTest.ClassA" lazy-init="true"/>
    <bean id="beanB" class="test.BeanNameAutoProxyBugTest.ClassB" lazy-init="true"/>

    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <property name="beanNames" value="beanA"/>
        <property name="customTargetSourceCreators">
            <bean class="org.springframework.aop.framework.autoproxy.target.LazyInitTargetSourceCreator"/>
        </property>
    </bean>
</beans>
package test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.aop.SpringProxy;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;

import javax.inject.Inject;

import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/context.xml")
@TestExecutionListeners(DependencyInjectionTestExecutionListener.class)
public class BeanNameAutoProxyBugTest {

    @Inject
    ClassA beanA;

    @Inject
    ClassB beanB;

    @Test
    public void test() {
        assertThat("beanA should be proxied", beanA, instanceOf(SpringProxy.class));
        assertThat("beanB should not be proxied", beanB, not(instanceOf(SpringProxy.class)));
    }

    static class ClassA {
    }

    static class ClassB {
    }
}

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions