纯手写轻量级springioc aop

 

github地址:https://github.com/919337588/cxaopioc

大致目录结构如此

纯手写轻量级springioc aop_第1张图片

注释算是非常清晰,比直接看源码容易理解的多 我写的是注解版

大致逻辑就是 

1扫描包下的类

2如果类存在注入bean所需的注解 将bean放入bean容器

3查看beanA中的属性 如果属性需要注入 就在bean容器中找到对应的beanB 并且注入到beanA的属性中

4 使用cglib动态代理所有的bean 达到aop效果

ClassUtil是网址寻找的反射工具类
package com.chixin.spring;

import com.chixin.note.CxAutowired;
import com.chixin.note.CxCompent;
import com.chixin.note.CxControl;
import com.chixin.note.CxService;
import com.chixin.utils.ClassUtil;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ApplicationContext {
    /*扫包地址*/
    private String packagePath;
    //bean容器
    private ConcurrentHashMap beanfactory;
    /*bean注释集合*/
    private static HashSet containerAnnotations;

    static {
        //初始化bean的注入注解
        containerAnnotations=new HashSet();
        containerAnnotations.add(CxControl.class);
        containerAnnotations.add(CxService.class);
        containerAnnotations.add(CxCompent.class);
    }
    public ApplicationContext(String packagePath) throws Exception {
        this.packagePath=packagePath;
        beanfactory = new ConcurrentHashMap();
        //初始化bean
        initBeans();
        //完善bean
        beanDecoration();
    }
  // 初始化bean对象
    public void initBeans() throws Exception {
        List listClassesAnnotation= findClassExisService();
        for (Class classInfo : listClassesAnnotation) {
            // 初始化对象
            Object newInstance =classInfo.newInstance();
            // bean放入容器
            beanfactory.put(classInfo, newInstance);
        }
    }
    //完善bean
    public void beanDecoration() throws Exception {
        for(Map.Entry val: beanfactory.entrySet()){
            //给bean的属性注入值
            attriAssign(val.getValue());
            //aop包裹
            doAop(val);
        };
    }
    // 使用反射读取类的属性,赋值信息
    public void attriAssign(Object object) throws Exception {
        // 1.获取类的属性是否存在 获取bean注解
        Class classInfo = object.getClass();
        Field[] declaredFields = classInfo.getDeclaredFields();
        for (Field field : declaredFields) {
            if (field.getDeclaredAnnotation(CxAutowired.class) != null) {
                Object bean = beanfactory.get(field.getType());
                if (bean != null) {
                    // 私有访问允许访问
                    field.setAccessible(true);
                    // 给属性赋值
                    field.set(object, bean);
                }
            }
        }
    }
    // bean变为aop代理对象
    public void doAop(Map.Entry val ) throws Exception {
        val.setValue(CglibProxy.initAop(val.getValue()));
    }

    // 使用反射机制获取该包下所有的类已经存在bean的注解类
    public List findClassExisService() throws Exception {
        // 1.使用反射机制获取该包下所有的类
        if (StringUtils.isBlank(packagePath)) {
            throw new Exception("扫包地址不能为空!");
        }
        // 2.使用反射技术获取当前包下所有的类
        List> classesByPackageName = ClassUtil.getClasses(packagePath);
        // 3.存放类上有bean注入注解
        List exisClassesAnnotation = new LinkedList<>();
        // 4.判断该类上属否存在注解
        for (Class classInfo : classesByPackageName) {
            for (Class containerAnnotation:containerAnnotations){
                Object cx =  classInfo.getDeclaredAnnotation(containerAnnotation);
                if (cx != null) {
                    exisClassesAnnotation.add(classInfo);
                    break;
                }
            }
        }
        return exisClassesAnnotation;
    }
    public T getBean(Class classinfo){
        return (T) beanfactory.get(classinfo);
    }
}
package com.chixin.spring;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class CglibProxy implements MethodInterceptor {
    private Object tar;
    CglibProxy(Object tar){
        this.tar=tar;
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object result = null;
       try {
           System.out.println("----------------------------------"+method.getDeclaringClass().getName()+" "+method.getName()+" aop前置捕捉");
           result = methodProxy.invoke(tar, objects);
           System.out.println("----------------------------------"+method.getDeclaringClass().getName()+" "+method.getName()+" aop后置捕捉");
       }catch (Exception e){
           System.out.println("----------------------------------"+method.getDeclaringClass().getName()+" "+method.getName()+" aop异常捕捉");
       }
        return result;
    }
    public static Object initAop(Object classInfo) throws Exception {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(classInfo.getClass());
        enhancer.setCallback(new CglibProxy(classInfo));
        return enhancer.create();
    }

}

 

你可能感兴趣的:(手写源码)