Spring AOP 源码手写实现

                                                                                                       20190815 田超凡

CGLIB动态代理,代理目标可以是任何Bean组件

JDK动态代理,代理目标只能是接口

本代码基于CGLIB动态代理实现进行手写源码,如果是JDK动态代理则ProxyManager中newProxy方法构造JDK代理对象即可

注意:JUnit时AopHelper必须在IoCHelper加载之前进行,因为需要先创建所有目标类和目标代理实例,最后再加载IoCHelper从而和上次手写的IoC代码整合自动注入代理实例

本代码针对同一代理目标多个代理对象的情况进行了统一封装,基于ProxyChain代理执行链实现,代理目标:代理实例 => 1:N关联映射,按照ProxyChain载入顺序按序执行代理方法

cglib Enhance.create

常用callback => MethodInterceptor接口实现,重写intercepter拦截

jdk Proxy.newProxyInstance
package com.tcf.kid.base.annotation;
import java.lang.annotation.Annotation;
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;/***
  * TODO TCF 自定义切面注解类
  * @author Hasee
  *
  */
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Aspect {    Class<? extends Annotation> value();
 }
  package com.tcf.kid.base.annotation;
import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;@Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Inject {}
  package com.tcf.kid.base.core;
/***
  * TODO TCF AOP代理接口
  * @author Hasee
  *
  */
 public interface Proxy {    //TODO TCF 调用执行链执行代理
     public Object doProxy(ProxyChain proxyChain);
 }
  package com.tcf.kid.base.core;
import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;import com.tcf.kid.base.core.Proxy;
import net.sf.cglib.proxy.MethodProxy;
/***
  * TODO TCF 代理类执行链,封装多个代理对象单元
  * @author Hasee
  *
  */
 public class ProxyChain {    //TODO TCF 代理的目标类
     private Class<?> targetClass;
     
     //TODO TCF 代理的目标实例
     private Object targetObject;
     
     //TODO TCF 代理的目标方法
     private Method targetMethod;
     
     //TODO TCF 代理的目标方法参数
     private Object[] methodParams;
     
     //TODO TCF 代理方法
     private MethodProxy methodProxy;
     
     //TODO TCF 所有代理对象
     private List<Proxy> proxyList=new ArrayList<Proxy>();
     
     //TODO TCF 执行链执行索引
     private int proxyExecuteIndex=0;
     
     public Class<?> getTargetClass() {
         return targetClass;
     }
     public Object getTargetObject() {
         return targetObject;
     }
     public Method getTargetMethod() {
         return targetMethod;
     }
     public Object[] getMethodParams() {
         return methodParams;
     }
     public MethodProxy getMethodProxy() {
         return methodProxy;
     }
     public List<Proxy> getProxyList() {
         return proxyList;
     }
     public Integer getProxyExecuteIndex() {
         return proxyExecuteIndex;
     }
     
     //TODO TCF 构造函数,注入代理参数
     public ProxyChain(Class<?> targetClass,
             Object targetObject,
             Method targetMethod,
             Object[] methodParams,
             MethodProxy methodProxy,
             List<Proxy> proxyList) 
     {
         this.targetClass=targetClass;
         this.targetObject=targetObject;
         this.targetMethod=targetMethod;
         this.methodParams=methodParams;
         this.methodProxy=methodProxy;
         this.proxyList=proxyList;
     }
     
     //TODO TCF 执行链方法
     public Object doProxyChain() throws Throwable
     {
         //TODO TCF 执行代理方法返回值
         Object methodResult=null;
         if(proxyExecuteIndex<proxyList.size())
         {
             //TODO TCF 执行代理方法,织入代理增强
             methodResult=proxyList.get(proxyExecuteIndex)!=null?proxyList.get(proxyExecuteIndex).doProxy(this):null;
             proxyExecuteIndex++;
         }
         else
         {
             //TODO TCF 执行代理目标方法
             methodResult=methodProxy.invokeSuper(targetObject,methodParams);
         }
         
         return methodResult;
     }
 }
  package com.tcf.kid.base.core;
import java.lang.reflect.Method;
 import java.util.List;import net.sf.cglib.proxy.Enhancer;
 import net.sf.cglib.proxy.MethodInterceptor;
 import net.sf.cglib.proxy.MethodProxy;/***
  * TODO TCF 动态代理管理器,创建代理对象
  * @author Hasee
  *
  */
 public class ProxyManager{    //TODO TCF 根据代理目标类型和多个代理类批量创建cglib动态代理对象
     @SuppressWarnings("unchecked")
     public static <T> T createProxy(final Class<?> targetClass,final List<Proxy> proxyList)
     {
         T result= (T)Enhancer.create(targetClass,new MethodInterceptor() {
             
             //TODO TCF 返回执行链依次执行所有织入的增强处理
             @Override
             public Object intercept(Object targetObject, Method targetMethod, Object[] methodParams, MethodProxy methodProxy) throws Throwable 
             {
                 return new ProxyChain(targetClass, targetObject, targetMethod, methodParams, methodProxy, proxyList)
                         .doProxyChain();
             }
             
         });
         
         return result;
     }
 }
  package com.tcf.kid.base.core;
import java.lang.reflect.Method;
/***
  * TODO TCF 定义切面,实现代理接口,其他类型切面直接继承该切面父类即可
  * @author Hasee
  *
  */
 public abstract class ProxyAspect implements Proxy{    //TODO TCF 代理织入主体(根据需要织入增强处理)
     @Override
     public Object doProxy(ProxyChain proxyChain) 
     {
         //TODO TCF 执行链执行返回代理方法执行结果
         Object result=null;
         
         //TODO TCF 代理目标类
         Class<?> targetClass=proxyChain.getTargetClass();
         
         //TODO TCF 代理目标方法
         Method targetMehod=proxyChain.getTargetMethod();
         
         //TODO TCF 代理目标方法参数
         Object[] methodParams=proxyChain.getMethodParams();
         
         try
         {
             //TODO TCF 织入增强处理
             before(targetClass, targetMehod, methodParams);
             
             //TODO TCF 代理执行链
             result=proxyChain.doProxyChain();
             
             after(targetClass, targetMehod, methodParams, result);
         }
         catch(Throwable e)
         {
             e.printStackTrace();
         }
         
         return result;
     }
     
     //TODO TCF 封装通用的增强处理方法(代理目标类,代理方法,方法参数,执行返回值)
     //TODO TCF 前置增强
     public void before(Class<?> targetClass,Method method,Object[] args)
     {
         //TODO TCF 前置增强处理
         //System.out.println("====前置增强====");
     }
     
     //TODO TCF 后置增强处理
     public void after(Class<?> targetClass,Method method,Object[] args,Object result)
     {
         //TODO TCF 后置增强处理
         //System.out.println("====后置增强====");
     }
     
 }
  package com.tcf.kid.base.aop;
import java.lang.reflect.Method;
import com.tcf.kid.base.annotation.Aspect;
 import com.tcf.kid.base.annotation.Controller;
 import com.tcf.kid.base.core.ProxyAspect;/***
  * TODO TCF 模拟某个控制器织入增强
  * @author Hasee
  *
  */
 @Aspect(Controller.class)
 public class AspectController extends ProxyAspect{    @Override
     public void before(Class<?> targetClass, Method method, Object[] args)
     {
         //super.before(targetClass, method, args);
         System.out.println("===="+targetClass.getName()+"织入前置增强====");
     }
     
     @Override
     public void after(Class<?> targetClass, Method method, Object[] args, Object result) 
     {
         //super.after(targetClass, method, args, result);
         System.out.println("===="+targetClass.getName()+"织入后置增强====");
     }
 }package com.tcf.kid.base.aop;
import com.tcf.kid.base.annotation.Controller;
@Controller
 public class TestController {    public void show()
     {
         System.out.println("====原方法====");
     }
 }
  package com.tcf.kid.base.helper;
import java.lang.annotation.Annotation;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;import com.tcf.kid.base.annotation.Aspect;
 import com.tcf.kid.base.core.Proxy;
 import com.tcf.kid.base.core.ProxyAspect;
 import com.tcf.kid.base.core.ProxyManager;/***
  * TODO TCF AOP代理助手类
  * @author Hasee
  *
  */
 public class AopHelper {    //TODO TCF 加载所有代理类和代理目标类并执行代理执行链
     static
     {
         try 
         {
             //TODO TCF 代理类,代理的多个目标类
             Map<Class<?>,Set<Class<?>>> proxyMap=createProxyMap();
             
             //TODO TCF 目标类,目标的多个代理类
             Map<Class<?>,List<Proxy>> targetMap=createTargetMap(proxyMap);
             
             if(targetMap!=null)
             {
                 for(Map.Entry<Class<?>,List<Proxy>> entry:targetMap.entrySet())
                 {
                     //TODO TCF 代理的目标类
                     Class<?> targetClass=entry.getKey();
                     
                     //TODO TCF 目标类的所有代理类
                     List<Proxy> proxyList=entry.getValue();
                     
                     System.out.println(proxyList.size());
                     
                     //TODO TCF 创建代理并执行代理执行链(按顺序执行每个代理的目标方法),返回代理执行链
                     Object proxy=ProxyManager.createProxy(targetClass,proxyList);
                     
                     //TODO TCF 存入Bean类型和Bean实例映射Map
                     BeanHelper.putBean(targetClass,proxy);
                 }
             }
         } 
         catch (Throwable e) 
         {
             e.printStackTrace();
         }
     }
     
     //TODO TCF 根据注解加载所有注解类
     public static Set<Class<?>> loadAspectClasses(Aspect aspect)
     {
         Set<Class<?>> classList=new HashSet<Class<?>>();
         
         //TODO TCF 切面注解类的反射
         Class<? extends Annotation> annotation=aspect.value();
         if(annotation!=null && !annotation.equals(Aspect.class))
         {
             //TODO TCF 加载定义了切面注解的类
             classList=ClassHelper.loadClassByAnnotation(annotation);
         }
         
         return classList;
     }
     
     //TODO TCF 读取所有代理类和代理的目标类
     public static Map<Class<?>,Set<Class<?>>> createProxyMap()
     {
         Map<Class<?>,Set<Class<?>>> map=new HashMap<Class<?>,Set<Class<?>>>();
         
         //TODO TCF 所有继承公共切面的代理类
         Set<Class<?>> classList=ClassHelper.loadClassBySuperClass(ProxyAspect.class);
         
         if(classList!=null && classList.size()>0)
         {
             for(Class<?> proxyClass:classList)
             {
                 if(proxyClass.isAnnotationPresent(Aspect.class))
                 {
                     //TODO TCF 获取当前代理类定义的注解
                     Aspect aspect=proxyClass.getAnnotation(Aspect.class);
                     
                     //TODO TCF 根据注解加载代理的所有目标类
                     Set<Class<?>> targetClassList=loadAspectClasses(aspect);
                     
                     //TODO TCF 代理类作为key,代理的所有目标类作为value
                     map.put(proxyClass,targetClassList);
                 }
             }
         }
         
         return map;
     }
     
     //TODO TCF 读取所有目标类和目标类的所有代理类
     public static Map<Class<?>,List<Proxy>> createTargetMap(Map<Class<?>,Set<Class<?>>> beforeMap) throws Throwable
     {
         Map<Class<?>, List<Proxy>> map=new HashMap<Class<?>,List<Proxy>>();
         
         if(beforeMap!=null)
         {
             for(Map.Entry<Class<?>,Set<Class<?>>> entry:beforeMap.entrySet())
             {
                 //TODO TCF 代理类
                 Class<?> proxyClass=entry.getKey();
                 
                 //TODO TCF 代理的所有目标类
                 Set<Class<?>> targetClassList=entry.getValue();
                 
                 for(Class<?> targetClass:targetClassList)
                 {
                     //TODO TCF 当前目标类的代理类
                     Proxy proxy=(Proxy)proxyClass.newInstance();
                     
                     if(map.containsKey(targetClass))
                     {
                         map.get(targetClass).add(proxy);
                     }
                     else
                     {
                         List<Proxy> proxyList=new ArrayList<Proxy>();
                         proxyList.add(proxy);
                         map.put(targetClass,proxyList);
                     }
                 }
             }
         }
         
         return map;
     }
 }
  package com.tcf.kid.base.helper;
import java.lang.annotation.Annotation;
 import java.util.HashSet;
 import java.util.Set;import com.tcf.kid.base.annotation.Controller;
 import com.tcf.kid.base.annotation.Service;
 import com.tcf.kid.base.util.ClassUtil;
 import com.tcf.kid.base.util.PropertiesUtil;/***
  * TODO TCF 类加载器助手类
  * @author Hasee
  *
  */
 public class ClassHelper {    public static String packageName=PropertiesUtil.getProperties("base_package");
     
     //TODO TCF 加载的所有文件
     public static Set<Class<?>> CLASSLIST=new HashSet<Class<?>>();
     
     //TODO TCF 加载所有文件的方法
     static
     {
         CLASSLIST=ClassUtil.loadClassPackage(packageName);
     }
     
     //TODO TCF 加载Service注解类
     public static Set<Class<?>> loadServiceClasses()
     {
         Set<Class<?>> classes=new HashSet<Class<?>>();
         if(CLASSLIST!=null && CLASSLIST.size()>0)
         {
             for(Class<?> cls:CLASSLIST)
             {
                 if(cls.isAnnotationPresent(Service.class))
                 {
                     classes.add(cls);
                 }
             }
         }
         
         return classes;
     }
     
     //TODO TCF 加载Controller注解类
     public static Set<Class<?>> loadControllerClasses()
     {
         Set<Class<?>> classes=new HashSet<Class<?>>();
         
         if(CLASSLIST!=null && CLASSLIST.size()>0)
         {
             for(Class<?> cls:CLASSLIST)
             {
                 if(cls.isAnnotationPresent(Controller.class))
                 {
                     classes.add(cls);
                 }
             }
         }
         
         return classes;
     }
     
     //TODO TCF 加载所有Inject注解类
     public static Set<Class<?>> loadBeanClasses()
     {
         Set<Class<?>> classes=new HashSet<Class<?>>();
         classes.addAll(loadServiceClasses());
         classes.addAll(loadControllerClasses());
         return classes;
     }
     
     //TODO TCF 根据注解加载标注的类
     public static Set<Class<?>> loadClassByAnnotation(Class<? extends Annotation> annotation)
     {
         Set<Class<?>> classList=new HashSet<Class<?>>();
         
         if(CLASSLIST!=null && CLASSLIST.size()>0)
         {
             for(Class<?> cls:CLASSLIST)
             {
                 if(cls.isAnnotationPresent(annotation))
                 {
                     classList.add(cls);
                 }
             }
         }
         
         return classList;
     }
     
     //TODO TCF 根据父类加载所有子类或接口实现类
     public static Set<Class<?>> loadClassBySuperClass(Class<?> superClass)
     {
         Set<Class<?>> classList=new HashSet<Class<?>>();
         
         if(CLASSLIST!=null && CLASSLIST.size()>0)
         {
             for(Class<?> cls:CLASSLIST)
             {
                 //TODO TCF superClass From childClass == childClass instanceof superClass
                 if(superClass.isAssignableFrom(cls) && !superClass.equals(cls))
                 {
                     classList.add(cls);
                 }
             }
         }
         
         return classList;
     }
 }
  package com.tcf.kid.test;
import java.util.HashSet;
 import java.util.Set;import com.tcf.kid.base.aop.TestController;
 import com.tcf.kid.base.helper.AopHelper;
 import com.tcf.kid.base.helper.BeanHelper;
 import com.tcf.kid.base.helper.ClassHelper;
 import com.tcf.kid.base.helper.IoCHelper;
 import com.tcf.kid.base.util.ClassUtil;public class Test {
    public static void main(String[] args) 
     {
         Set<Class<?>> classes=new HashSet<Class<?>>();
         classes.add(ClassHelper.class);
         classes.add(BeanHelper.class);
         
         //TODO TCF AOP 基于 cglib动态代理
         classes.add(AopHelper.class);
                 
         //TODO TCF IOC/DI
         //classes.add(IoCHelper.class);
         
         for(Class<?> cls:classes)
         {
             ClassUtil.loadClass(cls.getName());
         }
         
         new TestController().show();
     }
 }