Spring AOP 源码手写实现

                                  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 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 proxyList=new ArrayList();
    
    //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 getProxyList() {
        return proxyList;
    }
    public Integer getProxyExecuteIndex() {
        return proxyExecuteIndex;
    }
    
    //TODO TCF 构造函数,注入代理参数
    public ProxyChain(Class targetClass,
            Object targetObject,
            Method targetMethod,
            Object[] methodParams,
            MethodProxy methodProxy,
            List 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         {
            //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 createProxy(final Class targetClass,final List 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,Set>> proxyMap=createProxyMap();
            
            //TODO TCF 目标类,目标的多个代理类
            Map,List> targetMap=createTargetMap(proxyMap);
            
            if(targetMap!=null)
            {
                for(Map.Entry,List> entry:targetMap.entrySet())
                {
                    //TODO TCF 代理的目标类
                    Class targetClass=entry.getKey();
                    
                    //TODO TCF 目标类的所有代理类
                    List 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> loadAspectClasses(Aspect aspect)
    {
        Set> classList=new HashSet>();
        
        //TODO TCF 切面注解类的反射
        Class annotation=aspect.value();
        if(annotation!=null && !annotation.equals(Aspect.class))
        {
            //TODO TCF 加载定义了切面注解的类
            classList=ClassHelper.loadClassByAnnotation(annotation);
        }
        
        return classList;
    }
    
    //TODO TCF 读取所有代理类和代理的目标类
    public static Map,Set>> createProxyMap()
    {
        Map,Set>> map=new HashMap,Set>>();
        
        //TODO TCF 所有继承公共切面的代理类
        Set> 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> targetClassList=loadAspectClasses(aspect);
                    
                    //TODO TCF 代理类作为key,代理的所有目标类作为value
                    map.put(proxyClass,targetClassList);
                }
            }
        }
        
        return map;
    }
    
    //TODO TCF 读取所有目标类和目标类的所有代理类
    public static Map,List> createTargetMap(Map,Set>> beforeMap) throws Throwable
    {
        Map, List> map=new HashMap,List>();
        
        if(beforeMap!=null)
        {
            for(Map.Entry,Set>> entry:beforeMap.entrySet())
            {
                //TODO TCF 代理类
                Class proxyClass=entry.getKey();
                
                //TODO TCF 代理的所有目标类
                Set> 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 proxyList=new ArrayList();
                        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> CLASSLIST=new HashSet>();
    
    //TODO TCF 加载所有文件的方法
    static
    {
        CLASSLIST=ClassUtil.loadClassPackage(packageName);
    }
    
    //TODO TCF 加载Service注解类
    public static Set> loadServiceClasses()
    {
        Set> classes=new HashSet>();
        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> loadControllerClasses()
    {
        Set> classes=new HashSet>();
        
        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> loadBeanClasses()
    {
        Set> classes=new HashSet>();
        classes.addAll(loadServiceClasses());
        classes.addAll(loadControllerClasses());
        return classes;
    }
    
    //TODO TCF 根据注解加载标注的类
    public static Set> loadClassByAnnotation(Class annotation)
    {
        Set> classList=new HashSet>();
        
        if(CLASSLIST!=null && CLASSLIST.size()>0)
        {
            for(Class cls:CLASSLIST)
            {
                if(cls.isAnnotationPresent(annotation))
                {
                    classList.add(cls);
                }
            }
        }
        
        return classList;
    }
    
    //TODO TCF 根据父类加载所有子类或接口实现类
    public static Set> loadClassBySuperClass(Class superClass)
    {
        Set> classList=new HashSet>();
        
        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> classes=new HashSet>();
        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();
    }
}
 

 

 

你可能感兴趣的:(JavaEE,Spring框架,设计模式,动态代理)