博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring源码AOP解析
阅读量:5307 次
发布时间:2019-06-14

本文共 17847 字,大约阅读时间需要 59 分钟。

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 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 getProxy(Class
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"); }}
View Code

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 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 getProxy(Class
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"); }}
View Code

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    
greetingAroundAdvice
spring2.5+特性,@Component @Component public calss GreetingImpl implements Greeting { ... } -->
|-- 客户端调用 |-- 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
|-- 调用 |-- 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
|-- AOP自动代理(每一个类都需要配置切面太麻烦,因此需要自动生成代理) |-- 配置文件-spring.xml
*Impl -> 不清楚Bean实现了多少接口,不能代理接口,只能代理类。 |-- 匹配到目标类的指定方法 |-- 配置文件-spring.xml
-->
总结: 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
|-- 基于注解 |-- @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
View Code

4、开发aop框架

|-- 定义注解类:|-- @Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @Interface Aspect {    Class
value();}|-- 搭建代理框架|-- interface Proxy { 代理接口 // 执行链式代理:可将多个代理通过一条链子串起来,一个个地去执行,执行顺序取决于添加到链上的先后顺序 Object doProxy(ProxyChain proxyChain) throws Throwable;}|-- class ProxyChain // 代理链|-- Class
targetClass;|-- Object targetObject;}-- Method targetMethod;|-- MethodProxy methodProxy;}-- Object[] methodParams;|-- List
proxyList = new ArrayList<>();|-- int proxyIndex=0;|-- ProxChain(Class
targetClass,Object targetObject,Method targetMethod,MethodProxy methodProxy,Object[] methodParams,List
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
...|-- class ProxyManger // 代理管理类|--
T createProxy(final Class
targetClass, final List
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
> getClassSetBySuper(Class
superClass){ Set
> classSet = new HashSet
(); for(Class
cls : CLASS_SET){ if (superClass.isAssignableFrom(cls) && !superClass.equals(cls)){ classSet.add(cls); } } } // 获取应用包名下带有注解的所有类 public static Set
> getClassSetByAnnotation(Class
annotionClass){ Set
> classSet = new HashSet
(); for(Class
cls : CLASS_SET){ if (superClass.isAnnotationPresent(annotionClass)){ classSet.add(cls); } } } ...}|-- AopHelper { ... private static Set
> createTargetClassSet(Aspect aspect) throws Exception { Set
> targetClassSet = new HashSet
>(); Class
annotation = aspect.value(); if (annotation != null && !annotation.equals(Aspect.class)){ targetClassSet.addAll(ClassHelper.getClassSetByAnnotation(annotation)); } return targetClassSet; } private static Map
>,Set
>> createProxyMap() throws Exception { Map
>,Set
>> proxyMap = new HashMap
>,Set
>>(); Set
> proxyClassSet = ClassHelper.getClassSetByAnnotation(AspectProxy.class); for(Class
proxyClass : proxyClassSet){ if (proxyClass.isAnnotationPresent(Aspect.class)){ Aspect aspect = proxyClass.getAnnotation(Aspect.class); Set
> targetClassSet = createTargetClassSet(aspect); proxyMap.put(proxyClass, targetClassSet); } } return proxyMap; } private static Map
,List
> createTargetMap(Map
>,Set
>> proxyMap) throws Exception { Map
,List
> targetMap = new HashMap
,List
>(); for(Map.Entry
>,Set
>> proxyEntry : proxyMap.entrySet()){ Class
proxyClass = proxyEntry.getKey(); Set
targetClassSet = proxyEntry.getValue(); for(Class
targetClass : targetClassSet){ Proxy proxy = (Proxy) targetClass.newInstance(); if (targetMap.contains(targetClass)){ targetMap.get(targetClass).add(proxy); } else { List
proxyList = new ArrayList
(); proxyList.add(proxy); targetMap.put(targetClass, proxyList); } } } } static { try { Map
>,Set
>> proxyMap = createProxyMap(); Map
,List
> targetMap = createTargetMap(proxyMap); for(Map.Entry
,List
> targetEntry : targetMap.etrySet()){ Class
targetClass =targetEntry.getKey(); List
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); } }}
View Code

 

转载于:https://www.cnblogs.com/ice-line/p/9967369.html

你可能感兴趣的文章
javaagent 简介
查看>>
C++学习之智能指针
查看>>
python升级安装后的yum的修复
查看>>
Vim配置Node.js开发工具
查看>>
iOS开发者需要的5款排版工具
查看>>
web前端面试题2017
查看>>
Reflection in Teaching
查看>>
intellij idea 将模块打jar包
查看>>
给MySQL增加Sequence管理功能
查看>>
ELMAH——可插拔错误日志工具
查看>>
MySQL学习笔记(四)
查看>>
【Crash Course Psychology】2. Research & Experimentation笔记
查看>>
两数和
查看>>
Python subprocess 模块
查看>>
Http协议
查看>>
c#获取文件路径
查看>>
移动设备和SharePoint 2013 - 第3部分:推送通知
查看>>
SOPC Builder中SystemID
查看>>
MySQL数据库备份工具mysqldump的使用(转)
查看>>
SSL 1120——【USACO 2.4】回家[最短路]
查看>>