해결된 질문
작성
·
165
1
안녕하세요
또 이렇게 질문을 드리네요
공통 개발 - 인터셉터에서 AdminInterceptor은 @Component을 사용합니다.
제가 자료를 찾아봤는데 개념 이해가 어렵더라구요
개발자가 직접 작성한 class를 Bean으로 등록하기 위한 어노테이션이라고 정의 되어 있던데
그럼 Bean은 또 뭔지 찾아봤어요
자바 객체를 스프링에서는 Bean이라고 한다. 라고 정의 되었더라구요. 객체는 뭐 재료를 합쳐서 사용자가 사용할 수 있겠끔 만들어진 거가 객체인건 알고 있고 ....
다시 정리하면 직접 작성한 class를 객체화 시키려는건가라고 좀 애매하게 이해했는데 이건 또 아닌거 같고..
예제를 본다면
class InlineExamConsole
{
@Autowired
public void setExam(Exam exam) {
this.exam = exam;
}
}
이 클레스면 xml은
<context:annotation-config/>
<bean id = "exam" class="entity.NewlecExam" />
</bean>
로 되어야 하고...
IoC 컨테이너의 상황은
exam: Exam<---- console:InlineExamCode
처럼 플로우가 될꺼구...
그런데
<context:annotation-config/>
<bean id = "exam" class="entity.NewlecExam" />
를 해서 삭제.... bean을 삭제 하면
IoC 컨테이너의 상황은 아래처럼 될듯 한데
exam: Exam<---- console:InlineExamCode
console는 또 사용해야겠으니 아래처럼 @Componet를 등장시키고,
class InlineExamConsole
{
@Autowired
public void setExam(Exam exam) {
this.exam = exam;
}
}
IoC 컨테이너에서 console:InlineExamCode를 부활
exam: Exam<---- console:InlineExamCode
그런데 부활만 했지 그냥 좀비 상태가 되어 버린 console:InlineExamCode... console:InlineExamCode은 어떻게 찾는건지..
그럼 xml를 변경
<context:annotation-config/>
<bean id = "exam" class="entity.NewlecExam" />
위 테그로 spring.di.ui에 컴포넌트가 있으니 다른곳에 찾지 말고 위 테그에서 컴포넌트 찾고 그 컴포넌트를 Bean에 등록해서 객채화 해~~~ 라는거같은데
코드상으로는 이렇게 이해를 했어요
하지만 강의에서는 context:component-scan base-package 를 못본거 같은데 ....(뭐 제가 바빠서 꼼꼼하게 못본것일 수도 있고 ) 저 컴포넌트의 이해를 좀 도와주시면 안될까요??
컴포넌트 활용이나 @Component를 사용안하면 얼마나 불편해지길래 저 이노테이션을 사용한건지 ...
(사실 저 이노테이션을 안써도 잘 활용할 수 있을거 같은데 ...)
답변 1
0
안녕하세요 정보근입니다:)
질문자님의 자바/스프링 이해도가 어느 정도인지 몰라 간단하고 기본적인 내용 위주로 답변 드려보겠습니다.
크게 아래 두가지 내용을 설명 드릴 수 있을 것 같네요.
스프링 Bean이란 무엇인가
스프링과 스프링 부트의 차이
스프링 Bean이란 무엇인가
자바는 객체지향적 프로그래밍 언어라는 것은 알고 계시죠?
모든 자바 프로그래밍은 new 클래스명()과 같이 특정 클래스의 객체를 만드는 것에서부터 시작합니다.
그리고 Bean이란 개발자가 직접 new 명령어를 써서 객체를 만드는 것이 아닌,
스프링 내부적으로 알아서 객체를 생성하는, 즉 스프링에 의해 생성되고 관리되는 객체를 의미합니다.
모든 자바 객체가 아니라는 것을 알아주세요.
그럼 개발자가 생성한 많은 클래스들 중에 어떤 클래스가 스프링에 의해서 관리될까요?
스프링의 관점에서 생각해보면, 실행이 되면서 Bean을 만들어서 등록해야 되는데,
어떤 클래스를 Bean으로 등록해야할지 어떻게 알 수 있을까요?
그걸 알려주는 어노테이션이 @Component입니다.
그리고 @Controller, @Service 등도 마찬가지에요.
@Controller나 @Service를 선택하고 cmd + B(맥)나 ctrl + B(윈도우)를 누르면 내용을 볼 수 있는데요.
@Component 어노테이션이 포함되어 있습니다.
그래서 스프링이 시작될 때 이런 어노테이션이 달린 모든 클래스를 찾아서,
new Controller(), new Service() 이런 식으로 객체를 생성합니다.
기본적으로 Singleton 방식이라 객체는 단 하나만 생성됩니다.
그래서 개발자 작성하는 컨트롤러에서는, new Service()처럼 직접 서비스 객체를 만드는 게 아니고,
컨트롤러 클래스의 생성자에서 서비스 객체를 받아서 사용하게 됩니다.
스프링 내부적으로 컨트롤러 클래스가 서비스 클래스에 의존하는 것을 확인한 뒤,
Service service = new Service();
Controller controller = new Controller(service);
와 같이 알아서 필요한 Bean들을 만들고 의존성을 주입해주는거죠.
참고로 @ComponentScan이란 어노테이션으로 어떤 컴포넌트(=빈)를 스캔할지 지정해줄 수도 있습니다.
기본적으로 해당 어노테이션이 있는 클래스와 같은 레벨, 그리고 하위의 모든 패키지가 스캔 범위라고 보시면 됩니다.
그리고 @SpringBootApplication 안에 포함되어 있어요.
PortfolioApplication에서 해당 어노테이션 내부를 보시면 @ComponentScan 확인이 되실거에요.
그래서 PortfolioApplication과 같은 레벨에 있는 admin, domain, presentation 패키지 내의
모든 @Controller 등이 붙은 클래스는 빈으로 등록이 되고요.
만약 특정 서비스를 com.yongback.api.service와 같은 위치로 옮기면 스프링 실행 중 오류가 날 거에요.
PortfolioApplication은 com.yongback.portfolio 안에 있으니, 스캔 범위를 벗어나기 때문입니다.
스프링과 스프링 부트의 차이
여기서는 "스프링"과 "스프링 부트"를 구분해서 사용하도록 하겠습니다.
xml 파일을 사용하는 것은 스프링에서 빈을 등록하는 방법입니다.
빈을 등록하는 다양한 방법 중에 저렇게 직접 xml을 설정해서 범위를 지정하고, 빈의 이름을 지정하고 하는 방법도 있어요.
하지만 꽤 번거로운 작업이죠.
스프링 부트는 위에서 설명한 @ComponentScan, @Component, @Controller, @Service 등으로 저 기능을 다 대신할 수 있어요.
xml 없이 자바/코틀린 코드만 가지고 설정할 수 있는거죠.
말씀드렸다시피 PortfolioApplication -> @SpringBootApplication 안에 @ComponentScan이 있으니
<context:component-scan base-package = "spring.di.ui"/>와 같이 직접 지정할 필요도 없습니다.
물론 좀 더 커스터마이징을 하고 싶다면 @ComponentScan을 새로 추가해줘야겠죠.
@Configuration을 붙인 클래스 내부에 @Bean을 붙인 메소드를 이용해서 빈을 직접 등록해주는 방법도 있습니다.
AdminSecurityConfiguration이 그런 방식을 사용했어요.
사실 어떤 게 더 편한지는 개인차가 있을 수 있는 내용이긴 합니다.
하지만 스프링 부트 자체가 사람들이 스프링을 쓰면서 불편했던 점을 개선한 버전이라,
개인적으로는 어노테이션을 이용하는 것이 훨씬 편하다고 생각되긴 하네요.
감사합니다.