스프링 코어 - DI (Dependency Injection)
DI 가 필요한 이유
일정 규모 이상의 프로젝트 개발 시 다양한 컴포넌트를 조합하여 개발하는 것이 일반적이다. 예를 들면 공통 기능을 모아놓은 '공통 컴포넌트', 데이터 베이스에 접근하는 '데이터베이스 컴포넌트', 외부 시스템(레거시 시스템)에 접근하기 위한 '레거시 컴포넌트' 등 이 있을 수 있다. 또한 잘 만들어진 오픈소스 라이브러리를 조합하여 많이 사용하고 있다.
컴포넌트간 연결 방법 및 DI 컨테이너를 이용한 방법
컴포넌트간 연결은 여러 방법이 있다. 가장 전통적인 방법은 직접 클래스에 선언 후 인스턴스를 생성하는 것이다.
위 처럼 생성하여 사용할 경우 클래스간 결합도가 높아진다. 만약 인스턴스 B의 클래스가 변경되면 호출되는 부분이 변경되어야 하며, B 클래스가 미리 생성되어 있어야 생성 후 사용이 가능하다. 결합도를 낮추려면 생성자의 인수로 할당하는 방법 또는 더미(Dummy) 클래스로 대체하여 사용하는 경우도 있지만, B 클래스가 완성되면 결국엔 다시 인스턴스를 생성하여 사용하는 다른 클래스의 수정이 불가피 해진다.
DI 또는 IoC 는 소프트웨어 디자인 패턴 중 하나
DI 컨테이너를 사용하면 인스턴스를 애플리케이션에서 직접 생성하여 쓰는 결합도가 높은 위의 방식 대신 DI 컨테이너가 만들어주는 인스턴스를 가져오는 방법을 사용할 수 있다.
만약 인스턴스A를 다른 인스턴스가 사용할 경우 인스턴스B도 사용할 수 있게 된다.
이때 소유한 인스턴스가 의존하는 다른 인스턴스 역시 DI 컨테이너에서 관리되기 때문에 연쇄적으로 DI가 발생하여 연관된 클래스의 인스턴스 모두를 사용할 수 있게 된다.
컴포넌트간 연결은 여러 방법이 있다. 가장 전통적인 방법은 직접 클래스에 선언 후 인스턴스를 생성하는 것이다.
![](https://blog.kakaocdn.net/dn/beIgS6/btqTNzuEc3Z/nA3J1wE5XY6CjbNOJ8X7X1/img.png)
위 처럼 생성하여 사용할 경우 클래스간 결합도가 높아진다. 만약 인스턴스 B의 클래스가 변경되면 호출되는 부분이 변경되어야 하며, B 클래스가 미리 생성되어 있어야 생성 후 사용이 가능하다. 결합도를 낮추려면 생성자의 인수로 할당하는 방법 또는 더미(Dummy) 클래스로 대체하여 사용하는 경우도 있지만, B 클래스가 완성되면 결국엔 다시 인스턴스를 생성하여 사용하는 다른 클래스의 수정이 불가피 해진다.
DI 또는 IoC 는 소프트웨어 디자인 패턴 중 하나
DI 컨테이너를 사용하면 인스턴스를 애플리케이션에서 직접 생성하여 쓰는 결합도가 높은 위의 방식 대신 DI 컨테이너가 만들어주는 인스턴스를 가져오는 방법을 사용할 수 있다.
![](https://blog.kakaocdn.net/dn/535iV/btqTENuGnzT/kYcTkZ5JGigXK2dyieR26k/img.png)
만약 인스턴스A를 다른 인스턴스가 사용할 경우 인스턴스B도 사용할 수 있게 된다.
이때 소유한 인스턴스가 의존하는 다른 인스턴스 역시 DI 컨테이너에서 관리되기 때문에 연쇄적으로 DI가 발생하여 연관된 클래스의 인스턴스 모두를 사용할 수 있게 된다.
![](https://blog.kakaocdn.net/dn/c6KPrb/btqTKMH0bgJ/KaKYECEY875GgALIakCpW0/img.png)
스프링 프레임워크 빈(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가지 방법이 있다.
- 설정자 기반 의존성 주입 : setter메소드를 통해 의존성을 주입하는 방식
- 생성자 기반 의존성 주입 : 생성자메소드를 사용해 의존성을 주입하는 방식
- 필드 기반의 의존성 주입 : 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)
- 초기화 단계 (initialization) : 빈 설정 읽기 및 보완 > 빈 생성 및 의존 관계 해결 > 빈 생성 후 초기화 작업
- 빈 사용 단계 (activation) : 애플리케이션에서 사용됨...
- 빈 종료 단계 (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 애너테이션을 사용한다.
- 컴포넌트 스캔으로 패키지를 위치를 지정한다.
- 빈 스코프는 잘 지정해서 사용해야 한다.
- 빈 설정 파일은 여러개로 그룹화 하여 사용할 수도 있다.
- 프로파일별로 구분하여 사용할 수도 있다.
'개발 > spring, spring boot' 카테고리의 다른 글
[spring 에러] slf4j failed to load class org.slf4j.impl.staticloggerbinder (2) | 2021.01.17 |
---|---|
[spring 에러] 일치하는 와일드 카드 문자가 엄격하게 적용되지만 ... 요소에 대한 선언을 찾을 수 없습니다. (0) | 2021.01.17 |
[spring] Environment - 프로필(profile) (0) | 2021.01.17 |
[spring] Environment - PropertySource (0) | 2021.01.17 |
[spring] 스프링 코어 - AOP (Aspect Oriented Programming) (0) | 2021.01.17 |
댓글