-
Notifications
You must be signed in to change notification settings - Fork 38.5k
Ensure CGLIB proxy is created for mixin with IntroductionInterceptor
#31389
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,175 @@ | ||||||||||
package java.org.springframework.aop.framework; | ||||||||||
|
||||||||||
import org.junit.jupiter.api.Assertions; | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use AssertJ for assertions. The build will fail if you attempt to use JUnit Jupiter's Speaking of which, please run a full build locally before submitting a PR ( |
||||||||||
import org.junit.jupiter.api.Test; | ||||||||||
import org.springframework.aop.framework.ProxyFactory; | ||||||||||
import org.springframework.aop.support.AopUtils; | ||||||||||
import org.springframework.aop.support.DelegatePerTargetObjectIntroductionInterceptor; | ||||||||||
import org.springframework.aop.support.DelegatingIntroductionInterceptor; | ||||||||||
|
||||||||||
/** | ||||||||||
* @author 占道宏 | ||||||||||
* @create 2023/10/10 9:59 | ||||||||||
Comment on lines
+11
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
If possible, please provide your full name using the Latin alphabet for the |
||||||||||
*/ | ||||||||||
public class ProxyFactoryWithIntroductionInterceptorTests { | ||||||||||
|
||||||||||
/** | ||||||||||
* The target object does not implement any interfaces, and in this case, you want to use CGLIB for dynamic proxying. | ||||||||||
*/ | ||||||||||
@Test | ||||||||||
public void testDelegatingIntroductionInterceptorWithoutInterface() { | ||||||||||
People peo = new People(); | ||||||||||
ProxyFactory pf = new ProxyFactory(); | ||||||||||
DelegatingIntroductionInterceptor dii = new DelegatingIntroductionInterceptor((Developer) () -> System.out.println("Coding")); | ||||||||||
pf.addAdvice(dii); | ||||||||||
pf.setTarget(peo); | ||||||||||
|
||||||||||
Object proxy = pf.getProxy(); | ||||||||||
Assertions.assertTrue(AopUtils.isCglibProxy(proxy)); | ||||||||||
Assertions.assertTrue(proxy instanceof People); | ||||||||||
Assertions.assertTrue(proxy instanceof Developer); | ||||||||||
|
||||||||||
People people = (People) proxy; | ||||||||||
Assertions.assertDoesNotThrow(people::eat); | ||||||||||
|
||||||||||
Developer developer = (Developer) proxy; | ||||||||||
Assertions.assertDoesNotThrow(developer::code); | ||||||||||
} | ||||||||||
|
||||||||||
/** | ||||||||||
* The target object implements the Teacher interface, and in this case, you want to use JDK for dynamic proxying | ||||||||||
*/ | ||||||||||
@Test | ||||||||||
public void testDelegatingIntroductionInterceptorWithInterface() { | ||||||||||
Teacher teacher = () -> System.out.println("teach"); | ||||||||||
ProxyFactory pf = new ProxyFactory(); | ||||||||||
DelegatingIntroductionInterceptor dii = new DelegatingIntroductionInterceptor((Developer) () -> System.out.println("Coding")); | ||||||||||
pf.addAdvice(dii); | ||||||||||
pf.addInterface(Teacher.class); | ||||||||||
pf.setTarget(teacher); | ||||||||||
|
||||||||||
Object proxy = pf.getProxy(); | ||||||||||
Assertions.assertTrue(AopUtils.isJdkDynamicProxy(proxy)); | ||||||||||
Assertions.assertTrue(proxy instanceof Teacher); | ||||||||||
Assertions.assertTrue(proxy instanceof Developer); | ||||||||||
|
||||||||||
Teacher teacher1 = (Teacher) proxy; | ||||||||||
Assertions.assertDoesNotThrow(teacher1::teach); | ||||||||||
|
||||||||||
Developer developer = (Developer) proxy; | ||||||||||
Assertions.assertDoesNotThrow(developer::code); | ||||||||||
} | ||||||||||
|
||||||||||
/** | ||||||||||
* The target object does not implement any interfaces, and in this case, you want to use CGLIB for dynamic proxying. | ||||||||||
*/ | ||||||||||
@Test | ||||||||||
public void testDelegatePerTargetObjectIntroductionInterceptorWithoutInterface() { | ||||||||||
People peo = new People(); | ||||||||||
ProxyFactory pf = new ProxyFactory(); | ||||||||||
DelegatePerTargetObjectIntroductionInterceptor dii = new DelegatePerTargetObjectIntroductionInterceptor(DeveloperImpl.class, Developer.class); | ||||||||||
pf.addAdvice(dii); | ||||||||||
pf.setTarget(peo); | ||||||||||
|
||||||||||
Object proxy = pf.getProxy(); | ||||||||||
Assertions.assertTrue(AopUtils.isCglibProxy(proxy)); | ||||||||||
Assertions.assertTrue(proxy instanceof People); | ||||||||||
Assertions.assertTrue(proxy instanceof Developer); | ||||||||||
|
||||||||||
People people = (People) proxy; | ||||||||||
Assertions.assertDoesNotThrow(people::eat); | ||||||||||
|
||||||||||
Developer developer = (Developer) proxy; | ||||||||||
Assertions.assertDoesNotThrow(developer::code); | ||||||||||
} | ||||||||||
|
||||||||||
/** | ||||||||||
* The target object implements the Teacher interface, and in this case, you want to use JDK for dynamic proxying | ||||||||||
*/ | ||||||||||
@Test | ||||||||||
public void testDelegatePerTargetObjectIntroductionInterceptorWithInterface() { | ||||||||||
Teacher teacher = () -> System.out.println("teach"); | ||||||||||
ProxyFactory pf = new ProxyFactory(); | ||||||||||
DelegatePerTargetObjectIntroductionInterceptor dii = new DelegatePerTargetObjectIntroductionInterceptor(DeveloperImpl.class, Developer.class); | ||||||||||
pf.addAdvice(dii); | ||||||||||
pf.addInterface(Teacher.class); | ||||||||||
pf.setTarget(teacher); | ||||||||||
|
||||||||||
Object proxy = pf.getProxy(); | ||||||||||
Assertions.assertTrue(AopUtils.isJdkDynamicProxy(proxy)); | ||||||||||
Assertions.assertTrue(proxy instanceof Teacher); | ||||||||||
Assertions.assertTrue(proxy instanceof Developer); | ||||||||||
|
||||||||||
Teacher teacher1 = (Teacher) proxy; | ||||||||||
Assertions.assertDoesNotThrow(teacher1::teach); | ||||||||||
|
||||||||||
Developer developer = (Developer) proxy; | ||||||||||
Assertions.assertDoesNotThrow(developer::code); | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of asserting that the code does not throw an exception, please change the |
||||||||||
} | ||||||||||
|
||||||||||
/** | ||||||||||
* The target object does not implement any interfaces, so it is necessary to use CGLIB for proxying | ||||||||||
*/ | ||||||||||
@Test | ||||||||||
public void testProxyFactoryWithoutInterface() { | ||||||||||
People people = new People(); | ||||||||||
ProxyFactory pf = new ProxyFactory(); | ||||||||||
pf.setTarget(people); | ||||||||||
Object proxy = pf.getProxy(); | ||||||||||
|
||||||||||
Assertions.assertTrue(AopUtils.isCglibProxy(proxy)); | ||||||||||
Assertions.assertTrue(proxy instanceof People); | ||||||||||
Assertions.assertDoesNotThrow(((People)proxy)::eat); | ||||||||||
|
||||||||||
pf.addInterface(Teacher.class); | ||||||||||
proxy = pf.getProxy(); | ||||||||||
Assertions.assertTrue(AopUtils.isCglibProxy(proxy)); | ||||||||||
Assertions.assertTrue(proxy instanceof Teacher); | ||||||||||
Assertions.assertTrue(proxy instanceof People); | ||||||||||
Assertions.assertDoesNotThrow(((People)proxy)::eat); | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above. |
||||||||||
} | ||||||||||
|
||||||||||
/** | ||||||||||
* When the target object implements the Teacher interface | ||||||||||
* but we have not explicitly called the addInterface method, | ||||||||||
* we expect to use CGLIB; however, after calling it, we expect to use JDK | ||||||||||
*/ | ||||||||||
@Test | ||||||||||
public void testProxyFactoryWithInterface() { | ||||||||||
Teacher teacher = () -> System.out.println("teach"); | ||||||||||
ProxyFactory pf = new ProxyFactory(); | ||||||||||
pf.setTarget(teacher); | ||||||||||
Object proxy = pf.getProxy(); | ||||||||||
|
||||||||||
Assertions.assertTrue(AopUtils.isCglibProxy(proxy)); | ||||||||||
Assertions.assertTrue(proxy instanceof Teacher); | ||||||||||
Assertions.assertDoesNotThrow(((Teacher)proxy)::teach); | ||||||||||
|
||||||||||
pf.addInterface(Teacher.class); | ||||||||||
proxy = pf.getProxy(); | ||||||||||
Assertions.assertTrue(AopUtils.isJdkDynamicProxy(proxy)); | ||||||||||
Assertions.assertTrue(proxy instanceof Teacher); | ||||||||||
Assertions.assertDoesNotThrow(((Teacher)proxy)::teach); | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above. |
||||||||||
} | ||||||||||
|
||||||||||
public static class People { | ||||||||||
void eat() { | ||||||||||
System.out.println("eat"); | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do not use Please change the |
||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
public interface Teacher { | ||||||||||
void teach(); | ||||||||||
} | ||||||||||
|
||||||||||
public interface Developer { | ||||||||||
void code(); | ||||||||||
} | ||||||||||
|
||||||||||
public static class DeveloperImpl implements Developer { | ||||||||||
@Override | ||||||||||
public void code() { | ||||||||||
System.out.println("Coding"); | ||||||||||
} | ||||||||||
} | ||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's revise this method like this.
Also, please add Javadoc for this method, similar to the Javadoc for
hasNoUserSuppliedProxyInterfaces(...)
.