Skip to content

Have HotSwappableTargetSource.swap() take effect immediately if called within an interceptor [SPR-1238] #5941

Closed
@spring-projects-issues

Description

@spring-projects-issues

Ryan Stone opened SPR-1238 and commented

In the following code, in a MethodInterceptor, the target of the of the proxy is swapped with a HotSwappableTargetSource. However, when you call MethodInvocation.proceed(), the old target is still used for the current invocation. In subsequent invocations, the new target will be used.

//This interceptor:
public class TestCaseInterceptor implements MethodInterceptor, BeanFactoryAware {
private BeanFactory beanFactory;
private int count = 0;

public Object invoke(MethodInvocation methodInvocation) throws Throwable {
    count++;

    if(count == 5) {
        Advised bean = (Advised) AopContext.currentProxy();
        HotSwappableTargetSource source = (HotSwappableTargetSource) bean.getTargetSource();
        source.swap(beanFactory.getBean("target"));

        System.out.println("swapping...");
        count = 0;
    }

    return methodInvocation.proceed();
}

public void setBeanFactory(BeanFactory beanFactory) {
    this.beanFactory = beanFactory;
}

}

//the advised class:
public class ProxiedClass {
private static int nextInstanceId = 0;

private int instanceId;

public ProxiedClass() {
    this.instanceId = nextInstanceId;
    nextInstanceId++;
}

public void someMethod() {
    System.out.println("This is instance #" + instanceId);
}

}

<!-- The Spring configuration file: -->
<beans>
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyTargetClass"><value>true</value></property>
<property name="singleton">
<value>false</value>
</property>
<property name="exposeProxy">
<value>true</value>
</property>
<property name="targetSource" ref="swapper"/>
<property name="interceptorNames">
<list>
<value>targetAdvisor</value>
</list>
</property>
</bean>

<bean id="targetAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor" singleton="false">
    <constructor-arg>
        <bean class="org.springframework.aop.TruePointcut"/>
    </constructor-arg>
    <constructor-arg>
        <bean class="sdc.sade.common.spring_bug_testcase.TestCaseInterceptor"/>
    </constructor-arg>
</bean>

<bean id="swapper" class="org.springframework.aop.target.HotSwappableTargetSource" singleton="false">
    <constructor-arg>
        <ref bean="target"/>
    </constructor-arg>
</bean>

<bean id="target" class="sdc.sade.common.spring_bug_testcase.ProxiedClass" singleton="false"/>

</beans>

//The testcase:
public class TestCase {
public static void main(String [] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("testcase-context.xml");

    ProxiedClass o = (ProxiedClass) context.getBean("proxy");

    for(int i = 0; i < 20; i++) {
        o.someMethod();
    }
}

}

The output:
This is instance #0
This is instance #0
This is instance #0
This is instance #0
swapping...
This is instance #0
This is instance #2
This is instance #2
This is instance #2
This is instance #2
swapping...
This is instance #2
This is instance #3
This is instance #3
This is instance #3
This is instance #3
swapping...
This is instance #3
This is instance #4
This is instance #4
This is instance #4
This is instance #4
swapping...
This is instance #4


2 votes, 3 watchers

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)status: declinedA suggestion or change that we don't feel we should currently applytype: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions