본문 바로가기
Java & Kotlin/Spring

[Spring] 기본 어노테이션, Lombok을 이용한 의존성 주입

by heekng 2021. 5. 9.
반응형

[Spring] 기본 어노테이션, Lombok을 이용한 의존성 주입


스프링 프로젝트 기본 구성 요소

 

src/main/java : 작성되는 코드의 경로

src/main/resources : 실행할 때 참고하는 기본 경로

src/test/java : 테스트 코드를 넣는 경로

src/test/resources : 테스트 관련 설정 파일 보관 경로

 

웹과 관련된 스프링 설정 파일(View Resolver)

src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml

 

스프링 설정 파일(Bean, IoC 컨테이너)

src/main/webapp/WEB-INF/spring/root-context.xml

 

Tomcat의 web.xml파일(Front Controller, DispatcherServlet)

src/main/webapp/WEB-INF/web.xml

 

템플릿 프로젝트의 jsp파일 경로

src/main/webapp/WEB-INF/views

 

Maven이 사용하는 pom.xml

[project]/pom.xml


의존성 주입 테스트

의존성 주입을 위한 객체는 src/main/java에 생성한다.

package com.heekng.sample;

import org.springframework.stereotype.Component;

import lombok.Data;

@Component //스프링에게 현재 이 클래스가 스프링에서 관리해야 하는 대상임을 표시한다.
@Data //Lombok을 이용해 getter, setter, toString, 생성자를 자동 생성하게 한다.
public class Person {
	
}

 

package com.heekng.sample;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import lombok.Data;
import lombok.Setter;

@Component //스프링에게 현재 이 클래스가 스프링에서 관리해야 하는 대상임을 표시한다.
@Data //Lombok을 이용해 getter, setter, toString, 생성자를 자동 생성하게 한다.
public class Home1 {
	/*
	 * setter어노테이션을 통해 해당 객체에 setter메소드를 주입시킨다.
	 * setter어노테이션을 이요하므로 new를 대체한다.
	 * onMethod속성은 생성되는 setPerson에 @Autowired 어노테이션을 추가하도록 할 때 사용한다.
	 * 버전에 따라 onMethod 혹은 onMethod_를 사용하게 된다.
	 */
	@Setter(onMethod_ = @Autowired)
	private Person person;
}

 

package com.heekng.sample;

import org.springframework.stereotype.Component;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;

@Component //스프링에게 현재 이 클래스가 스프링에서 관리해야 하는 대상임을 표시한다.
@Getter //@data를 이용하지 않고 getter와 setter만을 생성하게 지정할 수 있다.
@ToString
@AllArgsConstructor //인스턴스 변수로 선언된 모든 것을 파라미터로 받는 생성자를 작성한다.
public class Home2 {
	private Person person;
}

 

package com.heekng.sample;

import org.springframework.stereotype.Component;

import lombok.Data;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

@Component
@Data
@RequiredArgsConstructor //특정 변수에 대해서만 생성자를 작성할 때 작성한다.
//@NonNull이나 final이 붙은 인스턴스 변수에 대한 생성자를 만들어낸다.
public class Home3 {
	@NonNull
	private Person person;
}

 

위처럼 Person클래스를 생성하고, Person객체를 필드로 가지고 있는 Home클래스를 3가지 만들었다.

@Component : 스프링에게 현재 이 클래스가 스프링에서 관리해야 하는 대상임을 표시한다.

@Data : Lombok라이브러리를 이용하여 getter, setter, toString, 생성자를 자동으로 생성하게 한다.

@Getter, @Setter, @ToString... : @Data어노테이션은 모든 항목을 자동 생성하나 모든 것이 필요하지 않을 때 특정 어노테이션만 작성하여 선택적으로 생성하게 한다.

@AllArgsConstructor : 인스턴스 변수로 선언된 모든 것을 파라미터로 받는 생성자를 작성한다.

@RequiredArgsConstructor : 특정 변수에 대해서만 생성자를 작성할 때 작성한다.

@NonNull 어노테이션을 할당하거나, final 키워드가 붙은 인스턴스 변수에 대한 생성자를 만든다.

@AllArgsConstructor 어노테이션이 필드의 모든 인스턴스 변수에 생성자를 작성한다면, @RequiredArgsConstructor 어노테이션은 선택적으로 생성자를 작성하게 지정할 수 있다.

root-context.xml > namespaces탭 > context 체크

**Namespaces와 같이 하단 탭이 보이지 않는다면 root-context.xml 우클릭 > openwith > Spring config editor로 root-context.xml을 열어준다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
	
	<!-- Root Context: defines shared resources visible to all other web components -->
		
	<context:component-scan base-package="com.heekng.sample"></context:component-scan>
</beans>

하단 Source탭에서 <context:component-scan base-package="com.heekng.sample"></context:component-scan> 작성하여 해당 경로의 객체들을 스프링에서 스캔할 수 있도록 설정한다.

이후 Beans Graph탭을 확인하면 해당 클래스들이 올라가 있는 것을 확인할 수 있고, .java파일에 S표시가 생긴 것을 확인할 수 있다.

테스트 서버 설정 / 테스트

<!-- Test -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-test</artifactId>
	<version>5.1.1.RELEASE</version>
</dependency>
<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.12</version>
	<scope>test</scope>
</dependency>

pom.xml에서 <dependencies>태그 속 하단에 <!-- Test -->주석 하단에 spring-test관련 코드 작성, junit의 버전을 4.12로 올린다.

이후 프로젝트 업데이트

src/test/java의 테스트 서버에서 패키지 생성 후

package com.heekng.sample;

import static org.junit.Assert.assertNotNull;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import lombok.Setter;
import lombok.extern.log4j.Log4j;

@RunWith(SpringJUnit4ClassRunner.class) //테스트 코드가 스프링을 실행하게 한다.
//지정된 클래스나 문자열을 이용해서 필요한 객체들을 스프링 내에 객체로 등록한다.
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j //로그 출력을 위한 어노테이션
public class HomeTest {
	@Setter(onMethod_ = @Autowired)
	private Home2 home2;
	
	@Test
	public void test() {
		assertNotNull(home2); //객체가 null인지 아닌지 확인
		
		log.info(home2);
		log.info("===============");
		log.info(home2.getPerson());
	}
}

 

위와 같이 테스트를 시도할 코드를 작성 > run > JUnit 선택

정상출력 확인


스프링 프레임워크 동작 시 생기는 일

1. 스프링 프레임워크가 시작되면 먼저 스프링이 사용하는 메모리 영역을 만든다 -> Context

2. 스프링은 자신이 객체를 생성하고 관리해야 하는 객체들에 대한 설정이 필요하다. 이 설정파일 -> root-context.xml

3. root-context.xml에 설정되어 있는 <context:component-scan>태그의 내용을 통해서 지정한 패키지를 스캔하기 시작한다.

4. 해당 패키지에 있는 클래스들 중에서 스프링이 사용하는 @Component라는 어노테이션이 존재하는 클래스의 인스턴스를 생성한다

5. A객체에 B객체가 필요하다는 어노테이션(@Autowired)설정이 있다면 B객체의 래퍼런스를 A객체에 주입한다.

반응형