Подтвердить что ты не робот

Можно ли включить/отключить загрузку spring @RestController с помощью свойств?

Учитывая "стандартное" приложение загрузки spring с @RestController, например

@RestController
@RequestMapping(value = "foo", produces = "application/json;charset=UTF-8")
public class MyController {
    @RequestMapping(value = "bar")
    public ResponseEntity<String> bar(
        return new ResponseEntity<>("Hello world", HttpStatus.OK);
    }
}

Есть ли аннотация или метод, который предотвращает запуск конечной точки вообще, если/если определенное свойство приложения не существует/не существует.

Примечание. Тестирование свойства внутри метода и взрыва не является решением, поскольку конечная точка будет существовать.

Меня не интересует гранулярность: то есть включение/отключение только метода или всего класса прекрасны.


Поскольку профиль не является свойством, управление через профили не решает мою проблему.

4b9b3361

Ответ 1

Я нашел простое решение с помощью @ConditionalOnExpression:

@RestController
@ConditionalOnExpression("${my.controller.enabled:false}")
@RequestMapping(value = "foo", produces = "application/json;charset=UTF-8")
public class MyController {
    @RequestMapping(value = "bar")
    public ResponseEntity<String> bar(
        return new ResponseEntity<>("Hello world", HttpStatus.OK);
    }
}

При добавлении этой аннотации, если у меня нет

my.controller.enabled=true

в моем файле application.properties, контроллер не запустится вообще.

Вы также можете использовать более удобный:

@ConditionalOnProperty("my.property")

который ведет себя точно так же, как указано выше; если свойство присутствует и "true", компонент запускается, иначе это не так.

Ответ 2

Добавление к этому вопросу и еще один вопрос здесь.

Это мой ответ:

Я бы на самом деле использовал бин @RefreshScope, а затем, когда вы хотите остановить Rest Controller во время выполнения, вам нужно всего лишь изменить свойство указанного контроллера на false.

SO ссылка на изменение свойства во время выполнения.

Вот мои фрагменты рабочего кода:

@RefreshScope
@RestController
class MessageRestController(
    @Value("\${message.get.enabled}") val getEnabled: Boolean,
    @Value("\${message:Hello default}") val message: String
) {
    @GetMapping("/message")
    fun get(): String {
        if (!getEnabled) {
            throw NoHandlerFoundException("GET", "/message", null)
        }
        return message
    }
}

И есть другие варианты использования фильтра:

@Component
class EndpointsAvailabilityFilter @Autowired constructor(
    private val env: Environment
): OncePerRequestFilter() {
    override fun doFilterInternal(
        request: HttpServletRequest,
        response: HttpServletResponse,
        filterChain: FilterChain
    ) {
        val requestURI = request.requestURI
        val requestMethod = request.method
        val property = "${requestURI.substring(1).replace("/", ".")}." +
                "${requestMethod.toLowerCase()}.enabled"
        val enabled = env.getProperty(property, "true")
        if (!enabled.toBoolean()) {
            throw NoHandlerFoundException(requestMethod, requestURI, ServletServerHttpRequest(request).headers)
        }
        filterChain.doFilter(request, response)
    }
}

Мой Github объясняет, как отключить во время выполнения

Ответ 3

Я предполагаю, что этот вопрос связан с тем фактом, что вы используете разные файлы application.properties для своих различных сред. В этом случае вы можете использовать пружинные профили и разделять конфигурации в разные файлы с суффиксом имени профиля, например:

application.properties:

[email protected]@

application-local.properties:

 //some config

application-prod.properties:

//some config

затем в параметрах сборки вы можете указать, какую среду вы строите, добавив опцию:

-Dspring.profiles.active= //<-put here profile local or prod

тогда в вашем приложении вы можете включить/отключить любой Spring Bean, добавив

@Profile("put here profile name")

например:

@RestController
@Profile("local")
@RequestMapping("/testApi")
public class RestForTesting{

//do some stuff

}

Теперь мой RestForTesting будет создан, только если я запускаю сборку, созданную с

-Dspring.profiles.active=local