spring boot 1.5.3 源代码片段 - MetadataReader读取*.class文件

37 篇文章 0 订阅
18 篇文章 0 订阅

解析class文件,读取类元信息

package cn.java.demo.beantag.internal.metareader;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class FooOneService extends FooOneSuper0 implements FooOneInterface, FooTwoInterface {

    public void method0() {

    }

    public void method1() {
        /**
         * 内部类
         */
        @Data
        class FooOneMemberClazz2 {
            private Integer id;
        }
    }

    /**
     * 成员类
     */
    @Data
    public class FooOneMemberClazz0 {
        private Integer id;

    }

    /**
     * 内部类
     */
    @Data
    public static class FooOneMemberClazz1 {
        private Integer id;

    }
}

class FooOneSuper0 {

}

interface FooOneInterface {

}

interface FooTwoInterface {

}
package cn.java.demo.beantag.internal.metareader;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.util.Set;

/**
 * @date 2020-12-11 15:45
 */
@Slf4j
public class ClassPathScanningCandidateComponentProviderTest {
    public static void main(String[] args) {
        new ClassPathScanningCandidateComponentProviderTest().findCandidateComponents(null);
    }

    /**
     * org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#findCandidateComponents()
     */
    public Set<BeanDefinition> findCandidateComponents(String basePackage) {
        ResourceLoader resourceLoader = null;
        ResourcePatternResolver resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
        MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);

        String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(FooOneService.class.getName()) + ClassUtils.CLASS_FILE_SUFFIX;
        log.info("packageSearchPath = {}", packageSearchPath);
        try {
            Resource[] resources = resourcePatternResolver.getResources(packageSearchPath); // 查找所有资源
            log.info("resources length = {}", resources.length);
            for (Resource resource : resources) {
                if (resource.isReadable()) {
                    MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);

                    // getAnnotationMetadata 获取注解元信息
                    {
                        AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
                        // ((不是内部类or是static的内部类) && ((不是接口&不是抽象) || (是抽象的&有方法配置@Lookup注解)))
                        boolean isCandidateComponent = (metadata.isIndependent() && (metadata.isConcrete() ||
                                (metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
                        log.info("isCandidateComponent = {}", isCandidateComponent);
                    }

                    // getClassMetadata 获取类元信息
                    {
                        ClassMetadata classMetadata = metadataReader.getClassMetadata();

                        String className = classMetadata.getClassName(); // 类名
                        log.info("className = {}", className);

                        String superClassName = classMetadata.getSuperClassName(); // 父类
                        log.info("superClassName = {}", superClassName);

                        String[] interfaceNames = classMetadata.getInterfaceNames(); // 接口
                        if(!ObjectUtils.isEmpty(interfaceNames)){
                            for (String interfaceName : interfaceNames) {
                                log.info("interfaceName = {}", interfaceName);
                            }
                        }

                        String[] memberClassNames = classMetadata.getMemberClassNames(); // 成员类
                        for (String memberClassName : memberClassNames) {
                            log.info("memberClassName = {}", memberClassName);
                            MetadataReader memberClassMetadataReader = metadataReaderFactory.getMetadataReader(memberClassName);
                            ClassMetadata memberClassMetadata =  memberClassMetadataReader.getClassMetadata();
                            String memberClassEnclosingClassName = memberClassMetadata.getEnclosingClassName();
                            log.info("\tenclosingClassName = {}", memberClassEnclosingClassName);
                        }

                        // the underlying class is an inner/nested class or a local class within a method // 外部类名
                        String enclosingClassName = classMetadata.getEnclosingClassName();
                        log.info("enclosingClassName = {}", enclosingClassName);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    protected String resolveBasePackage(String basePackage) {
        return ClassUtils.convertClassNameToResourcePath(basePackage); // 转换路径
    }

}

输出

2020-12-11 16:28:11,071 INFO [cn.java.demo.beantag.internal.metareader.ClassPathScanningCandidateComponentProviderTest] - packageSearchPath = classpath*:cn/java/demo/beantag/internal/metareader/FooOneService.class
2020-12-11 16:28:11,078 DEBUG [org.springframework.core.io.support.PathMatchingResourcePatternResolver] - Resolved classpath location [cn/java/demo/beantag/internal/metareader/FooOneService.class] to resources [URL [file:/Users/qudian/Documents/java_workspace/java_openstack_debug/springFrameworkDebug/web-demo/WebRoot/WEB-INF/classes/cn/java/demo/beantag/internal/metareader/FooOneService.class]]
2020-12-11 16:28:11,078 INFO [cn.java.demo.beantag.internal.metareader.ClassPathScanningCandidateComponentProviderTest] - resources length = 1
2020-12-11 16:28:11,091 INFO [cn.java.demo.beantag.internal.metareader.ClassPathScanningCandidateComponentProviderTest] - isCandidateComponent = true
2020-12-11 16:28:11,091 INFO [cn.java.demo.beantag.internal.metareader.ClassPathScanningCandidateComponentProviderTest] - className = cn.java.demo.beantag.internal.metareader.FooOneService
2020-12-11 16:28:11,091 INFO [cn.java.demo.beantag.internal.metareader.ClassPathScanningCandidateComponentProviderTest] - superClassName = cn.java.demo.beantag.internal.metareader.FooOneSuper0
2020-12-11 16:28:11,092 INFO [cn.java.demo.beantag.internal.metareader.ClassPathScanningCandidateComponentProviderTest] - interfaceName = cn.java.demo.beantag.internal.metareader.FooOneInterface
2020-12-11 16:28:11,092 INFO [cn.java.demo.beantag.internal.metareader.ClassPathScanningCandidateComponentProviderTest] - interfaceName = cn.java.demo.beantag.internal.metareader.FooTwoInterface
2020-12-11 16:28:11,092 INFO [cn.java.demo.beantag.internal.metareader.ClassPathScanningCandidateComponentProviderTest] - memberClassName = cn.java.demo.beantag.internal.metareader.FooOneService$FooOneMemberClazz1
2020-12-11 16:28:11,094 INFO [cn.java.demo.beantag.internal.metareader.ClassPathScanningCandidateComponentProviderTest] - 	enclosingClassName = cn.java.demo.beantag.internal.metareader.FooOneService
2020-12-11 16:28:11,094 INFO [cn.java.demo.beantag.internal.metareader.ClassPathScanningCandidateComponentProviderTest] - memberClassName = cn.java.demo.beantag.internal.metareader.FooOneService$FooOneMemberClazz0
2020-12-11 16:28:11,094 INFO [cn.java.demo.beantag.internal.metareader.ClassPathScanningCandidateComponentProviderTest] - 	enclosingClassName = cn.java.demo.beantag.internal.metareader.FooOneService
2020-12-11 16:28:11,094 INFO [cn.java.demo.beantag.internal.metareader.ClassPathScanningCandidateComponentProviderTest] - enclosingClassName = null

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值