手写轻量级IOC框架

package com.pab.cc.aplus.ams.service.common.h2.ioc;

import com.pab.cc.aplus.ams.service.common.h2.mybatis.MyBatisHelper;
import com.pab.cc.aplus.ams.service.common.h2.util.AnnotationUtil;
import com.pab.cc.aplus.ams.service.common.h2.util.BeanNameUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

/**
 * bean 加载器
 */
public class BeanDefinitionLoader {

    private static Logger logger = LoggerFactory.getLogger(BeanDefinitionLoader.class);

    /**
     * 加载所有的bean定义
     */
    public static void loadAllBeanDefinition(String packageName) {

        logger.info("开始扫描【" + packageName + "】下的所有的类名...");
        // 扫描所有的类名
        List<String> classNameList;
        try {
            classNameList = PackageUtil.getClassName(packageName);
            // 去重
            classNameList = new ArrayList<>(new HashSet<>(classNameList));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        if (CollectionUtils.isEmpty(classNameList)) {
            throw new RuntimeException("com.pab包下没有java类");
        }
        for (String className : classNameList) {
            logger.info("类名: {}", className);
        }

        logger.info("扫描【" + packageName + "】下的所有的类名结束,开始获取所有的类对象...");
        // 获取所有的类对象
        List<Class> classList = new ArrayList<>(classNameList.size());
        if (CollectionUtils.isNotEmpty(classNameList)) {
            for (String c : classNameList) {
                try {
                    classList.add(Class.forName(c));
                } catch (ClassNotFoundException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        ClassHolder.classList.addAll(classList);

        logger.info("获取所有的类对象结束,加载普通bean定义(类上加了@Service @Component @Repository @Configuration注解的bean)...");
        // 加载bean定义 TODO 一个类上即有Service又有Component的情况没有做校验
        for (Class clazz : classList) {
            Annotation[] annotations = clazz.getAnnotations();
            Annotation annotation = AnnotationUtil.getOneOfAnnotation(annotations, Service.class, Component.class, Repository.class, Configuration.class);
            if (annotation != null) {
                String beanName = null;
                // bean名称使用自定义的
                if (annotation.annotationType().equals(Service.class)){
                    beanName = ((Service)annotation).value();
                } else if (annotation.annotationType().equals(Component.class)){
                    beanName = ((Component)annotation).value();
                } else if (annotation.annotationType().equals(Repository.class)){
                    beanName = ((Repository)annotation).value();
                } else if (annotation.annotationType().equals(Configuration.class)){
                    beanName = ((Configuration)annotation).value();
                }
                if (StringUtils.isEmpty(beanName)) {
                    //bean名称使用默认名称
                    beanName =  BeanNameUtil.getDefaultBeanNameByClass(clazz);
                }
                if (BeanDefinitionHolder.get(beanName) != null) {
                    String possibleReason = "请检查:类名,javaConfigBean方法名,指定的名称";
                    throw new RuntimeException("定义了多个同名Bean:【"+beanName+"】" + possibleReason);
                }
                BeanDefinition beanDefinition = new BeanDefinition();
                beanDefinition.setBeanName(beanName);
                beanDefinition.setBeanClass(clazz);
                BeanDefinitionHolder.put(beanName,beanDefinition);
            }
        }

        logger.info("加载普通bean定义结束,开始加载JavaConfig bean定义...");
        // 收集所有的@Bean的定义
        for (Map.Entry<String, BeanDefinition> entry : BeanDefinitionHolder.getBeanDefinitionMap().entrySet()) {
            BeanDefinition value = entry.getValue();
            Annotation annotation = AnnotationUtil.getAnnotationByAnnotationClass(value.getBeanClass().getAnnotations(), Configuration.class);
            if (annotation != null) {
                // 查找所有的加了@Bean的method,注入参数,执行生成Bean
                Method[] methods = value.getBeanClass().getDeclaredMethods();
                for (Method method : methods) {
                    Annotation[] methodAnnotations = method.getAnnotations();
                    Annotation beanAnnotation = AnnotationUtil.getOneOfAnnotation(methodAnnotations, Bean.class);
                    if (beanAnnotation != null) {
                        String beanName = null;
                        String[] beanNames = ((Bean)beanAnnotation).value();
                        if (beanNames.length > 0) {
                            beanName = beanNames[0];
                        } else {
                            beanNames  = ((Bean)beanAnnotation).name();
                            if (beanNames.length > 0) {
                                beanName = beanNames[0];
                            }
                        }
                        // 默认取第一个
                        if (StringUtils.isEmpty(beanName)) {
                            beanName = method.getName();
                        }
                        BeanDefinition beanDefinition = new BeanDefinition();
                        beanDefinition.setBeanName(beanName);
                        beanDefinition.setBeanClass(method.getReturnType());
                        beanDefinition.setConfigurationFlag(true);
                        beanDefinition.setJavaConfigBeanMethod(method);
                        beanDefinition.setConfigurationBeanDefinitionName(value.getBeanName());
                        BeanDefinitionHolder.put(method.getName(), beanDefinition);
                    }
                }
            }
        }
    }

    /**
     * 递归创建Bean定义 TODO 还不能解决循环依赖,如果有循环依赖会StackOverFlow
     *
     * @param clazz
     * @param dependencyBeanDefinitionList
     * @return
     */
    public static BeanDefinition createAndPutBeanDefinition(Class clazz, List<BeanDefinition> dependencyBeanDefinitionList) {

        String classDefaultBeanName = BeanNameUtil.getDefaultBeanNameByClass(clazz);
        if (BeanDefinitionHolder.get(classDefaultBeanName) != null) {
            logger.info("BeanDefinitionHolder中已存在:{}", classDefaultBeanName);
            return BeanDefinitionHolder.get(classDefaultBeanName);
        }
        BeanDefinition beanDefinition = new BeanDefinition();
        beanDefinition.setBeanName(classDefaultBeanName);
        beanDefinition.setBeanClass(clazz);
        // 查询依赖的bean的定义
//        if (dependencyBeanDefinitionList == null) {
//            dependencyBeanDefinitionList = new ArrayList<>();
//        }
//        Field[] fields = clazz.getDeclaredFields();
//        if (fields != null && fields.length > 0) {
//            for (Field field : fields) {
//                Annotation[] annotations = field.getAnnotations();
//                if (AnnotationUtil.containAnnotation(annotations, Autowired.class)) {
//                    Class fieldClass = field.getType();
//                    String defaultBeanName = BeanNameUtil.getDefaultBeanNameByClass(fieldClass);
//                    if (AnnotationUtil.containAnnotation(annotations, Qualifier.class)) {
//                        // 取Qualifier指定的bean
//                        Qualifier qualifier = (Qualifier) AnnotationUtil.getAnnotationByAnnotationClass(annotations, Qualifier.class);
//                        String value = qualifier.value();
//                        if (StringUtils.isBlank(value)) {
//                            throw new RuntimeException(clazz.getSimpleName() + "的Qualifier指定的value为空");
//                        }
//                        defaultBeanName = value;
//                    }
//                    BeanDefinition dependencyDefinition = BeanDefinitionHolder.get(defaultBeanName);
//                    if (dependencyDefinition == null) {
//                        dependencyDefinition = createAndPutBeanDefinition(field.getType(), dependencyBeanDefinitionList);
//                    }
//                    BeanDefinitionHolder.put(defaultBeanName, beanDefinition);
//                    dependencyBeanDefinitionList.add(dependencyDefinition);
//                }
//                // TODO 处理其它注解,不光有Autowired...
//            }
//        }
//        beanDefinition.setDependencyBeanDefinitionList(dependencyBeanDefinitionList);
        // 放入BeanDefinitionMap中
        BeanDefinitionHolder.put(classDefaultBeanName, beanDefinition);
        return beanDefinition;
    }

    /**
     * 更新javaConfig Bean定义,主要加载依赖bean TODO 还不能解决循环依赖,如果有循环依赖会StackOverFlow
     *
     * @param clazz
     * @param dependencyBeanDefinitionList
     * @return
     */
    public static BeanDefinition updateJavaConfigBeanDefinition(Class clazz, String classDefaultBeanName, List<BeanDefinition> dependencyBeanDefinitionList) {
        BeanDefinition beanDefinition = BeanDefinitionHolder.get(classDefaultBeanName);
        beanDefinition.setBeanName(classDefaultBeanName);
        beanDefinition.setBeanClass(clazz);
        // 查询依赖的bean的定义
        if (dependencyBeanDefinitionList == null) {
            dependencyBeanDefinitionList = new ArrayList<>();
        }
        Field[] fields = clazz.getDeclaredFields();
        if (fields != null && fields.length > 0) {
            for (Field field : fields) {
                Annotation[] annotations = field.getAnnotations();
                if (AnnotationUtil.containAnnotation(annotations, Autowired.class)) {
                    Class fieldClass = field.getType();
                    String defaultBeanName = BeanNameUtil.getDefaultBeanNameByClass(fieldClass);
                    if (AnnotationUtil.containAnnotation(annotations, Qualifier.class)) {
                        // 取Qualifier指定的bean
                        Qualifier qualifier = (Qualifier) AnnotationUtil.getAnnotationByAnnotationClass(annotations, Qualifier.class);
                        String value = qualifier.value();
                        if (StringUtils.isBlank(value)) {
                            throw new RuntimeException(clazz.getSimpleName() + "的Qualifier指定的value为空");
                        }
                        defaultBeanName = value;
                    }
                    BeanDefinition dependencyDefinition = BeanDefinitionHolder.get(defaultBeanName);
                    // 获取不到bean应该抛异常
                    if (dependencyDefinition == null) {
                        // TODO 依赖其它javaConfigBean的时候其它javaConfigBean没有加载可能也是Null
//                        throw new RuntimeException("无法获取bean定义: 【" + clazz.getSimpleName() + "】中的【" + defaultBeanName + "】, 请确认包扫描范围是否正确!");
                        if ("Dao".equals(fieldClass.getSimpleName().substring(fieldClass.getSimpleName().length()-3))) {
                            try {
                                //TODO 不光有Dao还有别的,临时处理有点low后面改
                                fieldClass = Class.forName("com.pab.cc.aplus.ams.infrastructure.dao.impl." + fieldClass.getSimpleName() + "Impl");
                            } catch (ClassNotFoundException e) {
                                throw new RuntimeException(e);
                            }
                        }
                        dependencyDefinition = createAndPutBeanDefinition(fieldClass, null);//如果这个bean在Config中就不行了,这还有bug
                    }
//                    BeanDefinitionHolder.put(defaultBeanName, beanDefinition);
                    dependencyBeanDefinitionList.add(dependencyDefinition);
                }
                // TODO 处理其它注解,不光有Autowired...
            }
        }
//        beanDefinition.setDependencyBeanDefinitionList(dependencyBeanDefinitionList);
        // 放入BeanDefinitionMap中
        BeanDefinitionHolder.put(classDefaultBeanName, beanDefinition);
        return beanDefinition;
    }

    /**
     * 加载MyBatisBean
     */
    @SuppressWarnings("unchecked")
    public static void loadMyBatisBean() {

        // 加载Repository
        logger.info("开始加载加载Repository BeanDefinition");
        loadAllBeanDefinition("com.pab.cc.aplus.ams.infrastructure.dao.impl");

        // 加载 repository包下的bean
        loadAllBeanDefinition("com.pab.cc.aplus.ams.repository.impl");

        // 加载SqlSessionFactory
        logger.info("开始加载SqlSessionFactory");
        BeanDefinition beanDefinition = new BeanDefinition();
        beanDefinition.setBeanName("sqlSessionFactory");
        beanDefinition.setBeanClass(SqlSessionFactory.class);
        BeanDefinitionHolder.put("sqlSessionFactory", beanDefinition);

        // 实例化SqlSessionFactory
        logger.info("实例化SqlSessionFactory");
        BeanHolder.put("sqlSessionFactory", MyBatisHelper.getSqlSessionFactory());
        BeanHolder.put(SqlSessionFactory.class, MyBatisHelper.getSqlSessionFactory());
    }
}
 

package com.pab.cc.aplus.ams.service.common.h2.ioc;


import com.pab.cc.aplus.ams.common.util.DateTimeUtil;
import com.pab.cc.aplus.ams.service.common.h2.mybatis.MyBatisHelper;
import com.pab.cc.aplus.ams.service.common.h2.util.AnnotationUtil;
import com.pab.cc.aplus.ams.service.common.h2.util.BeanNameUtil;
import com.pab.cc.aplus.base.db.dao.core.configuration.DataSourceConfigProperties;
import com.pab.cc.aplus.base.db.dao.core.dao.impl.AbstractBaseDaoImpl;
import com.pab.cc.aplus.base.db.dao.core.dao.impl.AbstractEntityDaoImpl;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.pab.cc.aplus.ams.common.util.DateTimeUtil.DATE_PATTERN_YYYYMMDD_HHMMSS;

/**
 * Bean实例化工具
 *
 * @version 1.0
 * @date 2019/11/9 11:16
 */
public class BeanInstant {

    private static Logger logger = LoggerFactory.getLogger(BeanInstant.class);

    /**
     * 实例化所有的Bean对象
     */
    public static void instantAllBean() {
        logger.info("开始实例化所有的bean,开始时间:" + DateTimeUtil.formatDate(new Date(), DATE_PATTERN_YYYYMMDD_HHMMSS));
        for (Map.Entry<String, BeanDefinition> entry : BeanDefinitionHolder.getBeanDefinitionMap().entrySet()) {
            instantBean(entry.getValue());
            logger.info("实例化bean:{}完成", entry.getValue().getBeanName());
        }
        logger.info("实例化所有的bean结束,结束时间:" + DateTimeUtil.formatDate(new Date(), DATE_PATTERN_YYYYMMDD_HHMMSS));
    }

    /**
     * 实例化bean对象
     *
     * @param beanDefinition bean定义
     * @return Object
     */
    private static Object instantBean(BeanDefinition beanDefinition) {
        logger.info("开始实例化 {}", beanDefinition.getBeanName());
        Object bean = BeanHolder.get(beanDefinition.getBeanName());

        // TODO 临时处理
        if (beanDefinition.getBeanName().equals("sqlSessionFactory")) {
            return bean;
        }

        if (bean != null) {
//            return bean;
        } else {
            // 实例化普通bean 如用@Component,@Service注解的
            Class clazz = beanDefinition.getBeanClass();
            if (!beanDefinition.isConfigurationFlag()) {
                try {
                    bean = clazz.newInstance();
                } catch (InstantiationException | IllegalAccessException e) {
                    throw new RuntimeException("实例化bean:" + clazz.getSimpleName() + "失败", e);
                }
                // 创建好的bean放入容器
                BeanHolder.put(clazz, bean);
                BeanHolder.put(beanDefinition.getBeanName(), bean);
                fieldInject(bean);
                // 注入依赖属性
//                Field[] fields = clazz.getDeclaredFields();
//                if (fields != null && fields.length > 0) {
//                    for (Field field : fields) {
//                        Annotation[] annotations = field.getAnnotations();
//                        if (AnnotationUtil.containAnnotation(annotations, Autowired.class)) {
//                            Class fieldClass = field.getType();
//                            String defaultBeanName = BeanNameUtil.getDefaultBeanNameByClass(fieldClass);
//                            if (AnnotationUtil.containAnnotation(annotations, Qualifier.class)) {
//                                // 取Qualifier指定的bean
//                                Qualifier qualifier = (Qualifier) AnnotationUtil.getAnnotationByAnnotationClass(annotations, Qualifier.class);
//                                String value = qualifier.value();
//                                if (StringUtils.isBlank(value)) {
//                                    throw new RuntimeException(clazz.getSimpleName() + "的Qualifier指定的value为空");
//                                }
//                                defaultBeanName = value;
//                            }
//                            BeanDefinition dependencyDefinition = BeanDefinitionHolder.get(defaultBeanName);
//                            if (dependencyDefinition == null) {
//                                throw new RuntimeException("找不到"+ clazz.getSimpleName() + "中的【" + field.getName() +"】对应的bean【" + defaultBeanName + "】");
//                            }
//                            // 注入Bean
//                            logger.info("【{}】 注入依赖: 【{}】", beanDefinition.getBeanName(), dependencyDefinition.getBeanName());
//                            Object dependencyBean = instantBean(dependencyDefinition);
//                            field.setAccessible(true);
//                            try {
//                                field.set(bean, dependencyBean);
//                            } catch (IllegalAccessException e) {
//                                throw new RuntimeException(e);
//                            }
//                        }
//                        // TODO 处理其它注解,不光有Autowired...
//                    }
//                }
            } else {
                // 实例化javaConfigBean
                // 参数bean注入,只支持@Qualifier
                Method method = beanDefinition.getJavaConfigBeanMethod();
                logger.info("开始实例化javaConfigBean:{}", beanDefinition.getBeanName() + ",  methodName:" + method.getName());
                Parameter[] parameters = method.getParameters();
                Object[] params = new Object[parameters.length];
                int i = 0;
                if (parameters.length > 0) {
                    for (Parameter parameter : parameters) {
                        Annotation[] parameterAnnotations = parameter.getAnnotations();
                        if (parameterAnnotations.length != 1) {
                            throw new RuntimeException(method.getName() + "javaConfig方法参数只支持一个Qualifier注解");
                        }
                        if (parameterAnnotations[0].annotationType().equals(Qualifier.class)) {
                            Qualifier qualifier = (Qualifier) parameterAnnotations[0];
                            Object parameterBean = BeanHolder.get(qualifier.value());
                            if (parameterBean == null) {
                                BeanDefinition paramBeanDefinition = BeanDefinitionHolder.getBeanDefinitionMap().get(qualifier.value());
                                if (paramBeanDefinition == null) {
                                    throw new RuntimeException("类:" + clazz.getSimpleName() + "中的:" + method.getName() + "方法参数" + qualifier.value() + "在容器中不存在");
                                } else {
                                    // 递归实例化方法参数bean
                                    logger.info("{}递归实例化方法参数bean: {}", beanDefinition.getBeanName(), paramBeanDefinition.getBeanName());
                                    parameterBean = instantBean(paramBeanDefinition);
                                }
                            }
                            params[i++] = parameterBean;
                        } else {
                            throw new RuntimeException(method.getName() + " 方法参数必须加@Qualifier注解或为空");
                        }
                    }
                }
                Object javaConfigBean;
                // 获取configuration配置类
                String defConfBeanName = beanDefinition.getConfigurationBeanDefinitionName();
                Object configurationBean = BeanHolder.get(defConfBeanName);
                if (configurationBean == null) {
                    BeanDefinition confBeanDefinition = BeanDefinitionHolder.getBeanDefinitionMap().get(defConfBeanName);
                    configurationBean = instantBean(confBeanDefinition);
                }
                try {
                    logger.info("实例化javaConfigBean : {}", beanDefinition.getBeanName());
                    javaConfigBean = method.invoke(configurationBean, params);
                } catch (Exception e) {
                    throw new RuntimeException("方法" + method.getName() + "执行失败", e);
                }
                // 创建好的bean放入容器
                BeanHolder.put(javaConfigBean.getClass(), javaConfigBean);
                BeanHolder.put(beanDefinition.getBeanName(), javaConfigBean);

                // 注入后绑定的Bean
                Class methodReturnClass = javaConfigBean.getClass();
                BeanDefinition methodReturnBeanDefinition = BeanDefinitionHolder.getBeanDefinitionMap().get(method.getName());
                if (methodReturnBeanDefinition == null) {
                    throw new RuntimeException("类:" + methodReturnClass.getSimpleName() + "定义不存在: " + BeanNameUtil.getDefaultBeanNameByClass(methodReturnClass));
                }
                fieldInject(javaConfigBean);
                bean = javaConfigBean;
            }
            logger.info("实例化:{} 结束", beanDefinition.getBeanName());
//            return bean;
        }
        //TODO 还没有实现setter注入,所以把实现 了AbstractBaseDaoImpl接口的dao 注入sqlSession
        if (AbstractBaseDaoImpl.class.isAssignableFrom(bean.getClass())) {
            logger.info(beanDefinition.getBeanName() + "注入sqlSession");
            ((AbstractBaseDaoImpl) bean).setSqlSessionFactory(MyBatisHelper.getSqlSessionFactory());

            if (AbstractEntityDaoImpl.class.isAssignableFrom(bean.getClass())) {
                Class clazz = bean.getClass();
                // TODO 此处直接获取父类,有点low
                Field[] fields = clazz.getSuperclass().getDeclaredFields();
                if (fields != null && fields.length > 0) {
                    for (Field field : fields) {
                        if (field.getName().equals("dataSourceConfigProperties")) {
                            field.setAccessible(true);
                            try {
                                DataSourceConfigProperties dataSourceConfigProperties = new DataSourceConfigProperties();
                                dataSourceConfigProperties.setDialect(null);
                                dataSourceConfigProperties.setInterceptors(null);
                                dataSourceConfigProperties.setMybatisMapper(null);
                                dataSourceConfigProperties.setTypeHandlers(null);
                                field.set(bean, new DataSourceConfigProperties());
                            } catch (IllegalAccessException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    }
                }
            }

        }

        // 调用afterPropertiesSet方法
        logger.info("调用afterPropertiesSet方法");
        if (InitializingBean.class.isAssignableFrom(bean.getClass())) {
            Method afterPropertiesSetMethod;
            try {
                afterPropertiesSetMethod = bean.getClass().getMethod("afterPropertiesSet");
            } catch (NoSuchMethodException e) {
                throw new RuntimeException("类" + beanDefinition.getBeanName() + "实现了InitializingBean接口但是没有afterPropertiesSet方法");
            }
            try {
                afterPropertiesSetMethod.invoke(bean);
            } catch (Exception e) {
                throw new RuntimeException("afterPropertiesSet方法执行失败", e);
            }
        }

        // TODO 执行PostConstruct方法

        return bean;
    }


    public static void fieldInject(Object bean) {
        Class clazz = bean.getClass();
        Field[] fields = clazz.getDeclaredFields();
        if (fields != null && fields.length > 0) {
            for (Field field : fields) {
                Annotation[] annotations = field.getAnnotations();
                if (AnnotationUtil.containAnnotation(annotations, Autowired.class)) {
                    Class fieldClass = field.getType();
                    String defaultBeanName;
                    if (AnnotationUtil.containAnnotation(annotations, Qualifier.class)) {
                        // 取Qualifier指定的bean
                        Qualifier qualifier = (Qualifier) AnnotationUtil.getAnnotationByAnnotationClass(annotations, Qualifier.class);
                        String value = qualifier.value();
                        if (StringUtils.isBlank(value)) {
                            throw new RuntimeException(clazz.getSimpleName() + "的Qualifier指定的value为空");
                        }
                        defaultBeanName = value;
                    } else {
                        defaultBeanName = BeanNameUtil.getDefaultBeanNameByClass(fieldClass);
                    }
                    BeanDefinition dependencyDefinition = BeanDefinitionHolder.get(defaultBeanName);
                    if (dependencyDefinition == null) {
                        // 如果依赖是接口的话查询实现类
                        if (fieldClass.isInterface()) {
                            List<Class> classList = ClassHolder.getImplClass(fieldClass);
                            if (classList == null || classList.size() == 0) {
                                throw new RuntimeException("找不到" + fieldClass.getSimpleName() + "的实现类");
                            }
                            else if (classList.size() > 1) {
                                throw new RuntimeException("实现类" + fieldClass.getSimpleName() + "的个数不唯一");
                            }
                            dependencyDefinition = BeanDefinitionHolder.getSingleBeanDefinitionByClass(classList.get(0));
                        } else {
                            throw new RuntimeException("找不到"+ clazz.getSimpleName() + "中的【" + field.getName() +"】对应的bean【" + defaultBeanName + "】");
                        }
                    }
                    // 注入Bean
                    logger.info("【{}】 注入依赖: 【{}】", clazz.getSimpleName(), dependencyDefinition.getBeanName());
                    Object dependencyBean = instantBean(dependencyDefinition);
                    field.setAccessible(true);
                    try {
                        field.set(bean, dependencyBean);
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                }
                // TODO 处理其它注解,不光有Autowired...
            }
        }
    }

}
 

package com.pab.cc.aplus.ams.service.common.h2.ioc;

import java.lang.annotation.Annotation;

public class Util {

    /**
     * 类上包含指定的Annotation
     *
     * @param clazz
     * @param annotation
     * @return
     */
    public static boolean classContainAnnotation(Class clazz, Annotation annotation) {
        if (annotation == null) {
            return false;
        }
        Annotation[] annotations = clazz.getAnnotations();
        if (annotations != null && annotations.length > 0) {
            for (Annotation a : annotations) {
                if (a.annotationType().equals(annotation.annotationType())) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 判断一个类是否为另一个类的子类
     *
     * @param childClass  子类
     * @param parentClass 父类
     * @return boolean
     */
    public static boolean isSubClass(Class childClass, Class parentClass) {
        try {
            childClass.asSubclass(parentClass);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}
 

package com.pab.cc.aplus.ams.service.common.h2.ioc;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class PackageUtil {

//    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException {
//
//        List<String> names = getClassName("com.pab.cc.aplus.ams.statement");
        for (String s : names) {
            System.out.println(s);
        }
//
//        Class clazz = Class.forName("com.pab.cc.aplus.ams.service.common.h2.util.StatementUtil");
//        Object object = clazz.newInstance();
//
//        System.out.println(((StatementUtil)object).convertNullToZero(BigDecimal.ZERO));
//    }


    /**
     * 获取某包下(包括该包的所有子包)所有类
     *
     * @param packageName 包名
     * @return 类的完整名称
     * @throws
     */
    public static List<String> getClassName(String packageName) throws IOException {
        return getClassName(packageName, true);
    }

    /**
     * 获取某包下所有类
     *
     * @param packageName  包名
     * @param childPackage 是否遍历子包
     * @return 类的完整名称
     * @throws
     */
    public static List<String> getClassName(String packageName, boolean childPackage) throws IOException {
        List<String> fileNames = new ArrayList<>();
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        String packagePath = packageName.replace(".", "/");
        Enumeration<URL> urls = loader.getResources(packagePath);
        while (urls.hasMoreElements()) {
            URL url = urls.nextElement();
            if (url == null)
                continue;
            String type = url.getProtocol();
            if (type.equals("file")) {
                fileNames.addAll(getClassNameByFile(url.getPath(), childPackage));
            } else if (type.equals("jar")) {
                fileNames.addAll(getClassNameByJar(url.getPath(), childPackage));
            }
        }
        fileNames.addAll(getClassNameByJars(((URLClassLoader) loader).getURLs(), packagePath, childPackage));
        return fileNames;
    }

    /**
     * 从项目文件获取某包下所有类
     *
     * @param filePath     文件路径
     *                     类名集合
     * @param childPackage 是否遍历子包
     * @return 类的完整名称
     * @throws UnsupportedEncodingException
     */
    private static List<String> getClassNameByFile(String filePath, boolean childPackage) throws UnsupportedEncodingException {
        List<String> myClassName = new ArrayList<>();
//        filePath = UrlDecode.getURLDecode(filePath);
        File file = new File(filePath);
        File[] childFiles = file.listFiles();
        if (childFiles == null)
            return myClassName;
        for (File childFile : childFiles) {
            if (childFile.isDirectory()) {
                if (childPackage) {
                    myClassName.addAll(getClassNameByFile(childFile.getPath(), childPackage));
                }
            } else {
                String childFilePath = childFile.getPath();
//                childFilePath = FileUtil.clearPath(childFilePath);
                if (childFilePath.endsWith(".class")) {
                    //TODO 这块用com来截取包名有点Low,需要优化
                    childFilePath = childFilePath.substring(childFilePath.indexOf("com" + File.separatorChar), childFilePath.lastIndexOf("."));
                    childFilePath = childFilePath.replace(File.separatorChar + "", ".");
                    myClassName.add(childFilePath);
                }
            }
        }
        return myClassName;
    }

    /**
     * 从jar获取某包下所有类
     *
     * @param jarPath      jar文件路径
     * @param childPackage 是否遍历子包
     * @return 类的完整名称
     * @throws UnsupportedEncodingException
     */
    private static List<String> getClassNameByJar(String jarPath, boolean childPackage) throws UnsupportedEncodingException {
        List<String> myClassName = new ArrayList<String>();
        String[] jarInfo = jarPath.split("!");
        String jarFilePath = jarInfo[0].substring(jarInfo[0].indexOf("/"));
//        jarFilePath = UrlDecode.getURLDecode(jarFilePath);
        String packagePath = jarInfo[1].substring(1);
        try {
            JarFile jarFile = new JarFile(jarFilePath);
            Enumeration<JarEntry> entrys = jarFile.entries();
            while (entrys.hasMoreElements()) {
                JarEntry jarEntry = entrys.nextElement();
                String entryName = jarEntry.getName();
                if (entryName.endsWith(".class")) {
                    if (childPackage) {
                        if (entryName.startsWith(packagePath)) {
                            entryName = entryName.replace("/", ".").substring(0, entryName.lastIndexOf("."));
                            myClassName.add(entryName);
                        }
                    } else {
                        int index = entryName.lastIndexOf("/");
                        String myPackagePath;
                        if (index != -1) {
                            myPackagePath = entryName.substring(0, index);
                        } else {
                            myPackagePath = entryName;
                        }
                        if (myPackagePath.equals(packagePath)) {
                            entryName = entryName.replace("/", ".").substring(0, entryName.lastIndexOf("."));
                            myClassName.add(entryName);
                        }
                    }
                }
            }
        } catch (Exception e) {
            //SystemLog.Log(LogType.systemInfo, e.getMessage(), e);
        }
        return myClassName;
    }

    /**
     * 从所有jar中搜索该包,并获取该包下所有类
     *
     * @param urls         URL集合
     * @param packagePath  包路径
     * @param childPackage 是否遍历子包
     * @return 类的完整名称
     * @throws UnsupportedEncodingException
     */
    private static List<String> getClassNameByJars(URL[] urls, String packagePath, boolean childPackage) throws UnsupportedEncodingException {
        List<String> myClassName = new ArrayList<String>();
        if (urls != null) {
            for (int i = 0; i < urls.length; i++) {
                URL url = urls[i];
                String urlPath = url.getPath();
                // 不必搜索classes文件夹
                if (urlPath.endsWith("classes/")) {
                    continue;
                }
                String jarPath = urlPath + "!/" + packagePath;
                myClassName.addAll(getClassNameByJar(jarPath, childPackage));
            }
        }
        return myClassName;
    }
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值