question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

BeanNameAutoProxyCreator proxies the wrong beans when custom TargetSourceCreator specified

See original GitHub issue

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 {
    }
}

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
kennymacleodcommented, May 12, 2020

Speaking of which, are you hoping to see this fix applied to 5.2.7 or any earlier branches?

That was my hope, but I appreciate that this is old code, old enough as you say that people my be relying on the “broken” behaviour, which makes it hard to back-port.

0reactions
sbrannencommented, May 12, 2020

Thanks for the feedback, @kennymacleod.

This has been addressed in 3c3e8e6a8bfd45e8f1c3f1df5c7ef66d85d5d5f1 for Spring Framework 5.3.

Read more comments on GitHub >

github_iconTop Results From Across the Web

AbstractAutoProxyCreator (Spring Framework 6.0.2 API)
A simple concrete implementation is BeanNameAutoProxyCreator , identifying the beans to be proxied via given names. Any number of TargetSourceCreator ...
Read more >
AbstractAutoProxyCreator (Atlassian Confluence 6.0.1 API)
Create a proxy with the configured interceptors if the bean is identified as one to proxy ... Set custom TargetSourceCreators to be applied...
Read more >
Spring Framework example - LazyInitTargetSourceCreator.java
<p>To be registered as custom TargetSourceCreator for an auto-proxy creator, * in combination with custom interceptors for specific beans or for the ...
Read more >
"Fossies" - the Fresh Open Source Software Archive
71 * Instead of x repetitive proxy definitions for x target beans, ... of {@link TargetSourceCreator} implementations can be used to create 80...
Read more >
org.springframework.aop.framework.autoproxy ...
Instead of x repetitive proxy definitions for x target beans, ... If a TargetSourceCreator * returns a TargetSource for a specific bean, that...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found