본문 바로가기
개발/spring, spring boot

[spring] 스프링 코어 - DI (Dependency Injection)

by 가시죠 2021. 1. 17.
반응형

spring framework

 

스프링 코어 - DI (Dependency Injection)

 

DI 가 필요한 이유

일정 규모 이상의 프로젝트 개발 시 다양한 컴포넌트를 조합하여 개발하는 것이 일반적이다. 예를 들면 공통 기능을 모아놓은 '공통 컴포넌트', 데이터 베이스에 접근하는 '데이터베이스 컴포넌트', 외부 시스템(레거시 시스템)에 접근하기 위한 '레거시 컴포넌트' 등 이 있을 수 있다. 또한 잘 만들어진 오픈소스 라이브러리를 조합하여 많이 사용하고 있다. 

 

컴포넌트간 연결 방법 및 DI 컨테이너를 이용한 방법

더보기

컴포넌트간 연결은 여러 방법이 있다. 가장 전통적인 방법은 직접 클래스에 선언 후 인스턴스를 생성하는 것이다.

위 처럼 생성하여 사용할 경우 클래스간 결합도가 높아진다. 만약 인스턴스 B의 클래스가 변경되면 호출되는 부분이 변경되어야 하며,  B 클래스가 미리 생성되어 있어야 생성 후 사용이 가능하다. 결합도를 낮추려면 생성자의 인수로 할당하는 방법 또는 더미(Dummy) 클래스로 대체하여 사용하는 경우도 있지만, B 클래스가 완성되면 결국엔 다시 인스턴스를 생성하여 사용하는 다른 클래스의 수정이 불가피 해진다.

DI 또는 IoC 는 소프트웨어 디자인 패턴 중 하나

DI 컨테이너를 사용하면 인스턴스를 애플리케이션에서 직접 생성하여 쓰는 결합도가 높은 위의 방식 대신 DI 컨테이너가 만들어주는 인스턴스를 가져오는 방법을 사용할 수 있다.

만약 인스턴스A를 다른 인스턴스가 사용할 경우 인스턴스B도 사용할 수 있게 된다.

이때 소유한 인스턴스가 의존하는 다른 인스턴스 역시 DI 컨테이너에서 관리되기 때문에 연쇄적으로 DI가 발생하여 연관된 클래스의 인스턴스 모두를 사용할 수 있게 된다.

컴포넌트간 연결은 여러 방법이 있다. 가장 전통적인 방법은 직접 클래스에 선언 후 인스턴스를 생성하는 것이다.

일반적인 애플리케이션에서의 의존 관계

위 처럼 생성하여 사용할 경우 클래스간 결합도가 높아진다. 만약 인스턴스 B의 클래스가 변경되면 호출되는 부분이 변경되어야 하며,  B 클래스가 미리 생성되어 있어야 생성 후 사용이 가능하다. 결합도를 낮추려면 생성자의 인수로 할당하는 방법 또는 더미(Dummy) 클래스로 대체하여 사용하는 경우도 있지만, B 클래스가 완성되면 결국엔 다시 인스턴스를 생성하여 사용하는 다른 클래스의 수정이 불가피 해진다.

DI 또는 IoC 는 소프트웨어 디자인 패턴 중 하나

DI 컨테이너를 사용하면 인스턴스를 애플리케이션에서 직접 생성하여 쓰는 결합도가 높은 위의 방식 대신 DI 컨테이너가 만들어주는 인스턴스를 가져오는 방법을 사용할 수 있다.

DI 컨테이너를 활용한 인스턴스 생성

만약 인스턴스A를 다른 인스턴스가 사용할 경우 인스턴스B도 사용할 수 있게 된다.

이때 소유한 인스턴스가 의존하는 다른 인스턴스 역시 DI 컨테이너에서 관리되기 때문에 연쇄적으로 DI가 발생하여 연관된 클래스의 인스턴스 모두를 사용할 수 있게 된다.

DI 컨테이너를 활용한 DI (의존성 주입)

 

스프링 프레임워크 빈(Bean) 설정 방식

스프링 프레임웍에서는 ApplicationContext가 DI 컨테이너 역할을 한다. 인스턴스는 Bean으로 정의하여 사용한다.

빈(Bean) 설정 방법은 3가지로 구분된다.

방법 설명
자바 기반 설정 방식 자바 클래스에 @Configuration 애너테이션을, 메서드에 @Bean 애너테이션을 사용하여 빈을 정의하는 방법으로 스프링부트에서 이 방식을 많이 활용한다.
XML 기반 설정 방식 XML 파일을 사용하는 방법으로 <bean>요소의 class 속성에 FQCN(Fully-Qualified Class Name)을 기술하면 빈이 정의된다. <constructor-arg>나 <property> 요소를 사용
애너테이션 기반 설정 방식 @Component 같은 마커 애너테이션(Marker Annotation)이 부여된 클래스를 탐색해서 DI 컨테이너에 빈을 자동으로 등록하여 사용

실제 업무에서는 2가지를 조합하여 많이 사용한다.

ex) "자바 기반+애너테이션 기반" 또는 "XML 기반+애너테이션 기반"

  • 애너테이션 기반 : 업무 비즈니스 로직 부분
  • 자바 기반, XML 기반 : 공통 성격의 비기능적인 부분으로 업무 로직과 분리

 

설정 방식 별 ApplicationContext를 생성하는 예제

// [자바 기반] 설정클래스(configuration class) AppConfig을 인자로 전달하고 DI 컨테이너 생성
ApplicationContext context = 
	new AnnotationConfigApplicationContext(AppConfig.class);

// [애너테이션 기반] AnnotationConfigApplicationContext의 생성자에 패키지명을 인자로 전달. 
//   지정된 패키지 이하의 경로에서 컴포넌트를 스캔
ApplicationContext context = 
	new AnnotationConfigApplicationContext("com.exam.app");

// [XML 기반] ClassPathXmlApplicationContext의 생성자에 XML 파일을 인자로 전달.
//   경로에 prefix가 생략된 경우 클래스패스 안에서 상대 경로로 설정 파일을 탐색
ApplicationContext context = 
	new ClassPathXmlApplicationContext("META-INF/spring/applicationContext.xml");

// [XML 기반] FileSystemXmlApplicationContext의 생성자에 xml 파일을 인자로 전달.
//    경로에 prefix가 생략된 경우 JVM의 작업 디렉터리안애서 상대 경로로 설정 파일을 탐색
ApplicationContext context = 
	new FileSystemXmlApplicationContext("./spring/applicationContext.xml");

 참고로 스프링 MVC에서는 ApplicationContext를 웹 환경에 맞게 확장된 WebApplicationContext를 사용한다.

 

설정 방식 별 빈(Bean) 등록

자바 기반 설정 방식 빈(Bean) 등록 예제

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 클래스에 @Configuration 애너테이션을 붙여 설정 클래스라고 선언. 설정 클래스는 여러개 지정 가능.
@Configuration
// 컴포넌트 스캔 범위 지정. 이 속성이 없을 경우 설정 클래스가 틀어있는 패키지 이하를 스캔한다.
@ComponentScan("com.exam.demo")
public class AppConfig {
    // 메소드에 @Bean 애너테이션을 붙여 빈을 정의
    // 메소드 명이 빈 이름이 되며, 이름을 바꾸고 싶을 경우 @Bean(name="xxRepo") 으로 지정한다.
    @Bean(name = "xxRepo")
    XXRepository xxRepository() {
        return new XXRepositoryImpl();
    }
    
    @Bean
    XXService xxService() {
        // 다른 컴포넌트를 참조할 경우..
        return new XXService(xxRepository());
    }
    
    // 다른 컴포넌트를 참조할 경우.. 메소드의 인자로 지정도 가능.
    @Bean
    XXService xxService(XXRepository xxRepository) {
        return new XXService(xxRepository);
    }
}

 

XML 기반 설정 방식 빈(Bean) 등록 예제

<?xml version="1.0" encoding="UTF-8"?>
<!-- <beans> 요소에 안에 빈 정의를 여러개 한다. -->
<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">
    <!-- id 속성에 지정한 값이 빈 이름이며, class 속성에 지정한 클래스를 적는다. 
        class는 FQCN으로 패키지명부터 클래스 명까지 정확하게 적어야 한다. -->
    <bean id="xxReposition" class="com.example.demo.XXRepositoryImpl"/>
    
    <!-- constructor-arg에 생성자를 활용한 의존성을 주입한다. ref 속성에 주입할 빈의 이름을 적는다. -->
    <bean id="xxService" class="com.example.demo.XXService">
        <constructor-arg ref="xxReposition"/>
    </bean>
    
    <!-- 생성자에 특정 값을 주입할 경우 -->
    <!--
    <constructor-arg value="tistory.com"/>
    -->
    
    <!-- 컴포넌트 스캔 범위 지정 -->
    <context:component-scan base-package="com.exam.demo" />
</beans>

 

애너테이션 기반 설정 방식 빈(Bean) 등록 예제

import org.springframework.stereotype.Component;

// 빈(Bean) 클래스에 @Component 애너테이션을 붙인다.
@Component
public class XXRepositoryImpl implements XXRepository {
    // 생략
}
import com.example.demo.XXRepositoryImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

// 빈(Bean) 클래스에 @Component 애너테이션을 붙인다.
@Component
public class XXService {

    // 생성자를 통해서 의존성을 주입할 수 도 있지만, 
    // 클래스를 선언하여 @Autowired 애너테이션을 붙여서 사용도 가능하다.
    @Autowired
    YYRepository yyRepository;

    // 생성자에 @Autowired 애너테이션을 붙여 오토와이어링 되도록 함.
    @Autowired
    public XXService(XXRepositoryImpl xxRepository) {

    }
    
    // 애너테이션 방식의 의존성 주입은 @Autowired, @Resource, @Inject로 사용 가능
}

 

의존성 주입

의존성 주입에서 3가지 방법이 있다.

  1. 설정자 기반 의존성 주입 : setter메소드를 통해 의존성을 주입하는 방식
  2. 생성자 기반 의존성 주입 : 생성자메소드를 사용해 의존성을 주입하는 방식
  3. 필드 기반의 의존성 주입 : setter나 생성자 메소드를 사용하지 않고, 필드에 직접 선언하여 사용 (소스가 깔끔하고 생성자나 설정자 (Setter)메소드가 필요 없기 때문에 실무에서 가장 많이 사용)

 

애너테이션 기반 설정 방식의 의존 주입의 다양한 방법

A 클래스에서 B클래스를 사용해야 할 경우 의존성 주입하여 사용할 수 있는데, 방법은 3가지 애너테이션으로 사용한다.

  • @Autowired : 스프링 프레임워크에서 지원하는 애너테이션
  • @Resource : 자바에서 지원하는 애너테이션
  • @Inject : 자바에서 지원하는 애너테이션

실무에서는 @Resource나 @Inject를 가장 많이 사용한다. (자바표준 애너테이션이기 때문에..)

 

컴포넌트 스캔

컴포넌트 스캔은 클래스 로더를 스캔하면서 특정 클래스를 찾은 다음, DI 컨테이너에 등록하는 방법

탐색 대상이 되는 기본 애너테이션

  • @Component (org.springframework.stereotype.Component)
  • @Controller (org.springframework.stereotype.Controller)
  • @Service (org.springframework.stereotype.Service)
  • @Repository (org.springframework.stereotype.Repository)
  • @Configuration (org.springframework.context.annotation.Configuration)
  • @RestController (org.springframework.web.bind.annotation.RestController)
  • @ControllerAdvice (org.springframework.web.bind.annotation.ControllerAdvice)
  • @ManagedBean (javax.annotation.ManagedBean)
  • @Named (javax.inject.Named)

대표적인 스캔 대상 애너테이션

애너테이션 설명
@Controller MVC 패턴에서의 C, 컨트롤러역할을 하는 컴포넌트에 붙인다. 클라이언트 요청을 받고 비즈니스 로직 처리 결과를 응답으로 보내는 기능을 한다. 비즈니스 로직은 @Service 가 붙은 컴포넌트가 처리하도록 한다.
@Service 비즈니스 로직을 처리하는 컴포넌트에 붙인다. 컨트롤러에서 받은 입력 데이터로 로직을 실행한다. 영속적으로 보관해야 하는 데이터가 있다면 @Reposition가 붙은 컴포넌트에서 처리하도록 한다.
@Reposition 영속적인 데이터 처리를 수행하는 컴포넌트에 붙인다. ORM (Object-Relational Mapping) 관련 라이브러리를 활용해 데이터의 CRUD (Create, Read, Update, Delete)를 처리하도록 한다.
@Component 위의 세 경우에 해당되지 않는 컴포넌트 (유틸이나 지원 클래스 등)에 붙인다.

 컴포넌트 스캔에 필터를 적용 하여 다른 컴포넌트나 스캔 범위를 커스터 마이징 할 수도 있다. (많이 사용되지 않으므로 필요시 다시 찾아보자.)

자바 기반 컴포넌트 스캔 예제

@Configuration
// 컴포넌트 스캔 범위 지정. 이 속성이 없을 경우 설정 클래스가 틀어있는 패키지 이하를 스캔한다.
@ComponentScan("com.exam.demo")
public class AppConfig {
    
    @Bean(name = "xxRepo")
    XXRepository xxRepository() {
        return new XXRepositoryImpl();
    }
}

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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="xxReposition" class="com.example.demo.XXRepositoryImpl"/>
    <bean id="xxService" class="com.example.demo.XXService">
        <constructor-arg ref="xxReposition"/>
    </bean>
    <!-- 컴포넌트 스캔 범위 지정 -->
    <context:component-scan base-package="com.exam.demo" />
</beans>

 

빈 스코프(bean scope)

빈의 생존 기간을 빈 스코프라고 하며, DI 컨테이너가 알아서 관리 해주며 기본적으로 싱글톤으로 만들어진다.

사용 가능한 빈 스코프

스코프 설명
singleton DI 컨테이너를 기동할 때 인스턴스 하나가 만들어지고, 이후부터 그 인스턴스를 공유하는 방식. 기본값
prototype DI 컨테이너에 빈을 요청할 때마다 새로운 인스턴스가 만들어진다. 멀티 스레드 환경에서 오동작이 발생하지 않아야 하는 빈일 경우 사용.
request HTTP 요청이 들어올때마다 인스턴스가 만들어지며, 웹 애플리케이션에서만 사용가능
session HTTP 세션이 만들어질때마다 인스턴스가 만들어지며, 웹 애플리케이션에서만 사용가능
global session 포틀릿 환경에서 글로벌 HTTP 세션이 만들어질때마다 인스턴스가 생성되며 포틀릿을 사용한 웹 애플리케이션에서만 사용가능
application 서블릿 컨텍스트가 만들어질때마다 인스턴스가 만들어지며, 웹 애플리케이션에서만 사용가능
custom 스코프 이름과 규칙을 직접 만들어 사용

※ singleton, prototype가 가장 많이 활용된다.

 

자바기반 설정예제

@Bean
@Scope("prototype") // 스코프를 prototype로 설정
XXService xxService() {
    return new XXServiceImpl();
}
XXService xxService1 = context.getBean(XXService.class);
XXService xxService2 = context.getBean(XXService.class);

// XXService 빈 스코프를 prototype로 설정했기 때문에 xxService1과 xxService2는 
// 서로 다른 인스턴스가 된다.

 

XML 기반 설정예제

<bean id="xxService" class="com.exam.demo.XXServiceImpl" scope="prototype" />

 

애너테이션 기반 설정예제

@Component
@Scope("prototype")
public Class XXServiceImpl implements xxService {
    // 생략
}

 

 서로 다른 스코프를 가진 빈 간의 의존 관계가 존재할 경우 자신의 스코프에 상관없이 주입받는 빈의 스코프를 따른다. singleton 빈 A에 prototype빈 B를 Autowired 하여 사용할 경우 B 빈은 singleton 스코프가 된다.

이럴 경우 룩업 메서드 인젝션 또는 스코프트 프락시로 해결이 가능하다.

애너테이션 설정 기반의 룩업 메서드 예제

// XXService는 singleton
// XX YYUtil은 prototype

@Component
public class XXServiceImpl implements XXService {
	public void someThing() {
    	YYUtil yyUtil = yyUtil();  // prototype 스코프로 가져옴
        yyUtil.testFunc();
    }
}

@Lookup
YYUtil yyUtil() {
	return null;  // 반환값은 널로 해도 됨.
}

 

XML 설정 기반의 룩업 메서드 예제

<bean id="yyUtil" class="com.exam.demo.YYUtil" scope="prototype" />

<bean id="xxService" class="com.exam.demo.XXSerivce">
	<!-- name에 룩업 메소드명, bean에 룩업할 빈의 이름을 입력 -->
	<lookup-method name="yyUtil" bean="yyUtil" />
</bean>

 

자바 설정 기반의 스코프트 프락시 예제

@Bean
@Scope(value="request", proxyMode = ScopeProxyMode.INTERFACES)
YYUtil yyUtil() {
	return new YYUtil();
}

 

xml 설정 기반의 스코프트 프락시 예제

<bean id="yyUtil" class="com.exam.demo.YYUtil" scope="request">
	<!-- proxy-target-class = false : 인터페이스 기반,  true : 서브 클래스 기반 -->
	<aop:scoped-proxy proxy-target-class="true || false">
</bean>

<bean id="XXService" class="com.exam.demo.XXService">
	<property name="yyUtil" ref="yyUtil" />
</bean>

 

애너테이션 설정 기반의 스코프트 프락시 예제

@Component
@Scope(value="request", proxyMode = ScopedProxyMode.INTERFACES)
public class yyUtil {

}

 

빈의 생명주기

초기화 단계 (initialization) > 빈 사용 단계 (activation) > 빈 종료 단계 (destruction)

  1. 초기화 단계 (initialization) : 빈 설정 읽기 및 보완 > 빈 생성 및 의존 관계 해결 > 빈 생성 후 초기화 작업
  2. 빈 사용 단계 (activation) : 애플리케이션에서 사용됨...
  3. 빈 종료 단계 (destruction) : 종료 전 전처리 수행 > 빈 종료

xml설정 기반 초기화 및 종료 시 호출될 메소드 예제

...
<bean id="testBean" class="com.tistory.kisspa.TestBean" 
	init-method="initMethod" 
	destroy-method="destroyMethod"/> <!-- 생성, 소멸시 실행될 메서드 지정 -->
...

TestBean에 initMethod, destroyMethod 메소드를 정의하면 생성, 소멸 시 실행된다.

 

자바설정 기반 초기화 및 종료 시 호출될 메소드 예제

class TestBesn implements InitializingBean, DisposableBean { 
	public void test() {
    	System.out.println("Test"); 
    } 
    
    @Override public void afterPropertiesSet() throws Exception { 
    	System.out.println("testBean Instance is created"); 
    } 
    
    @Override public void destroy() throws Exception { 
    	System.out.println("testBean Instance is destroyed"); 
    } 
}

 

애너테이션 기반 초기화 및 종료 시 호출될 메소드 예제

@PostConstruct
public void postConstruct(){
    System.out.println("construct");
}

@PreDestroy
public void preDestroy(){
    System.out.println("destroying");
}

 

빈 설정 분할

빈이 많을 경우 빈 등록 설정 파일을 분리하여 목적에 맞게 관리하면 좋다.

자바설정 기반의 빈 분할 예제

@Configuration
// 대표 Config에 @Import를 붙이고 인자값으로 분할된 설정 파일들을 기술한다.
// CommonConfig와 ProcessConfig에 정의한 빈을 주입할 수 있다.
@Import({CommonConfig.class, ProcessConfig.class})
public class AppConfig {
	// 생략
}
@Configuration
public class CommonConfig {
    @Bean
    ...
}
@Configuration
public class ProcessConfig {
    @Bean
    ...
}

 

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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <import resource="classpath:conf/common-config.xml" />
    <import resource="classpath:conf/process-config.xml" />

    <!-- common-config와 process-config에 정의한 빈을 참조 할 수 있다. -->

</beans>
<?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 id="XXUtil" class="com.example.demo.XXUtil"/>
    ...
</beans>
<?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 id="XXService" class="com.example.demo.XXService"/>
    ...
</beans>

 

프로파일 별 설정

빈 정의를 할때 프로파일(ex. 개발 환경, 스테이징 환경, 운영 환경) 별로 따로 구성할때는 @Profile 애너테이션을 사용한다. 가령 특정 메소드가 개발서버와 운영서버에서 다르게 동작해야 할 경우 사용하면 된다.

자바 설정 기반의 프로파일 정의 예제

@Configuration
@Profile("development")
public class DevelopmentConfig {
    // 개발서버
    @Bean
    ....
}

@Configuration
@Profile("staging")
public class StagingConfig {
    // 스테이징서버
    @Bean
    ....
}

@Configuration
@Profile("production")
public class ProductionConfig {
    // 운영서버
    @Bean
    ....
}

자바 설정 기반의 메소드별 프로파일 정의 예제

@Configuration
public class AppConfig {
    @Bean(name = "dataSource")
    @Profile("development")
    DataSource dataSourceDev() {
        //....
    }
    
    @Bean(name="dataSource")
    @Profile("staging")
    DataSource dataSourceStage() {
        //....
    }
    
    @Bean(name = "dataSource")
    @Profile("production")
    DataSource dataSourceProd() {
        //....
    }
}

 

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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd"
    profile="staging">  <!-- 최상의 beans에 profile을 정의하였으며, 아래에 정의한 bean은 staging에서만 동작 -->
    <bean id="xxServiee" class="com.example.demo.XXService"/>
</beans>

※ beans 태그 안에 여러개의 beans를 지정할 수도 있다.

<?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">
    
    <beans profile="development">
        <!-- 개발환경에서만 동작 -->
        ...
    </beans>
    
    <beans profile="staging">
        <!-- 스테이징 환경에서만 동작 -->
        ...
    </beans>
    
    <beans profile="production">
        <!-- 운영환경에서만 동작 -->
        ...
    </beans>
</beans>

 

애너테이션 설정 기반의 프로파일 정의 예제

@Component
@Profile("development")
public class XXServiceForDev implements XXSerivce {
    ...
}

 

애플리케이션 실행 시 프로파일 선택

자바 명령행 옵션으로 지정 (가장 많이 사용)

-Dspring.profiles.active=production

환경변수로 지정

export SPRING_PROFILE_ACTIVE=production

web.xml에 프로파일로 지정

<context-param>
    <param-name>spring.profiles.active</param-name>
    <param-value>production</param-value>
</context-param>

 

 

요약

  • 스프링 DI를 사용하면 클래스간 인스턴스를 알아서 관리해준다.
  • 설정방법은 3가지로 자바기반, XML기반, 애너테이션 기반으로 나뉘며, 2가지를 조합하여 많이 사용한다.
  • 의존성 주입 시 setter메소드, 생성자, 필드기반이 있는데 소스가 깔끔한 필드 기반을 많이 사용한다.
  • 빈으로 등록된 컴포넌트 사용 시 @Autowired, @Resource, @Inject 애너테이션을 사용한다.
  • 컴포넌트 스캔으로 패키지를 위치를 지정한다.
  • 빈 스코프는 잘 지정해서 사용해야 한다.
  • 빈 설정 파일은 여러개로 그룹화 하여 사용할 수도 있다.
  • 프로파일별로 구분하여 사용할 수도 있다.

 

반응형

댓글