@ConditionalOnBean在方法上失效

@ConditionalOnBean在方法上失效

在自定义一个日志切面,作为一个工具提供给其它的模块依赖时,发现@ConditionalBean写在方法上失效了,却写在类上注入成功的问题。于是通过源码打断点,发现@ConditionalOnBean在方法上时,对自定义的bean无效且会导致bean注入失败。

//@ConditionalOnBean(annotation = {EnableAutoPintLog.class}) 此处生效
public class LogAutoConfiguration {

    @Bean
    @ConditionalOnBean(annotation = {EnableAutoPintLog.class}) //此处会失败
    public LogAspect logAspect() {
        return new LogAspect();
    }
}

@ConditionalOnBean(annotation = {EnableAutoPintLog.class})的意思是项目中至少有一个被spring管理的bean上有@EnableAutoPintLog注解修饰,当前的bean才会被注入IOC容器,一般我们把@EnableXXXX标注在启动类上。

首先全局搜索ConfigurationClassPostProcessor类(该类是自动配置的核心类),找到下面的postProcessBeanDefinitionRegistry入口,在下图所示。
 

断点进行,在this.reader.loadBeanDefinitions(configClasses)打上断点

 断点再到如下图所示

在断点处加上判断表达式configClass.getMetadata().getClassName().equals("com.zh.common.util.config.LogAutoConfiguration"),让停在指定的bean,并进入该方法。由于bean写在方法上,所以loadBeanDefinitionsForBeanMethod(beanMethod)处打上断点

进去,到this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)

shouldSkip方法中,判断该bean是否带有注解@ConditionalOnBean,当方法带有才会进入下面的condition.match逻辑。

	public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {
		if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
			return false;
		}

        ... 省略代码
			if ((requiredPhase == null || requiredPhase == phase) && !condition.matches(this.context, metadata)) {
				return true;
			}
		}

		return false;
	}

进入matchs方法,再进入getMatchOutcome方法

	@Override
	public final boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		String classOrMethodName = getClassOrMethodName(metadata);
		try {
		// 此处进入
			ConditionOutcome outcome = getMatchOutcome(context, metadata);
	@Override
	public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
		ConditionMessage matchMessage = ConditionMessage.empty();
		MergedAnnotations annotations = metadata.getAnnotations();
		if (annotations.isPresent(ConditionalOnBean.class)) {
		// 初始化,重要
			Spec<ConditionalOnBean> spec = new Spec<>(context, metadata, annotations, ConditionalOnBean.class);
			// 自定义bean时候,会找不到对应的type而导致match失败
			MatchResult matchResult = getMatchingBeans(context, spec);
			if (!matchResult.isAllMatched()) {
				String reason = createOnBeanNoMatchReason(matchResult);
				return ConditionOutcome.noMatch(spec.message().because(reason));
			}
			matchMessage = spec.message(matchMessage).found("bean", "beans").items(Style.QUOTE,
					matchResult.getNamesOfAllMatches());
		}

!!!此处重要,进入new spec构造方法里面,在deducedBeanType处推断bean的类型并赋值给type。以至后面的由于自定义bean找不到type,而判断类型出错

先判断是不是通过@bean在方法上注入的bean,是的话推断它的类型type并返回赋值,此时会导致后面因为这里不为空且找不到指定的type而match不成功。
当在类上添加注解@ConditionalOnBean上时候,由于不满足条件,返回空集。而不会导致type找不到问题。

		private Set<String> deducedBeanType(ConditionContext context, AnnotatedTypeMetadata metadata) {
			if (metadata instanceof MethodMetadata && metadata.isAnnotated(Bean.class.getName())) {
				return deducedBeanTypeForBeanMethod(context, (MethodMetadata) metadata);
			}
			return Collections.emptySet();
		}

由于是自定义的bean,最终匹配不成功,忽略不处理,注入失败。

(验证走的是自己本地的代码,和原博主的的文件路径不一致,请知悉)

源码粗略流程就是查看方法上有多少个Condition相关注解,找到对应注解的实现,即Condition的子类,然后遍历这些子类matches方法。

思考

我们将@ConditionalOnBean(annotation = {EnableAutoPintLog.class})改成@ConditionalOnBean(value = {A.class})发现就没类似的问题了(A是一个注入IOC的Bean),可跟踪源码看下,具体原因跟上面的差不多,最后type走的是这段代码,没有进入最后判断不匹配的集合中。

总结

条件注解的过滤属于自配配置类中筛选的一部分,具体源码可先参考相关文章的内容,了解下springboot根据条件注解筛选自动配置类(根据条件注解决定配置类是否注入IOC容器,类似开关的作用)的大体流程。本文牵扯的内容主要在【Spring Boot 源码学习】OnBeanCondition 详解。另外实际开发中比较常见的@ConditionalOnProperty注解则是在OnPropertyCondition实现的。

关于顶层接口Condition的方法boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);其中的AnnotatedTypeMetadata源码,可以参考这个:ClassMetadata/AnnotatedTypeMetadata源码解读,该文最后有测试案例,可以跑跑,有利于理解本文中与此相关的一些源码(比如MethodMetadata)。贴一下单侧代码:


#ClassMetadata和 AnnotatedTypeMetadata 可以理解为对 Class元数据 和 Annotation元数据 的抽象
public class TestMain {

    @Service
    @Configuration
    public class Config {

        @RequestMapping
        public void a() {

        }

    }

    @Test
    public void testReflect() throws IOException {

        String component = "org.springframework.stereotype.Component";
        String configuration = "org.springframework.context.annotation.Configuration";

        // 基于反射获取
        /*StandardAnnotationMetadata metadata
                = (StandardAnnotationMetadata) AnnotationMetadata.introspect(Config.class);*/

        // 基于 MetadataReader 获取
        MetadataReaderFactory factory = new CachingMetadataReaderFactory();
        MetadataReader metadataReader = factory.getMetadataReader("com.example.demo.metadata.TestMain.Config");
        AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();

        // -------------- AnnotatedTypeMetadata --------
        boolean annotated = metadata.isAnnotated(component);
        System.out.println("是否被指定 直接注解或元注解 标注:" + annotated);

        Map<String, Object> annotationAttributes
                = metadata.getAnnotationAttributes(component, true);
        System.out.println("指定 直接注解或元注解 的所有属性:");
        annotationAttributes.forEach((k, v) -> System.out.println(k +":"+ v));

        // ------------- AnnotationMetadata
        Set<String> annotationTypes = metadata.getAnnotationTypes();
        System.out.println("目标类上标注的 直接注解 有:");
        annotationTypes.forEach(System.out::println);

        Set<String> metaAnnotationTypes
                = metadata.getMetaAnnotationTypes(configuration);
        System.out.println("目标指定注解上的 元注解 有:");
        metaAnnotationTypes.forEach(System.out::println);

        boolean b = metadata.hasAnnotation(configuration);
        System.out.println("目标是否被指定 直接注解 标注:" + b);

        boolean b1 = metadata.hasMetaAnnotation(component);
        System.out.println("目标是否被指定 元注解 标注:" + b1);

        Set<MethodMetadata> annotatedMethods
                = metadata.getAnnotatedMethods("org.springframework.web.bind.annotation.Mapping");
        if (annotatedMethods != null && annotatedMethods.size() > 0) {
            System.out.print("目标类含有被指定 直接注解或元注解 标注的方法,其名称有:");

            for (MethodMetadata m : annotatedMethods) {
                System.out.println(m.getMethodName());
            }
        }
    }
}

H:\software\Java\jdk-1.8\bin\java -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:H:\software\IntelliJ IDEA 2018.1\lib\idea_rt.jar=62832:H:\software\IntelliJ IDEA 2018.1\bin" -Dfile.encoding=UTF-8 -classpath "H:\software\IntelliJ IDEA 2018.1\lib\idea_rt.jar;H:\software\IntelliJ IDEA 2018.1\plugins\junit\lib\junit-rt.jar;H:\software\IntelliJ IDEA 2018.1\plugins\junit\lib\junit5-rt.jar;H:\software\Java\jdk-1.8\jre\lib\charsets.jar;H:\software\Java\jdk-1.8\jre\lib\deploy.jar;H:\software\Java\jdk-1.8\jre\lib\ext\access-bridge-64.jar;H:\software\Java\jdk-1.8\jre\lib\ext\cldrdata.jar;H:\software\Java\jdk-1.8\jre\lib\ext\dnsns.jar;H:\software\Java\jdk-1.8\jre\lib\ext\jaccess.jar;H:\software\Java\jdk-1.8\jre\lib\ext\jfxrt.jar;H:\software\Java\jdk-1.8\jre\lib\ext\localedata.jar;H:\software\Java\jdk-1.8\jre\lib\ext\nashorn.jar;H:\software\Java\jdk-1.8\jre\lib\ext\sunec.jar;H:\software\Java\jdk-1.8\jre\lib\ext\sunjce_provider.jar;H:\software\Java\jdk-1.8\jre\lib\ext\sunmscapi.jar;H:\software\Java\jdk-1.8\jre\lib\ext\sunpkcs11.jar;H:\software\Java\jdk-1.8\jre\lib\ext\zipfs.jar;H:\software\Java\jdk-1.8\jre\lib\javaws.jar;H:\software\Java\jdk-1.8\jre\lib\jce.jar;H:\software\Java\jdk-1.8\jre\lib\jfr.jar;H:\software\Java\jdk-1.8\jre\lib\jfxswt.jar;H:\software\Java\jdk-1.8\jre\lib\jsse.jar;H:\software\Java\jdk-1.8\jre\lib\management-agent.jar;H:\software\Java\jdk-1.8\jre\lib\plugin.jar;H:\software\Java\jdk-1.8\jre\lib\resources.jar;H:\software\Java\jdk-1.8\jre\lib\rt.jar;H:\projects\spring_boot_study\target\test-classes;H:\projects\spring_boot_study\target\classes;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\boot\spring-boot-starter-web\2.4.4\spring-boot-starter-web-2.4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\boot\spring-boot-starter\2.4.4\spring-boot-starter-2.4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\boot\spring-boot\2.4.4\spring-boot-2.4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\boot\spring-boot-starter-logging\2.4.4\spring-boot-starter-logging-2.4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;H:\software\apache-maven-3.3.9-bin\localRepository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\logging\log4j\log4j-to-slf4j\2.13.3\log4j-to-slf4j-2.13.3.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\logging\log4j\log4j-api\2.13.3\log4j-api-2.13.3.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;H:\software\apache-maven-3.3.9-bin\localRepository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\yaml\snakeyaml\1.27\snakeyaml-1.27.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\boot\spring-boot-starter-json\2.4.4\spring-boot-starter-json-2.4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\fasterxml\jackson\core\jackson-databind\2.11.4\jackson-databind-2.11.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\fasterxml\jackson\core\jackson-annotations\2.11.4\jackson-annotations-2.11.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\fasterxml\jackson\core\jackson-core\2.11.4\jackson-core-2.11.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.4\jackson-datatype-jdk8-2.11.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.4\jackson-datatype-jsr310-2.11.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.4\jackson-module-parameter-names-2.11.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\boot\spring-boot-starter-tomcat\2.4.4\spring-boot-starter-tomcat-2.4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\tomcat\embed\tomcat-embed-core\9.0.44\tomcat-embed-core-9.0.44.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.44\tomcat-embed-websocket-9.0.44.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\spring-web\5.3.5\spring-web-5.3.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\spring-beans\5.3.5\spring-beans-5.3.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\spring-webmvc\5.3.5\spring-webmvc-5.3.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\spring-aop\5.3.5\spring-aop-5.3.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\spring-context\5.3.5\spring-context-5.3.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\spring-expression\5.3.5\spring-expression-5.3.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\boot\spring-boot-starter-test\2.4.4\spring-boot-starter-test-2.4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\boot\spring-boot-test\2.4.4\spring-boot-test-2.4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\boot\spring-boot-test-autoconfigure\2.4.4\spring-boot-test-autoconfigure-2.4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\jayway\jsonpath\json-path\2.4.0\json-path-2.4.0.jar;H:\software\apache-maven-3.3.9-bin\localRepository\net\minidev\json-smart\2.3\json-smart-2.3.jar;H:\software\apache-maven-3.3.9-bin\localRepository\net\minidev\accessors-smart\1.2\accessors-smart-1.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\ow2\asm\asm\5.0.4\asm-5.0.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\jakarta\xml\bind\jakarta.xml.bind-api\2.3.3\jakarta.xml.bind-api-2.3.3.jar;H:\software\apache-maven-3.3.9-bin\localRepository\jakarta\activation\jakarta.activation-api\1.2.2\jakarta.activation-api-1.2.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\assertj\assertj-core\3.18.1\assertj-core-3.18.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\hamcrest\hamcrest\2.2\hamcrest-2.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\junit\jupiter\junit-jupiter\5.7.1\junit-jupiter-5.7.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\junit\jupiter\junit-jupiter-api\5.7.1\junit-jupiter-api-5.7.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apiguardian\apiguardian-api\1.1.0\apiguardian-api-1.1.0.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\opentest4j\opentest4j\1.2.0\opentest4j-1.2.0.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\junit\platform\junit-platform-commons\1.7.1\junit-platform-commons-1.7.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\junit\jupiter\junit-jupiter-params\5.7.1\junit-jupiter-params-5.7.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\junit\jupiter\junit-jupiter-engine\5.7.1\junit-jupiter-engine-5.7.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\junit\platform\junit-platform-engine\1.7.1\junit-platform-engine-1.7.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\mockito\mockito-core\3.6.28\mockito-core-3.6.28.jar;H:\software\apache-maven-3.3.9-bin\localRepository\net\bytebuddy\byte-buddy\1.10.22\byte-buddy-1.10.22.jar;H:\software\apache-maven-3.3.9-bin\localRepository\net\bytebuddy\byte-buddy-agent\1.10.22\byte-buddy-agent-1.10.22.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\objenesis\objenesis\3.1\objenesis-3.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\mockito\mockito-junit-jupiter\3.6.28\mockito-junit-jupiter-3.6.28.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\skyscreamer\jsonassert\1.5.0\jsonassert-1.5.0.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\vaadin\external\google\android-json\0.0.20131108.vaadin1\android-json-0.0.20131108.vaadin1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\spring-core\5.3.5\spring-core-5.3.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\spring-jcl\5.3.5\spring-jcl-5.3.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\spring-test\5.3.5\spring-test-5.3.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\xmlunit\xmlunit-core\2.7.0\xmlunit-core-2.7.0.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\boot\spring-boot-starter-validation\2.4.4\spring-boot-starter-validation-2.4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\hibernate\validator\hibernate-validator\6.1.7.Final\hibernate-validator-6.1.7.Final.jar;H:\software\apache-maven-3.3.9-bin\localRepository\jakarta\validation\jakarta.validation-api\2.0.2\jakarta.validation-api-2.0.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\jboss\logging\jboss-logging\3.4.1.Final\jboss-logging-3.4.1.Final.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\fasterxml\classmate\1.5.1\classmate-1.5.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\boot\spring-boot-starter-data-redis\2.4.4\spring-boot-starter-data-redis-2.4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\data\spring-data-redis\2.4.6\spring-data-redis-2.4.6.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\data\spring-data-keyvalue\2.4.6\spring-data-keyvalue-2.4.6.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\data\spring-data-commons\2.4.6\spring-data-commons-2.4.6.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\spring-tx\5.3.5\spring-tx-5.3.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\spring-oxm\5.3.5\spring-oxm-5.3.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\spring-context-support\5.3.5\spring-context-support-5.3.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\io\lettuce\lettuce-core\6.0.3.RELEASE\lettuce-core-6.0.3.RELEASE.jar;H:\software\apache-maven-3.3.9-bin\localRepository\io\netty\netty-common\4.1.60.Final\netty-common-4.1.60.Final.jar;H:\software\apache-maven-3.3.9-bin\localRepository\io\netty\netty-handler\4.1.60.Final\netty-handler-4.1.60.Final.jar;H:\software\apache-maven-3.3.9-bin\localRepository\io\netty\netty-resolver\4.1.60.Final\netty-resolver-4.1.60.Final.jar;H:\software\apache-maven-3.3.9-bin\localRepository\io\netty\netty-buffer\4.1.60.Final\netty-buffer-4.1.60.Final.jar;H:\software\apache-maven-3.3.9-bin\localRepository\io\netty\netty-codec\4.1.60.Final\netty-codec-4.1.60.Final.jar;H:\software\apache-maven-3.3.9-bin\localRepository\io\netty\netty-transport\4.1.60.Final\netty-transport-4.1.60.Final.jar;H:\software\apache-maven-3.3.9-bin\localRepository\io\projectreactor\reactor-core\3.4.4\reactor-core-3.4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\reactivestreams\reactive-streams\1.0.3\reactive-streams-1.0.3.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\commons\commons-pool2\2.9.0\commons-pool2-2.9.0.jar;H:\software\apache-maven-3.3.9-bin\localRepository\cn\hutool\hutool-all\5.8.15\hutool-all-5.8.15.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\projectlombok\lombok\1.16.10\lombok-1.16.10.jar;H:\software\apache-maven-3.3.9-bin\localRepository\junit\junit\4.13.2\junit-4.13.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\hamcrest\hamcrest-core\2.2\hamcrest-core-2.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\jsoup\jsoup\1.10.2\jsoup-1.10.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\net\sourceforge\tess4j\tess4j\5.4.0\tess4j-5.4.0.jar;H:\software\apache-maven-3.3.9-bin\localRepository\net\java\dev\jna\jna\5.12.1\jna-5.12.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\github\jai-imageio\jai-imageio-core\1.4.0\jai-imageio-core-1.4.0.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\pdfbox\pdfbox\2.0.26\pdfbox-2.0.26.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\pdfbox\fontbox\2.0.26\fontbox-2.0.26.jar;H:\software\apache-maven-3.3.9-bin\localRepository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\pdfbox\pdfbox-tools\2.0.26\pdfbox-tools-2.0.26.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\pdfbox\pdfbox-debugger\2.0.26\pdfbox-debugger-2.0.26.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\pdfbox\jbig2-imageio\3.0.4\jbig2-imageio-3.0.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\commons-io\commons-io\2.11.0\commons-io-2.11.0.jar;H:\software\apache-maven-3.3.9-bin\localRepository\net\sourceforge\lept4j\lept4j\1.16.2\lept4j-1.16.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\jboss\jboss-vfs\3.2.17.Final\jboss-vfs-3.2.17.Final.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\httpcomponents\httpcore\4.4.14\httpcore-4.4.14.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\commons\commons-lang3\3.10\commons-lang3-3.10.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\alibaba\easyexcel\3.1.1\easyexcel-3.1.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\alibaba\easyexcel-core\3.1.1\easyexcel-core-3.1.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\alibaba\easyexcel-support\3.1.1\easyexcel-support-3.1.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\poi\poi\4.1.2\poi-4.1.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\commons-codec\commons-codec\1.15\commons-codec-1.15.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\commons\commons-collections4\4.4\commons-collections4-4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\commons\commons-math3\3.6.1\commons-math3-3.6.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\zaxxer\SparseBitSet\1.2\SparseBitSet-1.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\poi\poi-ooxml\4.1.2\poi-ooxml-4.1.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\commons\commons-compress\1.19\commons-compress-1.19.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\github\virtuald\curvesapi\1.06\curvesapi-1.06.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\poi\poi-ooxml-schemas\4.1.2\poi-ooxml-schemas-4.1.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\xmlbeans\xmlbeans\3.1.0\xmlbeans-3.1.0.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\apache\commons\commons-csv\1.8\commons-csv-1.8.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\ehcache\ehcache\3.9.2\ehcache-3.9.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\glassfish\jaxb\jaxb-runtime\2.3.3\jaxb-runtime-2.3.3.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\glassfish\jaxb\txw2\2.3.3\txw2-2.3.3.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\sun\istack\istack-commons-runtime\3.0.11\istack-commons-runtime-3.0.11.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\sun\activation\jakarta.activation\1.2.2\jakarta.activation-1.2.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\mysql\mysql-connector-java\8.0.23\mysql-connector-java-8.0.23.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\baomidou\mybatis-plus-boot-starter\3.4.1\mybatis-plus-boot-starter-3.4.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\baomidou\mybatis-plus\3.4.1\mybatis-plus-3.4.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\baomidou\mybatis-plus-extension\3.4.1\mybatis-plus-extension-3.4.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\baomidou\mybatis-plus-core\3.4.1\mybatis-plus-core-3.4.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\baomidou\mybatis-plus-annotation\3.4.1\mybatis-plus-annotation-3.4.1.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\github\jsqlparser\jsqlparser\3.2\jsqlparser-3.2.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\mybatis\mybatis\3.5.6\mybatis-3.5.6.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\mybatis\mybatis-spring\2.0.5\mybatis-spring-2.0.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\boot\spring-boot-autoconfigure\2.4.4\spring-boot-autoconfigure-2.4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\boot\spring-boot-starter-jdbc\2.4.4\spring-boot-starter-jdbc-2.4.4.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\zaxxer\HikariCP\3.4.5\HikariCP-3.4.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\org\springframework\spring-jdbc\5.3.5\spring-jdbc-5.3.5.jar;H:\software\apache-maven-3.3.9-bin\localRepository\com\alibaba\fastjson\1.2.73\fastjson-1.2.73.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 com.example.spring_boot_study.TestMain,testReflect
是否被指定 直接注解或元注解 标注:true
指定 直接注解或元注解 的所有属性:
value:
目标类上标注的 直接注解 有:
org.springframework.stereotype.Service
org.springframework.context.annotation.Configuration
目标指定注解上的 元注解 有:
org.springframework.stereotype.Component
org.springframework.stereotype.Indexed
目标是否被指定 直接注解 标注:true
目标是否被指定 元注解 标注:true
目标类含有被指定 直接注解或元注解 标注的方法,其名称有:a

相关文章

【Spring Boot 源码学习】自动装配流程源码解析(下)

【Spring Boot 源码学习】深入 FilteringSpringBootCondition

【Spring Boot 源码学习】OnClassCondition 详解

【Spring Boot 源码学习】OnBeanCondition 详解

【Spring Boot 源码学习】OnWebApplicationCondition 详解

【Spring Boot 源码学习】@Conditional 条件注解

————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/qq_45543606/article/details/129666978

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值