2장 스프링 특징과 의존성 주입
의존성 주입 (DI, Dependency Injection)
- 코드의 내부에서 객체간의 연결을 이루지 않고 외부에서 설정을 통해서 객체간을 연결하는 패턴
- 컴파일시가 아닌 실행시에 의존관계가 완성되는 방식
- 스프링은 의존성 주입을 쉽게 적용할 수 있는 프레임 워크
*Spring Beans Container - 자바 빈즈 객체를 보관하는 컨테이너!
(1) 의존성 주입 시그널을 받고
(2) 시그널대로 의존성 객체를 생성해서 의존하는 객체의 필드에 직접 주입(injection)해줌
위와 같이 의존성 객체들 간의 DI (의존성 주입)을 수행해주는 Beans Container의 구현객체의 타입이 정확히는 ApplicationContext임
* 스프링 의존성 주입은 아래 2가지 방법을 통해 주입된다.
1) 생성자를 통한 주입
2) Setter 메소드를 통한 주입
---
@ToString
@NoArgsConstructor
//@Component("chef")
public class Chef {
} // end class
chef.java
@ToString
@NoArgsConstructor // 모든 생성자는 명시적으로 보이게 하자 (기본 생성자는 안 만들어도 컴파일러가 자동으로 생성하지만 우리가 만들어주자)
//@Component("hotel")
// 관례에 따라 논리적인 이름은 타입명의 첫문자를 소문자로 한다
public class Hotel { // POJO : Plain Old Java Object
// @Resource(type=Chef.class)
// @Resource
// @Inject
// @Autowired
@Setter(onMethod_= { @Autowired })
private Chef chef;
} // end class
hotel.java
@ToString
@NoArgsConstructor
@Component("restaurant")
public class Restaurant {
// @Resource(type=Chef.class)
// @Resource
// @Inject
// @Autowired
// 아래 어노테이션의 의미 : 아래 필드에 대해, setter 메소드를 만들고 그 위에 지정된 어노테이션을 붙임
@Setter(onMethod_= { @Autowired }) // 이 필드에 대한 setter 메소드를 통한 의존성 주입 발생
private Chef chef;
// 생성자를 통한 주입
// @Autowired
// public Restaurant(Chef chef) {
// log.trace("constructor({}) invoked.", chef);
//
// this.chef = chef; // 초기화
// } // constructor
// setter 메소드를 통한 주입 (setter 메소드 직접 생성)
// @Autowired
// public void setChef(Chef chef) {
// log.trace("setChef({}) invoked.", chef);
//
// this.chef = chef; // 설정 (변경)
// } // setChef
} // end class
restaurant.java
<!-- 해당 패키지의 클래스들 싹 다 빈(Bean) 객체로 등록 -->
<!-- <context:component-scan base-package="org.zerock.myapp.domain" /> -->
<!-- <context:component-scan base-package="org.zerock.myapp.car" /> -->
<!-- 수동으로 등록 -->
<bean id="chef" class="org.zerock.myapp.domain.Chef"/>
<bean id="hotel" class="org.zerock.myapp.domain.Hotel"/>
<bean id="restaurant" class="org.zerock.myapp.domain.Restaurant"/>
<bean id="avanteCar" class="org.zerock.myapp.car.AvanteCar"/>
<bean id="handle" class="org.zerock.myapp.car.Handle"/>
<bean id="engine" class="org.zerock.myapp.car.Engine"/>
<bean id="tire" class="org.zerock.myapp.car.Tire"/>
root-context.xml
@NoArgsConstructor
// 테스트 메소드 수행시 스프링 프레임워크까지 함께 구동되도록 해주는 어노테이션 설정 추가
// For JUnit v4.x
//@RunWith(SpringRunner.class)
//@RunWith(SpringJUnit4ClassRunner.class)
// For JUnit v5.x
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations= {
// 필요한 스프링 설정파일을 등록해줌. 이때 file: 이 사용되는데
// 이 file: 의 의미는 프로젝트 폴더와 같음
"file:src/main/webapp/WEB-INF/spring/root-context.xml"
})
@TestInstance(Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class DITests {
// 이 JUnit 테스트 클래스도, JUnit test framework에 의해서 구동시 기본생성자를 이용하여 객체를 생성하고
// 이 객체는 자동으로 Spring Beans Container의 Bean으로 등록됨
// @Resource(type=Chef.class)
// @Resource
// @Inject
// @Autowired
@Autowired // 의존성 주입 시그널 정송 to Beans Container
private Restaurant restaurant;
@Autowired
private Hotel hotel;
@BeforeAll
void beforeAll() {
log.trace("beforeAll() invoked.");
assertNotNull(this.restaurant); // 방법1
// Objects.requireNonNull(this.restaurant); // 방법2
// assert this.restaurant != null; // 방법3
log.info("\t+ 1. this.restaurant: {}", restaurant);
// ---
assertNotNull(this.hotel); // 방법1
// Objects.requireNonNull(this.hotel); // 방법2
// assert this.hotel != null; // 방법3
log.info("\t+ 2. this.hotel: {}", hotel);
} // beforeAll
// @BeforeEach
//
// @Test
//
// @AfterEach
//
// @AfterAll
@Test
void dummyTest() {
;;
}
} // end class
DITests.java
DI 의존성 주입은 Spring Beans Container 안에서만 수행
따라서 의존성 주입을 받고 싶은 모든 객체는 Spring Beans Container에 Bean으로 등록되어 있어야함
---
chap 03
<!-- ================ 8. DataSource ================= -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.1</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
pom.xml
데이터 소스가 뭐에요? -> connection pool을 제공하는 객체의 규격
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<description>HikariCP Configuration</description>
<property name="driverClassName" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"/>
<!-- <property name="jdbcUrl" value="jdbc:log4jdbc:oracle:thin:@ㅇㅇㅇ/> -->
<property name="jdbcUrl" value="jdbc:log4jdbc:oracle:thin:@ㅇㅇㅇ"/>
<property name="username" value="HR"/>
<property name="password" value="비밀번호"/>
<property name="maximumPoolSize" value="10"/>
<property name="minimumIdle" value="2"/>
<property name="idleTimeout" value="10000"/>
<property name="connectionTimeout" value="3000"/>
<property name="connectionTestQuery" value="SELECT 1 FROM dual"/>
<property name="dataSourceJNDI" value="jdbc/HikariCP"/>
<property name="poolName" value="*** HikariDataSource ***"/>
</bean>
<bean id="hikariDataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<description>HikariCP DataSource</description>
<constructor-arg ref="hikariConfig"/>
</bean>
root-context.html
'국비학원' 카테고리의 다른 글
[국비지원] KH 정보교육원 97일차 (0) | 2022.08.16 |
---|---|
[국비지원] KH 정보교육원 96일차 (0) | 2022.08.12 |
[국비지원] KH 정보교육원 92-94일차 (0) | 2022.08.11 |
[국비지원] KH 정보교육원 91일차 (0) | 2022.08.11 |
[국비지원] KH 정보교육원 89-90일차 (MyBatis, 마이바티스) (0) | 2022.08.04 |