Spring으로 구성된 Application에서 객체를 생성, 관리, 소멸하는 역할을 담당합니다. 여기서 말하는 객체는 Bean이라고 하며, Spring Container는 Application이 시작될 때 설정 파일이나 annotation 같은 것들을 읽어 Bean을 생성하고 주입하는 모든 과정을 제어합니다.
Java에서 코드를 작성할 때에는 객체를 사용할 클래스에서 new 키워드 등으로 객체를 직접 생성합니다.
Java의 객체 생성과 조금 다르게, 객체를 사용할 클래스에서 객체가 필요하다면, 직접 생성하지 않고 Spring Container에게 객체를 만들어달라고 합니다. Spring Container에서는 객체(Bean)을 생성하고 관리하며, 의존성을 주입합니다.
객체 지향 다섯 가지 원칙인 SOLID에서 Java 객체 생성처럼 직접 객체를 생성하게 되면 OCP, DIP를 지키기 힘들다고 하였습니다. 그 이유는 객체끼리 의존성과 결합성이 높아지기 때문이었는데, Spring Container를 사용하면 그 자체에서 객체를 관리하기 때문에 인터페이스에만 의존하는 설계를 할 수 있게 됩니다.
BeanFactory, Application Context, MessageSource, EnvironmentCapable 등이 있는데, 크게 BeanFactory와 Application Context 이 둘을 중심으로 이야기 해보겠습니다.
Spring Conatiner의 최상위 인터페이스입니다. Spring Bean을 관리하고 조회하는 역할을 합니다.
BeanFactory의 확장된 형태 즉, implements한 형태입니다. 이 또한 인터페이스이며 Application 개발에 필요한 다양한 기능들을 BeanFactory에서 제공하는 것 이외(e.g. 국제화, 환경변수 분리, 이벤트, 리소스 조회 등)에도 추가적으로 제공합니다.
일반적으로는 ApplicationContext를 사용하기 때문에, 보통 ApplicationContext를 SpringContainer라고 표현하기도 합니다.
Spring Container가 관리하는 객체를 의미합니다. Java 객체와는 다르게, Spring이 이 객체를 관리하는 순간부터 Bean이 되고, Spring이 이를 생성, 초기화, 의존성 주입 등으로 관리합니다.
위에서 잠깐 이야기 했듯이, Java에서 new 키워드를 통해 만드는 것 대신 Spring Container가 만들어 주는 것입니다.
<beans>
<!-- myBean이라는 이름의 Bean 정의 -->
<bean id="myBean" class="com.example.MyBean" />
</beans>
public class MyApp {
public static void main(String[] args) {
// Spring 컨테이너에서 Bean을 가져옴
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyService myService = context.getBean("myService", MyService.class);
myService.doSomething();
}
}
@ComponentScan을 사용합니다.
// 이 클래스를 Bean으로 등록
// @Controller, @Service, @Repository
@Component
public class MyService {
public void doSomething() {
System.out.println("Spring Bean 으로 동작");
}
}
@Component
public class MyApp {
private final MyService myService;
@Autowired // 의존성 자동 주입
public MyApp(MyService myService) {
this.myService = myService;
}
public void run() {
myService.doSomething();
}
}
// com.example 패키지를 스캔하여 Bean 등록
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MyApp app = context.getBean(MyApp.class);
app.run();
}
}
사용한 annotation @ComponentScan은 추후에 따로 자세하게 다룰 예정입니다.
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
public class MyApp {
public static void main(String[] args) {
// Spring 컨테이너에서 Bean을 가져옴
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService = context.getBean(MyService.class);
myService.doSomething();
}
}
자료 및 코드 출처: 스파르타 코딩클럽