Spring 高级 Spring选择代理 jdk 和 cglib的统一 aspect 和 advisor的区别
一 aspect 和 advisor的区别
二 advisor 演示 Spring 选择代理
package com.mangoubiubiu.show.a15; import org.aopalliance.intercept.MethodInterceptor; import org.springframework.aop.aspectj.AspectJExpressionPointcut; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.DefaultPointcutAdvisor; import java.lang.reflect.Method; public class A15 { public static void main(String[] args) { //1. 备好切点 AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression("execution(* foo())"); //2. 备好通知 MethodInterceptor advice = invocation -> { System.out.println("before...."); Object result = invocation.proceed(); System.out.println("after...."); return result; }; //3. 备好切面 DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut,advice); /** * 创建代理 */ Target1 target = new Target1(); ProxyFactory factory = new ProxyFactory(); factory.setTarget(target); factory.addAdvisor(advisor); I1 proxy = (I1)factory.getProxy(); proxy.foo(); proxy.bar(); } interface I1 { void foo(); void bar(); } static class Target1 implements I1 { public void foo() { System.out.println("target1 foo"); } public void bar() { System.out.println("target1 bar"); } } static class Target2 { public void foo() { System.out.println("target2 foo"); } public void bar() { System.out.println("target2 bar"); } } }
发现 foo方法被增强了
三 Spring创建代理时 是用的哪种实现类
收获💡
- 底层的切点实现
- 底层的通知实现
- 底层的切面实现
- ProxyFactory 用来创建代理
- 如果指定了接口,且 proxyTargetClass = false,使用 JdkDynamicAopProxy
- 如果没有指定接口,或者 proxyTargetClass = true,使用 ObjenesisCglibAopProxy
- 例外:如果目标是接口类型或已经是 Jdk 代理,使用 JdkDynamicAopProxy
注意
- 要区分本章节提到的 MethodInterceptor,它与之前 cglib 中用的的 MethodInterceptor 是不同的接口
package com.mangoubiubiu.show.a15; import org.aopalliance.intercept.MethodInterceptor; import org.springframework.aop.aspectj.AspectJExpressionPointcut; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.DefaultPointcutAdvisor; import java.lang.reflect.Method; public class A15 { public static void main(String[] args) { //1. 备好切点 AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression("execution(* foo())"); //2. 备好通知 MethodInterceptor advice = invocation -> { System.out.println("before...."); Object result = invocation.proceed(); System.out.println("after...."); return result; }; //3. 备好切面 DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut,advice); /** * 4 创建代理 * a proxyTargetClass = false 目标实现了接口 , 用jdk实现 * b proxyTargetClass = false 目标没有实现接口 , 用cglib实现 * c proxyTargetClass = true 总是使用 cglib实现 * * * */ Target2 target = new Target2(); ProxyFactory factory = new ProxyFactory(); factory.setTarget(target); factory.addAdvisor(advisor); factory.setInterfaces(target.getClass().getInterfaces()); factory.setProxyTargetClass(false); Target2 proxy = (Target2)factory.getProxy(); System.out.println(proxy.getClass()); proxy.foo(); proxy.bar(); } interface I1 { void foo(); void bar(); } static class Target1 implements I1 { public void foo() { System.out.println("target1 foo"); } public void bar() { System.out.println("target1 bar"); } } static class Target2 { public void foo() { System.out.println("target2 foo"); } public void bar() { System.out.println("target2 bar"); } } }