*책 내용과 다르게, 다음과 같은 환경에서 프로젝트 생성
- Windows11(윈도우 11) 환경
- 자바 JDK 17 버전 설치 https://yungenie.tistory.com/11
[Java] 차근차근 Java 설치하기 (JDK17, Window 11)
자바 개발 도구 설치 방법에 대해서 알아보겠습니다. Java17은 LTS(Long Term Support : 장기 지원) 릴리즈로 1년 후까지 기술 지원 및 버그를 개선한 서비스를 제공받을 수 있습니다. 업데이트 버전을 꾸
yungenie.tistory.com
- 스프링 부트 4.31.0 사용 - STS(Spring Tool Suite) 설치(Spring Tools for Eclipse - https://spring.io/tools)
=> https://priming.tistory.com/147 참고
[Windows] Spring Tool Suite 4(STS 4) 다운로드 및 설치
STS란?Spring Tool Suite(STS)는 스프링 프로젝트를 생성하고, 개발할 수 있게 해주는 도구입니다. STS 설치 과정에 대해 설명드리겠습니다. 설치 파일 다운로드STS 공식 사이트에서 설치 파일을 다운로
priming.tistory.com

- MySQL Community Server 8.0.42 설치 https://dev.mysql.com/downloads/mysql/
MySQL :: Download MySQL Community Server
Select Version: 9.3.0 Innovation 8.4.5 LTS 8.0.42 Select Operating System: Select Operating System… Microsoft Windows Ubuntu Linux Debian Linux SUSE Linux Enterprise Server Red Hat Enterprise Linux / Oracle Linux Fedora Linux - Generic Oracle Solaris mac
dev.mysql.com

- Gradle
**STS에서 Gradle 프로젝트 생성한 과정



*** 함께 보면 좋은 글
스프링부트 핵심 가이드(장정우 지음) - 예외 처리 에러 해결, 액추에이터 활용하기
*책 내용과 다르게, 다음과 같은 환경에서 프로젝트 생성 Windows11(윈도우 11) 환경자바 JDK 17 버전 설치 https://yungenie.tistory.com/11 [Java] 차근차근 Java 설치하기 (JDK17, Window 11)자바 개발 도구 설치 방법
keep-programming-study.tistory.com
1. 액추에이터 주요 기능 살펴보기
1) 애플리케이션 기본 정보(/info)
- 액추에이터의 /info 엔드포인트를 활용하면 가동 중인 애플리케이션의 정보를 볼 수 있음
- application.properties 파일 내에 다음과 같이 애플리케이션 정보 속성을 작성한 후 서버 실행
# 액추에이터 info 정보 설정
info.organization.name=programming
info.contact.email=abc@defg.co.kr
info.contact.phoneNumber=010-1234-5678
에러 발생!
2026-02-05 19:00:42.291 [main] WARN o.h.e.j.e.i.JdbcEnvironmentInitiator - HHH000342: Could not obtain connection to query metadata
org.hibernate.exception.JDBCConnectionException: unable to obtain isolated JDBC connection [Public Key Retrieval is not allowed] [n/a]
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:100)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:58)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:108)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:94)
- 액추에이터를 추가하면, Spring Boot가 자동으로 DataSource HealthIndicator를 등록:
이때 spring-boot-starter-actuator가 들어오면서, DataSource 관련 빈을 확인하다가 Hibernate/JPA가 MySQL 드라이버 설정을 기본값으로 잡음
-> application.properties 다음과 같이 수정하여 해결
spring.application.name=study
# 테스트용 인메모리 H2 DB 설정
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
# JPA 설정
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
# H2 콘솔 (선택)
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
# Spring Boot 3.x 계열이면 아래 두 줄 반드시 붙임
management.info.env.enabled=true
management.info.defaults.enabled=true
# 액추에이터 info 정보 설정
info.organization.name=programming
info.contact.email=abc@defg.co.kr
info.contact.phoneNumber=010-1234-5678
# 액추에이터 엔드포인트 노출 설정(모든 엔드포인트 열기)
management.endpoints.web.exposure.include=*
# 액추에이터 health 상세 내역 활성화
management.endpoint.health.show-details=always
- http://localhost:8080/actuator/info에 접속 시 다음과 같이 뜸

2) 애플리케이션 상태(/health)
- 주로 네트워크 계층 중 L4(Loadbalancing) 레벨에서 애플리케이션의 상태를 확인하기 위해 사용
- http://localhost:8080/actuator/health에 접속 시 다음과 같이 뜸
-> management.endpoint.health.show-details=always가 있으므로, health 상세 내역이 보이는 것

3) 빈 정보 확인(/beans)
- 스프링 컨테이너에 등록된 빈의 전체 목록을 표시(JSON 형식으로 빈 정보를 반환)
- http://localhost:8080/actuator/beans에 접속 시 다음과 같이 뜸

4) 스프링 부트의 자동설정 내역 확인(/conditions)
- 스프링부트의 자동설정(AutoConfiguration) 조건 내역 확인
- http://localhost:8080/actuator/conditions에 접속 시 다음과 같이 뜸

5) 스프링 환경변수 정보(/env)
- 스프링의 환경변수 정보 확인(application.properties 파일의 변수들, OS/JVM의 환경변수들이 표시됨)
- http://localhost:8080/actuator/env에 접속 시 다음과 같이 뜸

6) 로깅 레벨 확인(/loggers)
- 애플리케이션의 로깅 레벨 수준 확인
- http://localhost:8080/actuator/loggers에 접속 시 다음과 같이 뜸

2. 액추에이터 커스텀 기능 만들기
- 개발자의 요구사항에 맞춰, 커스텀 기능 설정 및 개발이 가능
- 커스텀 기능 개발 방식: 기존 기능에 내용을 추가 or 새로운 엔드포인트를 개발
1) 기존 기능에 내용 추가: InfoContributer 인터페이스를 구현하는 클래스 생성
package com.example.demo.config.actuator;
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.actuate.info.Info.Builder;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.stereotype.Component;
/**
* Spring Boot Actuator의 Info 엔드포인트에
* 커스텀 정보를 추가하기 위한 클래스
*/
@Component // 스프링 빈으로 등록되어 자동으로 Actuator에 연결
public class CustomInfoContributor implements InfoContributor {
/**
* InfoContributor 인터페이스의 구현 메서드
* : 애플리케이션의 /actuator/info 엔드포인트에 원하는 정보를 추가
*/
@Override
public void contribute(Builder builder) {
// Info에 담을 커스텀 데이터를 저장할 Map 생성
Map<String, Object> content = new HashMap<>();
// key-value 형태로 원하는 정보 추가
content.put("code-info", "InfoContributor 구현체에서 정의한 정보");
// builder에 "custom-info-contributor"라는 이름으로 Map을 등록
builder.withDetail("custom-info-contributor", content);
}
}
*서버 재실행 후 http://localhost:8080/actuator/info에 접속

2) 새로운 엔드포인트 개발: 커스텀 엔드포인트 클래스 생성
- @Endpoint 어노테이션으로 빈에 추가된 객체들은, @ReadOperation @WriteOperation @DeleteOperation 어노테이션으로 JMX나 HTTP를 통해 커스텀 엔드포인트를 노출시킬 수 있음
-> JMX에서만 사용하거나 HTTP에서만 사용하고 싶을 경우, @JmxEndpoint @WebEndpoint를 사용하면 됨
package com.example.demo.config.actuator;
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.stereotype.Component;
/**
* Spring Boot Actuator에 커스텀 엔드포인트를 추가하는 클래스
* : "/actuator/note" 경로로 접근할 수 있으며, Read, Write, Delete 기능을 제공
*/
@Component // 스프링 빈으로 등록되어 Actuator에 자동 연결
@Endpoint(id="note") // 엔드포인트 ID를 "note"로 지정하여, /actuator/note 로 접근 가능
public class NoteEndpoint {
// 엔드포인트에서 관리할 데이터를 저장하는 Map
private Map<String, Object> noteContent = new HashMap<>();
/**
* ReadOperation: GET 요청 시 호출
* : 현재 저장된 noteContent 전체를 반환
*/
@ReadOperation
public Map<String, Object> getNote() {
return noteContent;
}
/**
* WriteOperation: POST 요청 시 호출
* : key-value 형태로 데이터를 저장하고 전체 Map을 반환
*/
@WriteOperation
public Map<String, Object> writeNote(String key, Object value) {
noteContent.put(key, value);
return noteContent;
}
/**
* DeleteOperation: DELETE 요청 시 호출
* : 전달받은 key에 해당하는 데이터를 삭제하고 전체 Map을 반환
*/
@DeleteOperation
public Map<String, Object> deleteNote(String key) {
noteContent.remove(key);
return noteContent;
}
}
(1) 서버 실행
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2026-02-19 19:01:45.279 [main] ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'healthEndpointWebMvcHandlerMapping' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointWebExtensionConfiguration$MvcAdditionalHealthEndpointPathsConfiguration.class]: Failed to instantiate [org.springframework.boot.actuate.endpoint.web.servlet.AdditionalHealthEndpointPathsWebMvcHandlerMapping]: Factory method 'healthEndpointWebMvcHandlerMapping' threw exception with message: Failed to extract parameter names for public java.util.Map com.example.demo.config.actuator.NoteEndpoint.deleteNote(java.lang.String)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:657)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:645)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1375)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1205)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1222)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1188)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1123)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350)
at com.example.demo.StudyApplication.main(StudyApplication.java:11)
- 서버실행에 에러발생!! 역시 IntelliJ 환경이었다면 발생하지 않았을 에러...
-> 파라미터 이름을 명시적으로 지정할 수 있는 액추에이터의 @Selector 어노테이션을 사용하도록 수정하면 해결 (요청에서 key값 추출 가능) + Spring Boot 3.5.3 환경에서는 메서드 시그니처를 Actuator가 이해할 수 있는 형태로 맞춰야 함
package com.example.demo.config.actuator;
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.annotation.Selector;
import org.springframework.boot.actuate.endpoint.annotation.WriteOperation;
import org.springframework.stereotype.Component;
/**
* Spring Boot Actuator에 커스텀 엔드포인트를 추가하는 클래스
* : "/actuator/note" 경로로 접근할 수 있으며, Read, Write, Delete 기능을 제공
*/
@Component // 스프링 빈으로 등록되어 Actuator에 자동 연결
@Endpoint(id="note") // 엔드포인트 ID를 "note"로 지정하여, /actuator/note 로 접근 가능
public class NoteEndpoint {
// 엔드포인트에서 관리할 데이터를 저장하는 Map
private Map<String, String> noteContent = new HashMap<>();
/**
* ReadOperation: GET 요청 시 호출
* : 현재 저장된 noteContent 전체를 반환
*/
@ReadOperation
public Map<String, String> getNote() {
return noteContent;
}
/**
* WriteOperation: POST 요청 시 호출
* : key-value 형태로 데이터를 저장하고 전체 Map을 반환
*/
@WriteOperation
public Map<String, String> writeNote(@Selector String key, String value) {
noteContent.put(key, value);
return noteContent;
}
/**
* DeleteOperation: DELETE 요청 시 호출
* : 전달받은 key에 해당하는 데이터를 삭제하고 전체 Map을 반환
*/
@DeleteOperation
public Map<String, String> deleteNote(@Selector String key) {
noteContent.remove(key);
return noteContent;
}
}
- 추가로, 프로젝트 우클릭 -> Properties -> Java Compiler -> Store information about method parameters (-parameters) 체크하니까 서버실행 됨!!
-> 이걸하면... 그동안 @RequestBody가 안되서 @RequestParameter를 썼던 문제도 해결가능할지도??

(2) 서버 실행 후, Talend API Tester(크롬 확장 프로그램)에서 커스텀 엔드포인트 호출 [Send를 클릭하면 됨]
- GET 요청: 값을 넣지 않은 상태이기에 JSON 형태의 빈 값이 보임

- POST 호출 후 다시 GET 호출: 값을 추가하여 /note에서 확인이 가능한 상태


- DELETE 호출 후 다시 GET 호출: 값을 삭제하여 /note가 다시 빈 값이 된 상태


'스프링(Spring), 스프링부트(SpringBoot) > 스프링부트(SpringBoot) 기초' 카테고리의 다른 글
| 스프링부트 핵심 가이드(장정우 지음) - 서버 간 통신 1: RestTemplate (1) | 2026.03.03 |
|---|---|
| 스프링부트 핵심 가이드(장정우 지음) - 예외 처리 에러 해결, 액추에이터 활용하기 (0) | 2026.02.04 |
| 스프링부트 핵심 가이드(장정우 지음) - 예외 처리 (0) | 2025.11.26 |
| 스프링부트 핵심 가이드(장정우 지음) - 유효성 검사(2) (0) | 2025.11.10 |
| 스프링부트 핵심 가이드(장정우 지음) - 유효성 검사(1) (0) | 2025.10.24 |