Spring Tool Suite(STS)는 Eclipse 기반의 통합 개발 환경으로, Spring 생태계에서의 개발 생산성을 극대화하도록 설계되었다. 본 문서에서는 네트워크가 제한된 환경에서도 안정적으로 설치할 수 있는 STS 3.9.0 오프라인 업데이트 사이트 패키지를 중심으로, 실무 적용에 필요한 핵심 기술과 운영 노하우를 다룬다.
Spring 핵심 메커니즘 이해
Spring 프레임워크는 제어의 역전(IoC)과 관점 지향 프로그래밍(AOP)을 기반으로 한 유연한 아키텍처를 제공한다. 이를 통해 비즈니스 로직과 기술적 관심사를 효과적으로 분리할 수 있다.
의존성 주입 패턴
필드 주입 대신 생성자 주입 방식을 권장하며, 이를 통해 불변성을 보장하고 테스트 용이성을 높인다.
@Repository
public class JdbcOrderDao implements OrderDao {
private final JdbcTemplate jdbcTemplate;
public JdbcOrderDao(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
컨테이너 생명주기 관리
AnnotationConfigApplicationContext를 활용한 순수 자바 기반 설정 예시:
public class ContainerBootstrap {
public static void main(String[] args) {
var ctx = new AnnotationConfigApplicationContext(AppConfig.class);
var svc = ctx.getBean(OrderService.class);
svc.processPendingOrders();
}
}
선언적 트랜잭션 처리
@Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = BusinessException.class)
public void transferFunds(Account from, Account to, MonetaryAmount amount) {
withdrawalService.debit(from, amount);
depositService.credit(to, amount);
}
Eclipse 플랫폼 아키텍처와 확장 체계
Eclipse의 강력한 확장성은 OSGi(Open Services Gateway initiative) 런타임 위에서 구현된다. 각 기능은 독립적인 번들(Bundle) 단위로 관리되며, 동적 로딩과 업데이트가 가능하다.
번들 메타데이터 구조
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Custom Spring Extension
Bundle-SymbolicName: com.example.spring.ext; singleton:=true
Bundle-Version: 2.1.0.qualifier
Bundle-Activator: com.example.spring.ext.internal.Activator
Require-Bundle: org.eclipse.ui;bundle-version="[3.109.0,4.0.0)",
org.eclipse.core.runtime;bundle-version="[3.13.0,4.0.0)"
Bundle-ActivationPolicy: lazy
Export-Package: com.example.spring.ext.api;version="2.1.0"
핵심 매니페스트 지시자 설명
| 지시자 | 역할 |
|---|---|
Bundle-SymbolicName | 번들 고유 식별자, 의존성 해석의 기준 |
Require-Bundle | 직접 의존하는 다른 번들 명시 |
Export-Package | 외부에 공개하는 패키지 목록 |
Bundle-ActivationPolicy | lazy 설정 시 실제 참조 시점까지 초기화 지연 |
오프라인 업데이트 사이트 구축 원리
기업 내부망이나 보안 분리망 경에서는 인터넷 접근이 불가능하다. 이 경우 p2 프로비저닝 플랫폼 기반의 오프라인 저장소를 구축하여 플러그인을 배포한다.
저장소 디렉터리 구성
| 경로 | 설명 | 필수 여부 |
|---|---|---|
plugins/ | OSGi 번들 JAR 파일 | 필수 |
features/ | 기능 모듈 아카이브 | 조건부 |
content.jar | 설치 단위(IU) 메타데이터 | 필수 |
artifacts.jar | 물리적 파일 매핑 및 체크섬 | 필수 |
메타데이터 생성 명령
eclipse -application org.eclipse.equinox.p2.publisher.FeaturesAndBundlesPublisher \
-metadataRepository file:/opt/repos/sts-offline \
-artifactRepository file:/opt/repos/sts-offline \
-source /extracted/sts-plugins \
-compress -publishArtifacts
content.jar 내부 IU 예시
<iu id='com.vmware.sts.boot.validation' version='3.9.0.v201707310000' >
<properties>
<property name='org.eclipse.equinox.p2.name' value='Boot Validation Support'/>
</properties>
<provides>
<capability namespace='osgi.bundle'
name='com.vmware.sts.boot.validation'
version='3.9.0.v201707310000'/>
</provides>
<requires>
<required namespace='osgi.bundle'
name='org.eclipse.jdt.core'
range='[3.13.0,4.0.0)' />
</requires>
</iu>
artifacts.jar 매핑 항목
<artifact key='osgi.bundle.com.vmware.sts.boot.validation_3.9.0.v201707310000'>
<repositoryProperties size='524288'>
<property name='download.size' value='524288'/>
<property name='download.md5' value='d41d8cd98f00b204e9800998ecf8427e'/>
</repositoryProperties>
<mappings>
<mapping directory='plugins'
filename='com.vmware.sts.boot.validation_3.9.0.v201707310000.jar'/>
</mappings>
</artifact>
STS 3.9.0 기능 스펙과 Eclipse 4.7 호환성
STS 3.9.0은 Eclipse Photon(4.7.0) 플랫폼을 기반으로 하며, Spring Boot 2.x 초기 버전에 대한 개발 지원을 내장하고 있다.
주요 구성 모듈
| 모듈 | 기능 |
|---|---|
| Language Server | application.yml, @ConfigurationProperties 등의 스마트 편집 |
| Boot Dashboard | 다중 부트 애플리케이션 중앙 관리 |
| Live Beans Graph | 런타임 Bean 의존성 시각화 |
| Cloud Foundry 통합 | 클라우드 배포 마법사 |
JDK 9+ 모듈 시스템 대응
STS 3.9.0은 비모듈 JAR로 패키징되어 있어 JPMS 환경에서 다음과 같이 실행해야 한다:
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens org.eclipse.osgi/org.osgi.framework=ALL-UNNAMED
Spring Boot 자동 구성 내부 메커니즘
Spring Boot의 @EnableAutoConfiguration은 클래스패스 탐색과 조건부 판정을 통해 필요한 인프라스트럭처를 자동으로 구성한다.
자동 구성 핵심 흐름
@AutoConfiguration
@ConditionalOnClass({Servlet.class, DispatcherServlet.class})
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@EnableConfigurationProperties(WebProperties.class)
public class DispatcherServletAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "dispatcherServlet")
public DispatcherServlet dispatcherServlet(WebProperties webProperties) {
DispatcherServlet servlet = new DispatcherServlet();
servlet.setDispatchOptionsRequest(webProperties.getDispatchOptionsRequest());
return servlet;
}
}
조건 어노테이션 종류
| 어노테이션 | 판정 기준 |
|---|---|
@ConditionalOnClass | 클래스패스에 특정 클래스 존재 여부 |
@ConditionalOnMissingBean | 스프링 컨테이너 내 해당 타입 Bean 부재 여부 |
@ConditionalOnProperty | 설정 속성 값 매칭 여부 |
@ConditionalOnWebApplication | 웹 애플리케이션 환경 여부 |
spring.factories에서 전용 메타파일로의 전환
| 버전 | 설정 방식 | 특징 |
|---|---|---|
| 2.3.x 이하 | META-INF/spring.factories | 단일 파일, 전체 SPI 포함 |
| 2.4.0 이상 | META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports | 자동 구성 전용 분리, 인덱싱 최적화 |
외부화 설정과 프로파일 관리
운영 환경별 설정 분리는 spring.profiles.active와 외부 속성 소스를 통해 유연하게 처리된다.
속성 우선순위 (높은 순)
- 커맨드라인 인수
--server.port=8081 SPRING_APPLICATION_JSON환경변수- JAR 외부
config/application.yml - JAR 외부
application.yml - JAR 내부
config/application.yml - JAR 내부
application.yml @PropertySource지정 파일
암호화 설정 예시 (Jasypt)
spring.datasource.url=jdbc:postgresql://db.internal:5432/orders
spring.datasource.username=app_user
spring.datasource.password=ENC(9OX8Pteg2PiP8wHfnWiaMjaCfqOIOZbw)
@Configuration
public class CryptoConfig {
@Bean
public StringEncryptor jasyptEncryptor() {
var encryptor = new PooledPBEStringEncryptor();
var cfg = new SimpleStringPBEConfig();
cfg.setPassword(System.getenv("JASYPT_KEY"));
cfg.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
encryptor.setConfig(cfg);
return encryptor;
}
}
Spring Roo CLI 활용
Spring Roo는 반복적인 CRUD 코드 생성을 자동화하는 명령줄 도구로, 빠른 프로토타이핑에 유용하다.
초기화 및 엔티티 정의
roo> project --topLevelPackage com.example.inventory
roo> jpa setup --provider HIBERNATE --database POSTGRESQL
roo> entity jpa --class ~.domain.StockItem
roo> field string --fieldName sku --sizeMin 8 --sizeMax 20 --notNull
roo> field number --fieldName quantity --type java.lang.Integer --notNull
roo> field date --fieldName lastRestocked --type java.time.LocalDateTime
웹 스캐폴드 생성
roo> web mvc setup
roo> web mvc scaffold --class ~.domain.StockItem --pathPrefix /admin/inventory
Roo 스크립트 기록 및 재생
roo> script recording on
# ... 작업 수행 ...
roo> script recording off
roo> script --file ~/templates/inventory-setup.roo
STS 그래픽 툴 연동
Spring Explorer 뷰 계층
OrderManagement (Spring Boot)
├── @Configuration
│ └── PersistenceConfig.java
│ └── WebSecurityConfig.java
├── @Service
│ └── OrderProcessingService.java
│ └── PaymentGatewayService.java
├── @Repository
│ └── OrderJpaRepository.java
├── @RestController
│ └── OrderApiController.java
└── @Component
└── OrderEventListener.java
Beans Graph 의존성 시각화
Spring Beans Graph 뷰에서는 다음과 같은 정보를 시각적으로 확인할 수 있다:
- 순환 참조: 빨간색 경고선으로 표시
- 조건부 Bean:
@ConditionalOnProperty미충족 시 회색 처리 - 프록시 객체: AOP 적용된 Bean은 이중 테두리로 표현
요청 매핑 뷰
| HTTP 메서드 | 패턴 | 처리 메서드 | 미디어타입 |
|---|---|---|---|
| GET | /api/v2/orders/{id} | OrderController.findById | application/json |
| POST | /api/v2/orders | OrderController.create | application/json |
| PATCH | /api/v2/orders/{id}/status | OrderController.updateStatus | application/json |
Actuator 운영 모니터링
엔드포인트 노출 설정
management:
endpoints:
web:
base-path: /ops
exposure:
include: health,info,metrics,prometheus
jmx:
exposure:
include: '*'
endpoint:
health:
show-details: when_authorized
show-components: always
metrics:
enabled: true
커스텀 HealthIndicator
@Component
public class MessageQueueHealthIndicator implements HealthIndicator {
private final AmqpTemplate amqpTemplate;
public MessageQueueHealthIndicator(AmqpTemplate amqpTemplate) {
this.amqpTemplate = amqpTemplate;
}
@Override
public Health health() {
try {
var props = amqpTemplate.execute(channel -> channel.queueDeclarePassive("orders"));
return Health.up()
.withDetail("queue", "orders")
.withDetail("consumerCount", props.getConsumerCount())
.build();
} catch (Exception ex) {
return Health.down(ex).build();
}
}
}
보안 강화 설정
@Configuration
public class ActuatorSecurityConfig {
@Bean
public SecurityFilterChain actuatorChain(HttpSecurity http) throws Exception {
http.securityMatcher(PathRequest.toEndpoint())
.authorizeHttpRequests(auth ->
auth.requestMatchers(EndpointRequest.to("health")).permitAll()
.anyRequest().hasRole("OPS_ADMIN"))
.httpBasic(Customizer.withDefaults());
return http.build();
}
}
오프라인 설치 최종 점검 항목
| 점검 항목 | 확인 방법 |
|---|---|
| ZIP 아카이브 무결성 | unzip -t sts-offline-site.zip 또는 SHA-256 대조 |
| p2 메타데이터 일관성 | content.jar와 artifacts.jar 존재 여부 |
| 의존성 충돌 여부 | Eclipse Plug-in Registry 뷰에서 중복 Bundle 확인 |
| 디렉터리 권한 | 실행 권한 보존: unzip -X 또는 chmod +x |
| JDK 호환성 | JDK 8 권장, JDK 9+ 시 --add-opens 추가 |
오프라인 패키지를 통한 STS 배포는 단순한 파일 복사를 넘어, 메타데이터 무결성 검증과 의존성 충돌 예방을 위한 체계적인 절차가 필요하다. 특히 기업 환경에서는 SBOM(Software Bill of Materials) 생성과 디지털 서명 검증을 병행하여 보안 기준을 충족해야 한다.