Skip to content

Commit

Permalink
Make proxyTargetClass=true with introduction advice work for JDK prox…
Browse files Browse the repository at this point in the history
…y targets

Closes gh-27044
  • Loading branch information
jhoeller committed Jul 9, 2021
1 parent 74f9133 commit c45c46d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 6 deletions.
Expand Up @@ -17,6 +17,7 @@
package org.springframework.aop.framework.autoproxy;

import java.lang.reflect.Constructor;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -440,7 +441,17 @@ protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);

if (!proxyFactory.isProxyTargetClass()) {
if (proxyFactory.isProxyTargetClass()) {
// Explicit handling of JDK proxy targets (for introduction advice scenarios)
if (Proxy.isProxyClass(beanClass)) {
// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
for (Class<?> ifc : beanClass.getInterfaces()) {
proxyFactory.addInterface(ifc);
}
}
}
else {
// No proxyTargetClass flag enforced, let's apply our default checks...
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 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.
Expand Down Expand Up @@ -28,6 +28,7 @@
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.aop.support.DefaultIntroductionAdvisor;
import org.springframework.aop.target.SingletonTargetSource;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanFactory;
Expand Down Expand Up @@ -219,7 +220,7 @@ public void testAutoProxyCreatorWithFallbackToDynamicProxy() {

MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("proxyFactoryBean", "false");
sac.registerSingleton("testAutoProxyCreator", TestAutoProxyCreator.class, pvs);
sac.registerSingleton("testAutoProxyCreator", IntroductionTestAutoProxyCreator.class, pvs);

sac.registerSingleton("noInterfaces", NoInterfaces.class);
sac.registerSingleton("containerCallbackInterfacesOnly", ContainerCallbackInterfacesOnly.class);
Expand Down Expand Up @@ -248,9 +249,9 @@ public void testAutoProxyCreatorWithFallbackToDynamicProxy() {
singletonNoInterceptor.getName();
assertThat(tapc.testInterceptor.nrOfInvocations).isEqualTo(0);
singletonToBeProxied.getAge();
assertThat(tapc.testInterceptor.nrOfInvocations).isEqualTo(1);
prototypeToBeProxied.getSpouse();
assertThat(tapc.testInterceptor.nrOfInvocations).isEqualTo(2);
prototypeToBeProxied.getSpouse();
assertThat(tapc.testInterceptor.nrOfInvocations).isEqualTo(4);
}

@Test
Expand Down Expand Up @@ -404,7 +405,7 @@ protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String name,
else if (name.endsWith("ToBeProxied")) {
boolean isFactoryBean = FactoryBean.class.isAssignableFrom(beanClass);
if ((this.proxyFactoryBean && isFactoryBean) || (this.proxyObject && !isFactoryBean)) {
return new Object[] {this.testInterceptor};
return getAdvicesAndAdvisors();
}
else {
return DO_NOT_PROXY;
Expand All @@ -414,6 +415,10 @@ else if (name.endsWith("ToBeProxied")) {
return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
}
}

protected Object[] getAdvicesAndAdvisors() {
return new Object[] {this.testInterceptor};
}
}


Expand All @@ -426,6 +431,17 @@ public FallbackTestAutoProxyCreator() {
}


@SuppressWarnings("serial")
public static class IntroductionTestAutoProxyCreator extends TestAutoProxyCreator {

protected Object[] getAdvicesAndAdvisors() {
DefaultIntroductionAdvisor advisor = new DefaultIntroductionAdvisor(this.testInterceptor);
advisor.addInterface(Serializable.class);
return new Object[] {this.testInterceptor, advisor};
}
}


/**
* Interceptor that counts the number of non-finalize method calls.
*/
Expand Down

0 comments on commit c45c46d

Please sign in to comment.