부스트코스 웹 프로그래밍 BE 영상을 보며 공부한 것을 간단히 정리한다.
1. Spring IoC / DI 컨테이너
컨테이너
- 컨테이너는 인스턴스의 생명주기를 관리한다.
- 또, 생성된 인스턴스에게 추가적인 기능을 제공한다.
- 예를 들어, 톰캣(WAS)는 Servlet 컨테이너를 통해 Servlet 요청을 해결한다.
IoC (Inversion of Contorl)
- 오브젝트의 제어권을 개발자의 코드가 아니라, 컨테이너가 가져가는 것을 의미한다.
- 즉, 개발자는 오브젝트를 직접 실행하는 것이 아니라, 컨테이너에게 요청하여 받아온다.
DI (Dependency Injection)
- 클래스 간의 의존 관계를 코드가 아닌, 컨테이너가 직접 주입해주는 것을 의미한다.
- 클래스 간의 의존 관계는 Bean 설정을 바탕으로 작성한다.
Spring
- 스프링은 이런 DI container 기반의 프레임워크다.
- 스프링에서는 다음과 같은 컨테이너를 제공한다.
- BeanFactory, ApplicationContext, ...
2. Bean
스프링의 DI 컨테이너를 통해 만들어낼 Java 클래스를 Bean 클래스라고 한다.
DI 컨테이너에 우리가 들 임의의 클래스를 등록하는 방법은 다음과 같다.
1) 먼저 임의의 클래스를 만들어 두자.
DI 컨테이너에 등록할 클래스는 다음 3가지 조건을 지켜야 한다.
- 기본 생성자가 있음.
- 필드는 private 함.
- getter, setter 를 가짐.
// UserBean.java
package kr.or.connect.diexam01;
public class UserBean {
// 필드는 private 하다.
private String name;
private int age;
private boolean male;
// 기본생성자를 가지고 있다.
public UserBean() {
}
public UserBean(String name, int age, boolean male) {
this.name = name;
this.age = age;
this.male = male;
}
// Getter 와 Setter 를 가지고 있어야 한다.
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
...
}
2) applicationContext.xml 에 클래스 등록
// resources/applicationContext.xml
// (resources 는 java 디렉토리와 같은 디렉토리에 있다.)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
// 바로 이 부분에 클래스를 Bean 클래스로 등록한다.
// 다만 이렇게할 시, 기본적으로 싱클톤 인스턴스로 등록됨.
<bean id="userBean" class="kr.or.connect.diexam01.UserBean"></bean>
</beans>
3) Spring framework 를 build 파일의 dependency 에 추가
// pom.xml
...
<dependencies>
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>
...
4) 등록된 Bean Class 사용하기
// ApplicationContextExam01.java
package kr.or.connect.diexam01;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ApplicationContextExam01 {
public static void main(String[] args) {
// ApplicationContext 라는 DI 컨테이너를 사용하여 초기화.
ApplicationContext ac = new ClassPathXmlApplicationContext(
"classpath:applicationContext.xml");
System.out.println("초기화 완료.");
// ApplicationContext 의 getBean("{bean id}") 으로 인스턴스 획득.
// 다만 이 때, getBean 은 기본적으로 Instance 오브젝트를 반환하므로 타입 변환 필요.
UserBean userBean = (UserBean)ac.getBean("userBean");
UserBean userBean2 = (UserBean)ac.getBean("userBean");
// 참고로 userBean 과 userBean2 는 같음. (싱글톤)
}
}
3. Bean property
Bean 에서 프로퍼티란 Setter, Getter 를 의미함.
(즉 메쏘드라고 안부르고, 프로퍼티라고 부름)
한 클래스 내에서 다른 클래스를 가져올 때(Set 할 때) 다음과 같이 Bean을 설정할 수 있음.
// Car 라는 클래스가 Engine 이라는 인스턴스를 내부 필드로 가지는 상황임.
// Car.java
package kr.or.connect.diexam01
public class Car {
Engine v8;
...
public void setEngine(Engine e) {
this.v8 = e;
}
...
}
이럴 때, applicationContext.xml
에 Bean 정보를 다음과 같이 바꿔주면 됨.
// resources/applicationContext.xml
...
<bean id="e" class="kr.or.connect.diexam01.Engine"></bean>
<bean id="car" class="kr.or.connect.diexam01.Car">
<property name="engine" ref="e"></property>
</bean>
이는 다음 코드와 같은 의미임
Engine e = new Engine();
Car c = new Car();
c.setEngine( e );
4. @Bean
을 이용하여 더 쉽게 Bean 설정하기
위의 방법은 새로운 클래스를 만들 때 마다, applicationContext.xml
에 추가해야하는 번거로움이 있음.
따라서, 더 쉬운 방법을 고안하게 되었는데 바로 Annotation(@
) 을 고려한 방법임.
1) Config 파일 설정
@Configuration
를 갖는 별도의 Config 클래스 선언하고,
이 안에 사용할 클래스들을 메쏘드로 초기화.
// ApplicationConfig.java
package kr.or.connect.diexam01;
import org.springframework.context.annotation.*;
@Configuration
public class ApplicationConfig {
@Bean
public Car car(Engine e) {
Car c = new Car();
c.setEngine(e);
return c;
}
// 중요한건, '메쏘드'로 정의한다는 것.
// 반환 타입이 해당 클래스의 이름이 됨.
@Bean
public Engine engine() {
return new Engine();
}
}
2) 등록된 Bean Class 사용하기
AnnotationConfigApplicationContext
를 사용하여 Config 파일을 읽어옴.
// ApplicationContextExam03.java
package kr.or.connect.diexam01;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class ApplicationContextExam03 {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(
ApplicationConfig.class);
// AnnotationConfigApplicationContext({Config 파일.class}) 를 사용하면,
// 해당 파일을 프로젝트 내에서 검색 후, 설정 파일을 읽어들임.
Car car = (Car)ac.getBean("car");
car.run();
}
}
5. @ComponentScan
을 통한 더더 쉬운 방법
1) Config 에 @ComponentScan
붙이기
이번엔 @ComponentScan
을 클래스 어노테이션으로 추가하여,
직접 직접 내부 메쏘드에 추가하지 않고, 해당 클래스를 서치하여 등록하는 방법.
// ApplicationConfig2.java
package kr.or.connect.diexam01;
import org.springframework.context.annotation.*;
@Configuration
@ComponentScan("kr.or.connect.diexam01")
public class ApplicationConfig2 {
}
@ComponentScan("패키지 명")
은 패키지 명
에 해당하는 패키지 내 @Component
가 붙어있는 클래스들을 모두 찾아, 메모리에 로드시킴.
이제 우리가 사용하려는 클래스에 @Component
를 붙여줘야함.
2) 사용할 클래스에 @Component
붙이기
// Engine.java
package kr.or.connect.diexam01;
import org.springframework.stereotype.Component;
@Component
public class Engine {
...
}
// Car.java
package kr.or.connect.diexam01;
import org.springframework.stereotype.Component;
@Component
public class Car {
...
}
3) 등록된 Bean Class 사용하기
// ApplicationContextExam04.java
package kr.or.connect.diexam01;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class ApplicationContextExam04 {
public static void main(String[] args) {
ApplicationContext ac = new AnnotationConfigApplicationContext(
ApplicationConfig2.class);
// AnnotationConfigApplicationContext 사용
Car car = ac.getBean(Car.class);
car.run();
}
}
'더 나은 엔지니어가 되기 위해 > 지금은 안쓰는 자바' 카테고리의 다른 글
[부스트코스 웹 프로그래밍] 인터셉터와 아규먼트 리졸버 (0) | 2020.01.24 |
---|---|
[부스트코스 웹 프로그래밍] 쿠키와 세션 (0) | 2020.01.24 |
[부스트코스 웹 프로그래밍] 스프링 MVC (2) | 2020.01.23 |
[부스트코스 웹 프로그래밍] 스프링 JDBC (1) | 2020.01.20 |
[부스트코스 웹 프로그래밍] 자바 웹 개발 기초 (0) | 2020.01.17 |