diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnEnabledEndpoint.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnEnabledEndpoint.java index f55fb15443..0c2f40f2b3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnEnabledEndpoint.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnEnabledEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -92,7 +92,7 @@ import org.springframework.core.env.Environment; * @see Endpoint */ @Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) +@Target({ ElementType.METHOD, ElementType.TYPE }) @Documented @Conditional(OnEnabledEndpointCondition.class) public @interface ConditionalOnEnabledEndpoint { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnEnabledEndpointCondition.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnEnabledEndpointCondition.java index 61bed1d9f0..953c93a22a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnEnabledEndpointCondition.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnEnabledEndpointCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -90,15 +90,11 @@ class OnEnabledEndpointCondition extends SpringBootCondition { private AnnotationAttributes getEndpointAttributes(ConditionContext context, AnnotatedTypeMetadata metadata) { - Assert.state( - metadata instanceof MethodMetadata - && metadata.isAnnotated(Bean.class.getName()), - "OnEnabledEndpointCondition may only be used on @Bean methods"); - Class endpointType = getEndpointType(context, (MethodMetadata) metadata); - return getEndpointAttributes(endpointType); + return getEndpointAttributes(getEndpointType(context, metadata)); } - private Class getEndpointType(ConditionContext context, MethodMetadata metadata) { + private Class getEndpointType(ConditionContext context, + AnnotatedTypeMetadata metadata) { Map attributes = metadata .getAnnotationAttributes(ConditionalOnEnabledEndpoint.class.getName()); if (attributes != null && attributes.containsKey("endpoint")) { @@ -107,15 +103,19 @@ class OnEnabledEndpointCondition extends SpringBootCondition { return target; } } - // We should be safe to load at this point since we are in the REGISTER_BEAN phase + Assert.state( + metadata instanceof MethodMetadata + && metadata.isAnnotated(Bean.class.getName()), + "OnEnabledEndpointCondition must be used on @Bean methods when the endpoint is not specified"); + MethodMetadata methodMetadata = (MethodMetadata) metadata; try { - return ClassUtils.forName(metadata.getReturnTypeName(), + return ClassUtils.forName(methodMetadata.getReturnTypeName(), context.getClassLoader()); } catch (Throwable ex) { throw new IllegalStateException("Failed to extract endpoint id for " - + metadata.getDeclaringClassName() + "." + metadata.getMethodName(), - ex); + + methodMetadata.getDeclaringClassName() + "." + + methodMetadata.getMethodName(), ex); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnEnabledEndpointTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnEnabledEndpointTests.java index 715fcdb43b..c77bfdda0c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnEnabledEndpointTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/ConditionalOnEnabledEndpointTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * Copyright 2012-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -148,6 +148,14 @@ public class ConditionalOnEnabledEndpointTests { .run((context) -> assertThat(context).hasBean("fooBar")); } + @Test + public void outcomeWhenEndpointEnabledPropertyIsFalseOnClassShouldNotMatch() { + this.contextRunner.withPropertyValues("management.endpoint.foo.enabled=false") + .withUserConfiguration( + FooEndpointEnabledByDefaultTrueOnConfigurationConfiguration.class) + .run((context) -> assertThat(context).doesNotHaveBean("foo")); + } + @Endpoint(id = "foo", enableByDefault = true) static class FooEndpointEnabledByDefaultTrue { @@ -193,6 +201,17 @@ public class ConditionalOnEnabledEndpointTests { } + @Configuration + @ConditionalOnEnabledEndpoint(endpoint = FooEndpointEnabledByDefaultTrue.class) + static class FooEndpointEnabledByDefaultTrueOnConfigurationConfiguration { + + @Bean + public FooEndpointEnabledByDefaultTrue foo() { + return new FooEndpointEnabledByDefaultTrue(); + } + + } + @Configuration static class FooEndpointEnabledByDefaultFalseConfiguration {