spring源码AOP解析
程序员文章站
2022-05-18 22:52:40
1、代理技术(静态代理、JDK动态代理、CGLib代理) 静态代理: |-- Hello |-- void say(String name); |-- HelloImpl implements Hello { voiv say(String name){ sysout("Hello!"+name); ......
1、代理技术(静态代理、jdk动态代理、cglib代理)
静态代理: |-- hello |-- void say(string name); |-- helloimpl implements hello { voiv say(string name){ sysout("hello!"+name); } } |-- helloproxy implents hello { hello hello; helloproxy(){ hello = new helloimpl(); } voiv say(string name){ before(); sysout("hello!"+name); end(); } void before(){ sysout("before"); } void after(){ sysout("after"); } main(string[] args){ hello hello = new helloproxy(); hello.say("jack"); } } jdk动态代理: |-- dynamicproxy implements invocationhandler { object target; dynamicproxy (object target){ this.target = target; } @override public object invoke(object proxy, method method, object[] args){ before(); object result = method.invoke(target, args); after(); return result; } ... main(string[] args){ // 尝试1 hello hello = new helloimpl(); dynamicproxy dynamicproxy = new dynamicproxy(hello); hello hello = (hello)proxy.newproxyinstance(hello.getclass().getclassloader(), hello.getclass.getinterfaces(), dynamicproxy); hello.say("jack"); // 尝试2 dynamicproxy dynamicproxy = new dynamicproxy(new helloimpl()); hello hello = dynamicproxy.getproxy(); hello.say("jack"); } public <t> t getproxy(){ return (t)proxy.newproxyinstance( target.getclass().getclassloader(), target.getclass.getinterfaces(), this ); } } cglib动态代理: |-- cglibproxy implements methodinterceptor { private static cglibproxy instance = new cglibproxy(); private cglibproxy() {} public cglibproxy getinstance(){ return instance; } public <t> t getproxy(class<t> cls){ return (t) enhancer.create(cls, this); } public object inercept(object obj, method method, object[] args, methodproxy proxy){ before(); object result = proxy.invokesuper(obj, args); after(); return result; } ... main(string[] args){ // 尝试1 cglibproxy cglibproxy = new cglibproxy(); hello helloproxy = cglibproxy.getproxy(helloimpl.class); helloproxy.say("jack"); // 尝试2 hello helloproxy =cglibproxy.getinstance().getproxy(helloimpl.class); helloproxy.say("jack"); } }
2、aop技术
|-- interface greeting |-- void sayhello(string name); |-- greetingimpl implements greeting |-- sayhello(string name){ before(); sysout("hello!"+name); after(); } |-- greetingproxy implements greeting |-- greetingimpl greetingimpl; |-- greetingproxy(greetingimpl greetingimpl) -> this.greetingimpl = greetingimpl; |-- sayhello(string name){ before(); greetingimpl.sayhello(); after(); } |-- before() -> sysout("before"); |-- after() -> sysout("after"); |-- main(string[] args){ greeting greetingproxy = new greetingproxy(new greetingimpl()); greetingproxy.sayhello("jack"); } |-- jdkdynamicproxy implements invocationhandler { object target; jdkdynamicproxy (object target){ this.target = target; } @override public object invoke(object proxy, method method, object[] args){ before(); object result = method.invoke(target, args); after(); return result; } public <t> t getproxy(){ return (t)proxy.newproxyinstance( target.getclass().getclassloader(), target.getclass.getinterfaces(), this ); } private void before(){ sysout("before"); } private void after(){ sysout("after"); } main(string[] args){ greeting greeting = new jdkdynamicproxy(new greetingimpl()).getproxy(); greeting.sayhello("jack"); } } |-- cglibproxy implements methodinterceptor{ private static cglibproxy instance = new cglibproxy(); private cglibproxy() {} public cglibproxy getinstance(){ return instance; } public <t> t getproxy(class<t> cls){ return (t) enhancer.create(cls, this); } public object inercept(object obj, method method, object[] args, methodproxy proxy){ before(); object result = proxy.invokesuper(obj, args); after(); return result; } main(string[] args){ greeting greeting = cglibproxy.getinstance().getproxy(greetingimpl.class); greeting.sayhello("jack"); } }
3、spring aop技术
|-- greetingbeforeadvice implements methodbeforeadvice |-- before(method method, object[] args, object target) throws throwable -> sysout("before"); |-- afterreturningadvice |-- afterreturning(object result, method method, object[] args, object target) throws throwable -> sysout("after"); |-- greetingbeforeandafteradvice implements methodbeforeadvice, afterreturningadvice |-- before(method method, object[] args, object target) throws throwable -> sysout("before"); |-- afterreturning(object result, method method, object[] args, object target) throws throwable -> sysout("after"); |-- greetingaroundadvice implements methodinterceptor // 环绕增强(org.aopalliance.intercept.methodinterceptor,aop联盟) |-- object invoke(methodinvocation invocation){ before(); object result = invocation.proceed(); after(); } |-- before() -> sysout("before") |-- after() -> sysout("after") |-- main (string[] args){ proxyfactory proxyfactory = new proxyfactory(); // 创建代理工厂 proxyfactory.settarget(new greetingimpl()); // 射入目标类对象 // proxyfactory.addadvice(new greetingbeforeadvice()); // 添加前置增强 // proxyfactory.addadvice(new afterreturningadvice()); // 添加后置增强 // proxyfactory.addadvice(new greetingbeforeandafteradvice()); // 添加前后置增强 proxyfactory.addadvice(new greetingaroundadvice()); // 添加环绕增强 greeting greeting = (greeting)proxyfactory.getproxy(); // 从代理工厂获取代理对象 greeting.sayhello("jack"); // 调用代理方法 } |-- 配置文件-spring.xml <!-- 扫描指定包(将带有@componet注解类自动定义为spring bean) --> <context:componet-scan base-package="aop.demo"/> <!-- 配置一个代理 --> <bean id="greetingproxy" class="org.springframework.aop.framework.proxyfactorybean"> <property name="interfaces" value="aop.greeting"></property><!-- 需要代理的接口 --> <property name="target" value="greetingimpl"></property><!-- 接口实现类 --> <!-- <property name="target" value="greetingaroundadvice"></property> --> <property name="interceptornames"> <list> <value>greetingaroundadvice</value> </list> </property> </bean> spring2.5+特性,@component @component public calss greetingimpl implements greeting { ... } --> <bean id="xxx" class="xxx"> |-- 客户端调用 |-- main(string[] args){ applicationcontext context = new classpathxmlapplicationcontext("aop/demo/spring.xml"); greeting greeting = (greeting)context.getbean("greetingproxy"); greeting.sayhello("jack"); } |-- 抛出增强-throwsadvice |-- greetingthrowadvice implements throwsadvice { public void afterthrowing(method method, object[] args, object target, exception e){ sysout("--------- throw exception ---------"); sysout("target class: " + target.getclass().getname()); sysout("method name: " + method.getname()); sysout("exception message: " + e.getmessage()); sysout("-----------------------------------"); } } |-- 引入增强 |-- interface apology |-- void saysorry(string name); |-- @component greetingintroadvice extends delegatingintroductioninterceptor implements apology { @override public object invoke(methodinvocation invocation) throws throwable{ return super.invoke(invocation); } @overrice public void saysorry(string name){ sysout("sorry! + name); } } |-- 配置文件-spring.xml <!-- 扫描指定包(将带有@componet注解类自动定义为spring bean) --> <context:componet-scan base-package="aop.demo"/> <!-- 配置一个代理 --> <bean id="greetingproxy" class="org.springframework.aop.framework.proxyfactorybean"> <property name="interfaces" value="aop.demo.apology"></property><!-- 需要动态实现的接口 --> <property name="target" value="greetingimpl"></property><!-- 目标类 --> <property name="interceptornames" value="greetingintroadvice"></property> <!-- 引入增强 --> <property name="proxytargetclass" value="true"/> <!-- 代理目标类(默认为false,代理接口)--> </bean> |-- 调用 |-- main(string[] args){ applicationcontext context = new classpathxmlapplicationcontext("aop/demo/spring.xml"); geetingimpl greetingimpl = (geetingimpl)context.getbean("greetingproxy"); // 转型为目标类,而非它的接口 greetingimpl.sayhello("jack"); apology apology = (apology) greetingimpl; // 将目标类型强制向上转型为apology接口(这就是引入增强给我们带来的特性,也就是“接口动态实现”功能) apology.saysorry("jack"); } |-- aop 切面 |-- @component public class greetingimpl implements greeting { @override public void sayhello(){ sysout("hello!" + name); } public void goodmorning(string name){ sysout("good morning!" + name); } public void goodnight(string name){ sysout("good night!" + name); } } |-- 配置文件-spring.xml <!-- 扫描指定包(将带有@componet注解类自动定义为spring bean) --> <context:componet-scan base-package="aop.demo"/> <!-- 配置一个切面 --> <bean id="greetingadvisor" class="org.springframework.aop.support.regexpmethodpointcutadvisor"> <property name="advice" value="greetingaroundadvice"></property> <!-- 增强 --> <property name="pattern" value="aop.demo.greetingimpl.good.*"></property> <!-- 切点(正则表达式) --> </bean> <!-- 配置一个代理 --> <bean id="greetingproxy" class="org.springframework.aop.framework.proxyfactorybean"> <property name="target" value="greetingimpl"></property><!-- 目标类 --> <property name="interceptornames" value="greetingadvisor"></property><!-- 切面 --> <property name="proxytargetclass" value="true"/> <!-- 代理目标类(默认为false,代理接口)--> </bean> |-- aop自动代理(每一个类都需要配置切面太麻烦,因此需要自动生成代理) |-- 配置文件-spring.xml <bean class="org.springframework.aop.framework.autoproxy.beannameautoproxycreator"> <property name="target" value="*impl"></property><!-- 目标类 --> <property name="interceptornames" value="greetingaroundadvice"></property><!-- 增强 --> <property name="optimize" value="true"/> <!-- 是否对代理生成策略进行优化,默认是false --> </bean> *impl -> 不清楚bean实现了多少接口,不能代理接口,只能代理类。 |-- 匹配到目标类的指定方法 |-- 配置文件-spring.xml <bean class="org.springframework.aop.framework.autoproxy.beannameautoproxycreator"> <!-- <property name="target" value="*impl">--></property><!-- 目标类 --> <!-- <property name="interceptornames" value="greetingaroundadvice"></property>--><!-- 增强 --> <property name="optimize" value="true"/> <!-- 是否对代理生成策略进行优化,默认是false --> </bean> --> <bean id="greetingadvisor" class="org.springframework.aop.support.regexpmethodpointcutadvisor"> <property name="advice" ref="greetingaroundadvice"></property> <!-- 增强 --> <property name="pattern" value="aop.demo.greetingimpl.good.*"></property> <!-- 切点(正则表达式) --> </bean> <bean class="org.springframework.aop.framework.autoproxy.defaultadvisorautoproxycreator"> <property name="optimize" value="true"/> <!-- 是否对代理生成策略进行优化,默认是false --> </bean> 总结: cglib代理:创建代理速度慢,创建代理后运行速度快(系统初始化创建代理备用最佳) jdk动态代理:创建代理速度快,运行速度慢 |-- spring + aspectj(advisor) |-- 普通demo |-- @aspect @component public class greetingaspect { @arount("execution(* aop.demo.greetingimpl.*(..))") public object around(proceedingjoinpoint pjp) throws throwable { before(); object result = pjp.proceed(); after(); return result; } public void before(){ sysout("before"); } public void after(){ sysout("after"); } } |-- 配置文件-spring.xml <!-- 扫描指定包(将带有@componet注解类自动定义为spring bean) --> <context:componet-scan base-package="aop.demo"/> <aop:aspect-autoproxy proxy-target-class="true" /> |-- 基于注解 |-- @target(elementtype.method) @retention(retentionpolicy.runtime) public @interface tag { } |-- @aspect @component public class greetingaspect { @arount("@annotation(aop.demo.tag)") public object around(proceedingjoinpoint pjp) throws throwable { ... } ... } |-- @component public class greetingimpl implements greeting { @tag @override public void sayhello(string name){ sysout("hello!" + name); } ... } |-- 实现引入增强 |-- @aspect @component public class greetingaspect { @delareparents(value="aop.demo.greetingimpl",defaultimpl="apologyimpl.class") private apology apology; } |-- apologyimpl implements apology { @override public void saysorry(string name){ sysout("sorry!" + name); } main(string[] args){ applicationcontext context = new classpathxmlapplicationcontext("aop/demp/spring.xml"); greeting greeting = context.getbean("greetingimpl"); greeting.sayhello("jack"); apology apology = (apology) greeting; apology.saysorry("jack"); } } |-- 基于配置 |-- 配置文件-spring.xml <!-- 扫描指定包(将带有@componet注解类自动定义为spring bean) --> <context:componet-scan base-package="aop.demo"/> <beans ...> <bean id="greetingimpl" class="aop.demo.greetingimpl" /> <bean id="greetingaspect" class="aop.demo.greetingaspect" /> <aop:config> <aop:aspect ref="greetingaspect"> <aop:around method="around" pointcut="execution (* aop.demo.greetingimpl.*(..))"/> </aop:aspect> </aop:config> </beans>
4、开发aop框架
|-- 定义注解类: |-- @target(elementtype.type) @retention(retentionpolicy.runtime) public @interface aspect { class<? extends annotion> value(); } |-- 搭建代理框架 |-- interface proxy { 代理接口 // 执行链式代理:可将多个代理通过一条链子串起来,一个个地去执行,执行顺序取决于添加到链上的先后顺序 object doproxy(proxychain proxychain) throws throwable; } |-- class proxychain // 代理链 |-- class<?> targetclass; |-- object targetobject; }-- method targetmethod; |-- methodproxy methodproxy; }-- object[] methodparams; |-- list<proxy> proxylist = new arraylist<>(); |-- int proxyindex=0; |-- proxchain(class<?> targetclass,object targetobject,method targetmethod,methodproxy methodproxy,object[] methodparams,list<proxy> proxylist){ this.targetclass = targetclass; ... } |-- getmethodparams() -> return methodparams; |-- gettargetclass() -> return targetclass; |-- gettargetmethod() -> return targetmethod; |-- object doproxychain() throws throwable{ object methodresult; if (proxyindex < proxylist.size()){ methodresult = proxylist.get(proxyindex++).doproxy(); } else { methodresult = methodproxy.invokesuper(targetobject, methodparams); } return methodresult; } |-- 添加pom.xml依赖 <!-- cglib 依赖--> <grouid>cglib<groupid>... |-- class proxymanger // 代理管理类 |-- <t> t createproxy(final class<?> targetclass, final list<proxy> proxylist){ return (t) enhancer.create(targetclass, new methodinterceptor(){ @overrice public object intercept(object targetobject, method targetmethod, object[] methodparams, methodproxy methodproxy){ return new proxychain(targetclass, targetobject, targetmethod, methodproxy, methodparams, proxylist); } }); } |-- public abstract calss aspectproxy implements proxy { // 切面代理 @override public final object doproxy(proxychain proxychain) throws throwable { object result = null; class<?> cls = proxychain.gettargetclass(); method method = proxychain.gettargetmethod(); object[] params = proxychain.getmethodparams(); begin(); try { if (intercept(cls, method, params)){ before(cls, method, params); result = proxychain.doproxychain(); after(cls, method, params); } else { return proxychain.doproxychain(); } } catch(exception e){ logger.error("proxy failure", e); error(cls, method, params, e); throw e; } finally { end(); } } public void begin(){ } public void end(){ } public boolean intercept(class<?> cls, method method, object[] params) throws throwable { return true; } public void before(class<?> cls, method method, object[] params) throws throwable { } public void after(class<?> cls, method method, object[] params) throws throwable { } public void error(class<?> cls, method method, object[] params, throwable e){ } } |-- @aspect(controller.class) controlleraspect extends aspectproxy{ // 拦截controller 所有方法 private long begin; @override public void before(class<?> cls, method method, object[] params) throws throwable { begin = system.currenttimemillis(); } @override public void after(class<?> cls, method method, object[] params) throws throwable { sysout(system.currenttimemillis()-begin); } } |-- beanhelper { ... // 设置bean实例 public static void setbean(class<?> cls, object obj){ bean_map.put(cls, obj); } } |-- classhelper { ... // 获取某父类(或接口)的所有子类(或实现类) public static set<class<?>> getclasssetbysuper(class<?> superclass){ set<class<?>> classset = new hashset<classs<?>(); for(class<?> cls : class_set){ if (superclass.isassignablefrom(cls) && !superclass.equals(cls)){ classset.add(cls); } } } // 获取应用包名下带有注解的所有类 public static set<class<?>> getclasssetbyannotation(class<? extends annotation> annotionclass){ set<class<?>> classset = new hashset<classs<?>(); for(class<?> cls : class_set){ if (superclass.isannotationpresent(annotionclass)){ classset.add(cls); } } } ... } |-- aophelper { ... private static set<class<?>> createtargetclassset(aspect aspect) throws exception { set<class<?>> targetclassset = new hashset<class<?>>(); class<? extends annotation> annotation = aspect.value(); if (annotation != null && !annotation.equals(aspect.class)){ targetclassset.addall(classhelper.getclasssetbyannotation(annotation)); } return targetclassset; } private static map<class<?>>,set<class<?>>> createproxymap() throws exception { map<class<?>>,set<class<?>>> proxymap = new hashmap<class<?>>,set<class<?>>>(); set<class<?>> proxyclassset = classhelper.getclasssetbyannotation(aspectproxy.class); for(class<?> proxyclass : proxyclassset){ if (proxyclass.isannotationpresent(aspect.class)){ aspect aspect = proxyclass.getannotation(aspect.class); set<class<?>> targetclassset = createtargetclassset(aspect); proxymap.put(proxyclass, targetclassset); } } return proxymap; } private static map<class<?>,list<proxy>> createtargetmap(map<class<?>>,set<class<?>>> proxymap) throws exception { map<class<?>,list<proxy>> targetmap = new hashmap<class<?>,list<proxy>>(); for(map.entry<class<?>>,set<class<?>>> proxyentry : proxymap.entryset()){ class<?> proxyclass = proxyentry.getkey(); set<class<?> targetclassset = proxyentry.getvalue(); for(class<?> targetclass : targetclassset){ proxy proxy = (proxy) targetclass.newinstance(); if (targetmap.contains(targetclass)){ targetmap.get(targetclass).add(proxy); } else { list<proxy> proxylist = new arraylist<proxy>(); proxylist.add(proxy); targetmap.put(targetclass, proxylist); } } } } static { try { map<class<?>>,set<class<?>>> proxymap = createproxymap(); map<class<?>,list<proxy>> targetmap = createtargetmap(proxymap); for(map.entry<class<?>,list<proxy>> targetentry : targetmap.etryset()){ class<?> targetclass =targetentry.getkey(); list<proxy> proxylist = targetentry.getvalue(); object proxy = proxymanager.createproxy(targetclass, proxylist); beanhelper.setbean(targetclass, proxy); } } catch(exception e){ logger.error("aop failure", e); } } } |-- helperloader { public static void init(){ class<?>[] classlist = { classhelper.class, beanhelper.class, aophelper.class, iochelper.class, controllerhelper.class }; for(class<?> cls : classlist){ classutil.loadclass(cls.getname(), true); } } }
上一篇: 1
下一篇: springboot集合jpa使用
推荐阅读
-
spring为java.util.Properties类型的属性进行赋值过程解析
-
Spring AOP定义AfterReturning增加实例分析
-
spring级联属性赋值的两种方式解析
-
spring5 源码深度解析----- 被面试官给虐懵了,竟然是因为我不懂@Configuration配置类及@Bean的原理
-
AngularJS动态生成div的ID源码解析
-
Spring HttpMessageConverter的作用及替换解析
-
java源码解析(java新手代码大全)
-
基于spring中的aop简单实例讲解
-
ArrayList构造方法的源码解析
-
mac下用IDEA、gradle构建spring源码步骤(精品,干货满满)