Spring IOC和AOP整合手写源码总结

                                          Spring IOC和AOP整合手写源码总结

                                                                                                                                                                                     作者:田超凡

                                                                                                                                                                       时间:2019年8月20日

1.maven依赖

因为整个项目是纯手写的,所以只需要依赖Apache的一些工具包,如collection、lang包,以及实现aop动态代理功能的cglib源包

<dependencies>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>

        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.5</version>
        </dependency>

    </dependencies>

2.base.properties 属性文件

作用:指定IOC扫描的基准包,一般配置为顶级包,下文IOC实现部分会递归扫描该基准包下的类

base_package=com.tcf.smart.framework.demo

3.PropertiesUtil工具类

 作用:

 (1).属性文件工具类,根据指定的属性文件名加载对应的属性文件
 (2).根据Key获取属性值

package com.tcf.smart.framework.util;

import java.io.IOException;
import java.util.Properties;

/***
 * TODO TCF 属性文件工具类,根据指定的属性文件名加载对应的属性文件
 * TODO TCF 根据Key获取属性值
 * @author 71485
 *
 */
public class PropertiesUtil {

    //TODO TCF 采用单例模式-饿汉模式
    private static Properties properties=new Properties();
    
    //TODO TCF 根据属性文件名加载属性文件
    public static Properties loadProperties(String propertiesFileName)
    {
        try
        {
            properties.load(PropertiesUtil.class.getClassLoader().getResourceAsStream(propertiesFileName));
        } 
        catch (IOException e)
        {
            e.printStackTrace();
        }
        
        return properties;
    }
    
    //TODO TCF 根据Key获取属性文件value
    public static String getProperty(String key)
    {
        return properties.getProperty(key);
    }
}

4.ClassUtil工具类

作用:

(1).类加载器工具类,获取类加载器、根据类名加载类、根据类名一次加载一个类、根据类名、包路径、包名一次加载所有子类、根据包名加载包及其子包下的所有类文件

package com.tcf.smart.framework.util;

import java.io.File;
import java.io.FileFilter;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.apache.commons.lang3.StringUtils;

import com.tcf.smart.framework.common.Const;

/***
 * TODO TCF 类加载器工具类
 * TODO TCF 获取类加载器、根据类名加载类、根据类名一次加载一个类、根据类名、包路径、包名一次加载所有子类、根据包名加载包及其子包下的所有类文件
 * @author 71485
 *
 */
public class ClassUtil {

    //TODO TCF 获取类加载器
    public static ClassLoader getClassLoader()
    {
        return Thread.currentThread().getContextClassLoader();
    }
    
    //TODO TCF 根据类名加载类
    public static Class<?> loadClassByName(String className)
    {
        Class<?> cls=null;
        try
        {
            cls=Class.forName(className,true,getClassLoader());
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        
        return cls;
    }
    
    //TODO TCF 根据类名一次加载一个类
    public static void addSingleClass(Set<Class<?>> classList,String className)
    {
        try
        {
            Class<?> cls=loadClassByName(className);
            classList.add(cls);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    
    //TODO TCF 根据包路径和包名递归加载所有类文件
    public static void addClassBatch(Set<Class<?>> classList,String packagePath,String packageName)
    {
        try
        {
            if(StringUtils.isNotEmpty(packagePath))
            {
                //TODO TCF 要扫描的基准目录
                File dirFile=new File(packagePath);
                
                if(dirFile!=null)
                {
                    File[] files=dirFile.listFiles(new FileFilter() {
                        
                        @Override
                        public boolean accept(File file) 
                        {
                            return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();
                        }
                    });
                    
                    if(files!=null && files.length>0)
                    {
                        for(File file:files)
                        {
                            String fileName=file.getName();
                            
                            if(StringUtils.isNotEmpty(fileName))
                            {
                                if(file.isFile())
                                {
                                    //TODO TCF 扫描到的类文件加载到类加载器
                                    String className=fileName.substring(0,fileName.lastIndexOf("."));
                                    if(StringUtils.isNotEmpty(packageName))
                                    {
                                        className=packageName+"."+className;
                                    }
                                    
                                    addSingleClass(classList,className);
                                }
                                else
                                {
                                    //TODO TCF 获取子包路径、子包名并递归加载
                                    String subPackagePath=fileName;
                                    if(StringUtils.isNotEmpty(packagePath))
                                    {
                                        subPackagePath=packagePath+"/"+subPackagePath;
                                    }
                                    
                                    String subPackageName=fileName;
                                    if(StringUtils.isNotEmpty(packageName))
                                    {
                                        subPackageName=packageName+"."+subPackageName;
                                    }
                                    
                                    addClassBatch(classList, subPackagePath, subPackageName);
                                }
                            }
                        }
                    }
                }
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    
    //TODO TCF 根据包名递归加载所有类文件
    public static Set<Class<?>> loadClassSetByPackageName(String packageName)
    {
        Set<Class<?>> classList=new HashSet<Class<?>>();
        
        try 
        {
            Enumeration<URL> urls=getClassLoader().getResources(packageName.replace(".","/"));
            if(urls!=null)
            {
                while(urls.hasMoreElements())
                {
                    URL url=urls.nextElement();
                    
                    if(url!=null)
                    {
                        //TODO TCF URL协议类型
                        String protocol=url.getProtocol();
                        
                        if(StringUtils.isNotEmpty(protocol))
                        {
                            if(protocol.equals(Const.URL_PROTOCOLS.FILE))
                            {
                                //TODO TCF 文件协议
                                String packagePath=url.getPath().replaceAll("%20"," ");
                                addClassBatch(classList, packagePath, packageName);
                            }
                            else if(protocol.equals(Const.URL_PROTOCOLS.JAR))
                            {
                                //TODO TCF JAR包协议
                                JarURLConnection jarURLConnection=(JarURLConnection)url.openConnection();
                                
                                if(jarURLConnection!=null)
                                {
                                    JarFile jarFile=jarURLConnection.getJarFile();
                                    
                                    if(jarFile!=null)
                                    {
                                        Enumeration<JarEntry> entries=jarFile.entries();
                                        if(entries!=null)
                                        {
                                            while(entries.hasMoreElements())
                                            {
                                                JarEntry jarEntry=entries.nextElement();
                                                
                                                if(jarEntry!=null)
                                                {
                                                    //TODO TCF jar文件名称
                                                    String entryName=jarEntry.getName();
                                                    
                                                    if(StringUtils.isNotEmpty(entryName) && entryName.endsWith(".class"))
                                                    {
                                                        String className=entryName.substring(0,entryName.lastIndexOf(".")).replace("/",".");
                                                        addSingleClass(classList,className);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
        }
        
        return classList;
    }
}

5.ReflectUtil工具类

作用:

(1).反射工具类,根据类型创建实例、基于反射机制执行对应方法、给对应属性注入属性值

package com.tcf.smart.framework.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/***
 * TODO TCF 反射工具类
 * TODO TCF 根据类型创建实例、基于反射机制执行对应方法、给对应属性注入属性值
 * @author 71485
 *
 */
public class ReflectUtil {

    //TODO TCF 根据类型基于反射机制创建对应类型实例
    public static Object newInstance(Class<?> cls)
    {
        Object instance=null;
        
        try
        {
            instance=cls.newInstance();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        
        return instance;
    }
    
    //TODO TCF 基于反射机制给目标属性注入属性值
    public static void setField(Object instance,Field field,Object fieldValue)
    {
        try
        {
            field.setAccessible(true);
            field.set(instance,fieldValue);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    
    //TODO TCF 基于反射机制执行目标实例的方法
    public static Object invokeMethod(Object instance,Method method,Object[] methodParams)
    {
        Object result=null;
        
        try
        {
            result=method.invoke(instance,methodParams);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        
        return result;
    }
}
 

6.ClassHelper助手类

作用:

(1).类加载器助手类,初始化加载基准包下的所有类存入临时容器,提供根据注解加载指定类的通用方法,提供根据继承关系加载父类下所有子类或接口所有实现类的方法

package com.tcf.smart.framework.helper;

import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;
import com.tcf.smart.framework.annotation.KidComponent;
import com.tcf.smart.framework.annotation.KidController;
import com.tcf.smart.framework.annotation.KidRepository;
import com.tcf.smart.framework.annotation.KidService;
import com.tcf.smart.framework.common.Const;
import com.tcf.smart.framework.util.ClassUtil;
import com.tcf.smart.framework.util.PropertiesUtil;

/**
 * TODO TCF 类加载器助手类
 * TODO TCF 初始化加载基准包下的所有类存入临时容器,提供根据注解加载指定类的通用方法,提供根据继承关系加载父类下所有子类或接口所有实现类的方法
 * @author 71485
 *
 */
public class ClassHelper {

    public static Set<Class<?>> CLASS_LIST=new HashSet<Class<?>>();
    
    static
    {
        CLASS_LIST=ClassUtil.loadClassSetByPackageName(PropertiesUtil.loadProperties(Const.PROPERTIES_FILES.BASE_PROPERTIES).getProperty(Const.BASE_KEYS.BASE_PACKAGE));
    }
    
    //TODO TCF 根据注解加载对应类
    public static Set<Class<?>> loadClassByAnnotation(Class<? extends Annotation> annotation)
    {
        Set<Class<?>> classList=new HashSet<Class<?>>();
        
        if(CLASS_LIST!=null && CLASS_LIST.size()>0)
        {
            for(Class<?> cls:CLASS_LIST)
            {
                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(CLASS_LIST!=null && CLASS_LIST.size()>0)
        {
            for(Class<?> cls:CLASS_LIST)
            {
                if(superClass.isAssignableFrom(cls) && !superClass.equals(cls))
                {
                    classList.add(cls);
                }
            }
        }
        
        return classList;
    }
    
    //TODO TCF 加载预定义的注解标注类
    public static Set<Class<?>> loadClassExample()
    {
        Set<Class<?>> classList=new HashSet<Class<?>>();
        
        classList.addAll(loadClassByAnnotation(KidComponent.class));
        classList.addAll(loadClassByAnnotation(KidRepository.class));
        classList.addAll(loadClassByAnnotation(KidService.class));
        classList.addAll(loadClassByAnnotation(KidController.class));
        
        return classList;
    }
}
 

7.BeanHelper助手类

作用:

(1).自定义Bean组件及Bean实例映射管理工具类
(2).初始化加载Bean组件及其对应Bean实例,提供根据Bean类型获取Bean实例方法,提供存取元素方法

package com.tcf.smart.framework.helper;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/***
 * TODO TCF 自定义Bean组件及Bean实例映射管理工具类
 * TODO TCF 初始化加载Bean组件及其对应Bean实例,提供根据Bean类型获取Bean实例方法,提供存取元素方法
 * @author 71485
 *
 */
public class BeanHelper {

    public static Map<Class<?>,Object> BEAN_MAP=new HashMap<Class<?>,Object>();
    
    static
    {
        Set<Class<?>> classList=ClassHelper.CLASS_LIST;
        if(classList!=null && classList.size()>0)
        {
            for(Class<?> cls:classList)
            {
                try 
                {
                    Object instance=cls.newInstance();
                    BEAN_MAP.put(cls,instance);
                } 
                catch (Exception e) 
                {
                    e.printStackTrace();
                }
            }
        }
    }
    
    //TODO TCF 根据Bean类型获取Bean实例
    public static Object getBeanByClass(Class<?> cls)
    {
        return BEAN_MAP.get(cls);
    }
    
    //TODO TCF 存入Bean组件和Bean实例映射元素
    public static void putBeanMapping(Class<?> cls,Object instance)
    {
        BEAN_MAP.put(cls,instance);
    }
}

8.SpringIOC类加载器:IocHelper

作用:

(1).DI/IOC依赖注入助手类,加载基准包下的类并注入属性值,反射方法进行调用

package com.tcf.smart.framework.helper;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.tcf.smart.framework.annotation.Aspect;
import com.tcf.smart.framework.annotation.KidController;
import com.tcf.smart.framework.annotation.KidInject;
import com.tcf.smart.framework.demo.TestDemoFirst;
import com.tcf.smart.framework.demo.TestDemoSecond;
import com.tcf.smart.framework.demo.TestDemoThird;
import com.tcf.smart.framework.util.ReflectUtil;

/***
 * TODO TCF DI/IOC依赖注入助手类,加载基准包下的类并注入属性值,反射方法进行调用
 * @author 71485
 *
 */
public class IocHelper {

    static
    {
        //TODO TCF simpleClassName => fieldName:fieldValue
        Map<String,Map<String,Object>> fieldMap=new HashMap<String, Map<String,Object>>();
        
        //TODO TCF 需要注入的属性名:属性值
        Map<String,Object> paramMap=new HashMap<String,Object>();
        paramMap.put("name","张三");
        fieldMap.put(TestDemoFirst.class.getSimpleName(),paramMap);
        
        paramMap=new HashMap<String,Object>();
        paramMap.put("age",18);
        fieldMap.put(TestDemoSecond.class.getSimpleName(),paramMap);
        
        paramMap=new HashMap<String,Object>();
        paramMap.put("first",new TestDemoFirst());
        fieldMap.put(TestDemoThird.class.getSimpleName(),paramMap);
        
        //TODO TCF 启动容器,实现DI/IOC依赖注入
        init(fieldMap);
    }
    
    //TODO TCF DI/IOC容器启动
    public static void init(Map<String,Map<String,Object>> fieldMap)
    {
        //TODO TCF 获取Bean组件和实例映射Map
        Map<Class<?>,Object> beanMap=BeanHelper.BEAN_MAP;
        
        if(beanMap!=null)
        {
            for(Map.Entry<Class<?>,Object> entry:beanMap.entrySet())
            {
                //TODO TCF 目标类型
                Class<?> targetClass=entry.getKey();
                
                //TODO TCF 过滤AOP已经加载的代理类
                if(targetClass.isAnnotationPresent(Aspect.class))
                {
                    continue;
                }
                
                //TODO TCF 目标类型实例
                Object instance=entry.getValue();
                
                //TODO TCF 目标类型下面定义的所有属性
                Field[] fields=targetClass.getDeclaredFields();
                
                if(fields!=null && fields.length>0)
                {
                    for(Field field:fields)
                    {
                        if(field.isAnnotationPresent(KidInject.class))
                        {
                            //TODO TCF 参数注入使用KidInject注解标注的属性
                            for(Map.Entry<String,Map<String,Object>> fieldEntry:fieldMap.entrySet())
                            {
                                //TODO TCF 属性所在类型名称
                                String className=fieldEntry.getKey();
                                
                                //TODO TCF 属性KEY-VALUE键值对
                                Map<String,Object> paramMap=fieldEntry.getValue();
                            
                                if(StringUtils.isNotEmpty(className))
                                {
                                    if(className.equals(targetClass.getSimpleName()))
                                    {
                                        //TODO TCF 注入属性值
                                        for(Map.Entry<String,Object> destEntry:paramMap.entrySet())
                                        {
                                            //TODO TCF 属性值
                                            Object fieldValue=destEntry.getValue();
                                            
                                            //TODO TCF 注入属性值
                                            ReflectUtil.setField(instance, field, fieldValue);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                
                //TODO TCF 只执行AOP代理的控制器方法
                //TODO TCF 实际可以去掉该条件或换成其他条件,满足条件的目标类中的方法会被执行
                if(targetClass.isAnnotationPresent(KidController.class))
                {
                    //TODO TCF 反射执行目标方法
                    Method[] methods=targetClass.getDeclaredMethods();
                    if(methods!=null && methods.length>0)
                    {
                        for(Method method:methods)
                        {
                            //TODO TCF 方法参数
                            Object[] methodParams=null;
                            
                            //TODO TCF ...方法入参补全
                            ReflectUtil.invokeMethod(instance, method, methodParams);
                        }
                    }
                }
            }
        }
    }
}


9.注解定义类

作用:自定义项目需要使用的注解及其功能

@KidComponent 注册普通组件 => @Component

@KidRepository 注册持久层组件 => @Repository

@KidService 注册业务层组件 => @Service

@KidController 注册控制器组件 => @Controller

@KidInject 显式指定需要注入值的属性 => @Inject

@Aspect 定义切面类 => @Aspect

package com.tcf.smart.framework.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 KidComponent {

}
 

package com.tcf.smart.framework.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 KidRepository {

}

package com.tcf.smart.framework.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 KidService {

}
 

package com.tcf.smart.framework.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface KidInject {

}
 

package com.tcf.smart.framework.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 KidController {

}
 

package com.tcf.smart.framework.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;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Aspect {

    //TODO TCF 获取切面注解值
    Class<? extends Annotation> value();
}
 

10.常量类Const

package com.tcf.smart.framework.common;
/***
 * TODO TCF 常量类
 * @author 71485
 *
 */
public class Const {

    //TODO TCF 属性配置文件名
    public static class PROPERTIES_FILES
    {
        //TODO TCF IOC和AOP配置文件
        public static final String BASE_PROPERTIES="base.properties";
    }
    
    //TODO TCF URL协议类型
    public static class URL_PROTOCOLS
    {
        //TODO TCF file文件协议
        public static final String FILE="file";
        
        //TODO TCF jar文件协议
        public static final String JAR="jar";
    }
    
    //TODO TCF 属性文件key
    public static class BASE_KEYS
    {
        //TODO TCF 基准包目录
        public static final String BASE_PACKAGE="base_package";
    }
}
 

11.AOP代理接口

作用:

(1).代理接口,定义封装的切面方法织入各类增强,调用代理实例的执行链依次执行代理方法

package com.tcf.smart.framework.aop;

/**
 * TODO TCF 代理接口,定义封装的切面方法织入各类增强,调用代理实例的执行链依次执行代理方法
 * @author 71485
 *
 */
public interface Proxy {

    //TODO TCF 执行增强方法
    public Object doProxy(ProxyChain proxyChain);
}
 

12.AOP代理执行链

作用:

(1).代理实例执行链,跟踪代理实例执行顺序

package com.tcf.smart.framework.aop;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import net.sf.cglib.proxy.MethodProxy;

/***
 * TODO TCF 代理实例执行链,跟踪代理实例执行顺序
 * @author 71485
 *
 */
public class ProxyChain {

    //TODO TCF 代理目标类型
    private Class<?> targetClass;
    
    //TODO TCF 代理目标实例
    private Object targetInsatnce;
    
    //TODO TCF 代理目标方法
    private Method targetMethod;
    
    //TODO TCF 代理方法
    private MethodProxy methodProxy;
    
    //TODO TCF 方法参数
    private Object[] methodParams;
    
    //TODO TCF 存放代理实例的集合
    private List<Proxy> proxyList=new ArrayList<Proxy>();
    
    //TODO TCF 记录执行链执行索引
    private static Integer proxyExecuteIndex=0;
    
    //TODO TCF 获取代理目标类型、目标实例、目标方法、方法参数
    public Class<?> getTargetClass() {
        return targetClass;
    }
    public Object getTargetInsatnce() {
        return targetInsatnce;
    }
    public Method getTargetMethod() {
        return targetMethod;
    }
    public Object[] getMethodParams() {
        return methodParams;
    }
    public List<Proxy> getProxyList() {
        return proxyList;
    }
    
    //TODO TCF 构造注入代理信息
    public ProxyChain(
                 Class<?> targetClass,
                 Object targetInstance,
                 Method targetMethod,
                 MethodProxy methodProxy,
                 Object[] methodParams,
                 List<Proxy> proxyList
            )
    {
        this.targetClass=targetClass;
        this.targetInsatnce=targetInstance;
        this.targetMethod=targetMethod;
        this.methodProxy=methodProxy;
        this.methodParams=methodParams;
        this.proxyList=proxyList;
    }
    
    //TODO TCF 代理执行链启动
    public Object doProxyChain()
    {
        Object result=null;
        if(proxyExecuteIndex<proxyList.size())
        {
            result=proxyList.get(proxyExecuteIndex++).doProxy(this);
        }
        else
        {
            try 
            {
                result=methodProxy.invokeSuper(targetInsatnce,methodParams);
            } 
            catch (Throwable e) 
            {
                e.printStackTrace();
            }
        }
        
        return result;
    }
}
 

13.CGLIB代理工厂ProxyManager

作用:

(1).代理模式工厂类,基于cglib创建多个代理实例并执行对应代理方法

package com.tcf.smart.framework.aop;

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 代理模式工厂类,基于cglib创建多个代理实例并执行对应代理方法
 * @author 71485
 *
 */
public class ProxyManager {

    @SuppressWarnings("unchecked")
    public static <T> T newProxyInstance(Class<?> targetClass,List<Proxy> proxyList)
    {
        return (T) Enhancer.create(targetClass,new MethodInterceptor() {
            
            @Override
            public Object intercept(Object targetInstance, 
                    Method targetMethod, 
                    Object[] methodParams,
                    MethodProxy methodProxy) throws Throwable
            {
                return new ProxyChain(targetClass, targetInstance, targetMethod, methodProxy, methodParams, proxyList).doProxyChain();
            }
            
        });
    }
}

14.封装后的通用切面类ProxyAspect

作用:

(1).切面基类,定义通用的各类增强处理方法,其他切面类直接继承该类重写对应增强处理即可

package com.tcf.smart.framework.aop;

/***
 * TODO TCF 切面基类,定义通用的各类增强处理方法,其他切面类直接继承该类重写对应增强处理即可
 * @author 71485
 *
 */
public abstract class ProxyAspect implements Proxy{

    @Override
    public Object doProxy(ProxyChain proxyChain) 
    {
        Object result=null;
        
        //TODO TCF 织入增强处理
        try
        {
            before();
            result=proxyChain.doProxyChain();
            after();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        
        return result;
    }
    
    //TODO TCF 自定义各类增强处理
    //TODO TCF 前置增强
    public void before()
    {
        System.out.println("====前置增强 before====");
    }
    
    //TODO TCF 后置增强
    public void after()
    {
        System.out.println("====后置增强 afterReturning====");
    }
}
 

15.AOP核心控制器(助手类)AopHelper

作用:

(1).AOP切面助手类
(2).初始化加载所有基准包下的目标类及其对应的代理类,批量创建每个目标类的多个代理实例并调用对应的代理方法执行(织入增强处理效果)

package com.tcf.smart.framework.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.smart.framework.annotation.Aspect;
import com.tcf.smart.framework.aop.Proxy;
import com.tcf.smart.framework.aop.ProxyAspect;
import com.tcf.smart.framework.aop.ProxyManager;

/***
 * TODO TCF AOP切面助手类
 * TODO TCF 初始化加载所有基准包下的目标类及其对应的代理类,批量创建每个目标类的多个代理实例并调用对应的代理方法执行(织入增强处理效果)
 * @author 71485
 *
 */
public class AopHelper {

    static
    {
        //TODO TCF 加载基准包下的所有代理类
        //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();
                
                //TODO TCF 批量创建cglib代理实例
                Object result=ProxyManager.newProxyInstance(targetClass, proxyList);
                
                //TODO TCF 存入Bean组件和Bean实例映射(目标类的实例使用创建的代理实例);
                BeanHelper.putBeanMapping(targetClass,result);
            }
        }
    } 
    
    //TODO TCF 读取切面子类(目标类)
    public static Set<Class<?>> loadByAspect(Aspect aspect)
    {
        Set<Class<?>> classList=new HashSet<Class<?>>();
        
        Class<? extends Annotation> annotation=aspect.value();
        
        if(annotation!=null && !annotation.equals(Aspect.class))
        {
            classList.addAll(ClassHelper.loadClassByAnnotation(annotation));
        }
        
        return classList;
    }
    
    //TODO TCF 读取代理类:代理的所有目标类
    public static Map<Class<?>,Set<Class<?>>> createProxyMap()
    {
        Map<Class<?>,Set<Class<?>>> proxyMap=new HashMap<Class<?>, Set<Class<?>>>();
        
        //TODO TCF 代理的所有目标类
        Set<Class<?>> classList=ClassHelper.loadClassBySuperClass(ProxyAspect.class);
    
        if(classList!=null)
        {
            for(Class<?> proxyClass:classList)
            {
                if(proxyClass.isAnnotationPresent(Aspect.class))
                {
                    Aspect aspect=proxyClass.getAnnotation(Aspect.class);
                    
                    Set<Class<?>> targetClassList=loadByAspect(aspect);
                    
                    proxyMap.put(proxyClass,targetClassList);
                }
            }
        }
        
        return proxyMap;
    }
    
    //TODO TCF 读取目标类,目标的所有代理类
    public static Map<Class<?>,List<Proxy>> createTargetMap(Map<Class<?>,Set<Class<?>>> proxyMap)
    {
        Map<Class<?>,List<Proxy>> targetMap=new HashMap<Class<?>,List<Proxy>>();
        
        if(proxyMap!=null)
        {
            for(Map.Entry<Class<?>,Set<Class<?>>> entry:proxyMap.entrySet())
            {
                //TODO TCF 代理类
                Class<?> proxyClass=entry.getKey();
                
                //TODO TCF 代理的所有目标类
                Set<Class<?>> targetClassList=entry.getValue();
                
                for(Class<?> targetClass:targetClassList)
                {
                    try 
                    {
                        Proxy proxy=(Proxy)proxyClass.newInstance();
                        
                        if(targetMap.containsKey(targetClass))
                        {
                            targetMap.get(targetClass).add(proxy);
                        }
                        else
                        {
                            List<Proxy> proxyList=new ArrayList<Proxy>();
                            proxyList.add(proxy);
                            targetMap.put(targetClass,proxyList);
                        }
                    } 
                    catch (Exception e) 
                    {
                        e.printStackTrace();
                    }
                }
            }
        }
        
        return targetMap;
    }
}
 

发布了100 篇原创文章 · 获赞 10 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_30056341/article/details/99864914