// ────────────────────────────────────────────────────────────────────────
// 1) com.example.glasses.service 패키지
package com.example.glasses.service;
@Service
public class GlassesService {
// ... 로직 생략
}
// ────────────────────────────────────────────────────────────────────────
// 2) com.example.sunglasses.service 패키지
package com.example.sunglasses.service;
@Service
public class GlassesService {
// ... 로직 생략
}
// com.example.glasses.controller
package com.example.glasses.controller;
import com.example.glasses.service.GlassesService;
import org.springframework.stereotype.Controller;
import lombok.RequiredArgsConstructor;
@Controller
@RequiredArgsConstructor
public class GlassesController {
private final GlassesService glassesService; // simple name 동일 → 충돌
}
-------------------------------------------------------------------
// com.example.sunglasses.controller
package com.example.sunglasses.controller;
import com.example.sunglasses.service.GlassesService;
import org.springframework.stereotype.Controller;
import lombok.RequiredArgsConstructor;
@Controller
@RequiredArgsConstructor
public class SunglassesController {
private final GlassesService glassesService; // simple name 동일 → 충돌
}
// 어디 패키지에 속한 컬럼을 SunglassesController가 가지는지 정의하고 있음
import com.example.sunglasses.service.GlassesService;
@Controller
public class SunglassesController {
private final GlassesService glassesService;
// 주입 받아서 결국에는 SunglassesController 객체를 생성한다는 것 ->
// GlassesService의 명확한 package 경로가 필요하단것 (주입 받을 때 명확한 패키지(타입) 알아야 한다는 것) ->
// 그럼 결국 GlassesService bean 등록 자체도 특정 패키지(타입)에 맞춰 등록되어야 있어야 한다.
public SunglassesController(GlassesService glassesService) {
this.glassesService = glassesService;
}
}
GlassesService의 Package가 다르고, 주입받는 속성이 다른데 왜 안되지?! com.example.glasses.service.GlassesService → "glassesService"
com.example.sunglasses.service.GlassesService → "glassesService"
BeanDefinitionOverrideException 등 충돌 오류!nameToDefinition:
{
"com.example.glasses.service.GlassesService" : BeanDefinition{
beanClassName="com.example.glasses.service.GlassesService",
scope="singleton",
lazyInit=false,
... // 기타 메타데이터
},
"com.example.sunglasses.service.GlassesService" : BeanDefinition{ … }
}
Class<?> 객체List<String>)typeToNames:
{
com.example.glasses.service.GlassesService.class : [
"com.example.glasses.service.GlassesService"
],
com.example.sunglasses.service.GlassesService.class : [
"com.example.sunglasses.service.GlassesService"
]
}
| 전략 | Bean Name | 충돌 여부 |
|---|---|---|
| 기본(simple) | glassesService ×2 | 있음 |
| FCQN 전략 | com.example…GlassesService, com.example…GlassesService | 없음 |
FCQN 네이밍 전략 사용하기@SpringBootApplication(
scanBasePackages = "com.example",
nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class
)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
"com.example.glasses.service.GlassesService"
"com.example.sunglasses.service.GlassesService"
// com.example.glasses.controller
package com.example.glasses.controller;
import com.example.glasses.service.GlassesService;
import org.springframework.stereotype.Controller;
import lombok.RequiredArgsConstructor;
@Controller
@RequiredArgsConstructor
public class GlassesController {
private final GlassesService glassesService; // Type이 다르기 때문에 가능
}
-------------------------------------------------------------------
// com.example.sunglasses.controller
package com.example.sunglasses.controller;
import com.example.sunglasses.service.GlassesService;
import org.springframework.stereotype.Controller;
import lombok.RequiredArgsConstructor;
@Controller
@RequiredArgsConstructor
public class SunglassesController {
private final GlassesService glassesService; // Type이 다르기 때문에 가능
}
@Service("abc"), @Qualifier("abc") 와 같이 임시로 Bean Name을 겹치지 않게 지정해도 된다!