Dependency Injection

2024. 6. 11. 17:28Spring Framework/Spring IoC

의존성 주입(DI) 은 객체가 자신이 필요로 하는 의존성(즉, 함께 동작할 다른 객체들)을 다음과 같은 방식으로만 정의하는 과정입니다:

  • 생성자 아규먼트(Constructor arguments)
  • 팩토리 메서드의 아규먼트(Factory method arguments)
  • 객체가 생성된 후 설정되는 프로퍼티(Properties)

이후 Spring IoC 컨테이너는 해당 빈(Bean)을 생성할 때 이 의존성들을 주입(inject)합니다.

이러한 과정은 본질적으로 역제어(Inversion of Control, IoC) 의 개념을 따릅니다.

  • 이름 그대로, 의존성의 생성이나 위치를 스스로 제어하는 것이 아니라, 컨테이너가 대신 제어하게 되는 구조입니다.
  • 예전에는 객체가 필요한 의존성을 직접 생성하거나, Service Locator 패턴을 이용해 직접 위치를 찾아야 했지만, DI는 이를 반대로 뒤집어 컨테이너가 주입해주는 방식입니다.

✅ DI 원칙의 효과

  • DI 원칙을 적용하면 코드가 더 깔끔해지고, 결합도가 낮아집니다.
  • 객체는 의존성을 직접 찾지 않으며, 의존성의 위치나 클래스에 대해 알 필요도 없습니다.
  • 그 결과:
    • 클래스가 더 테스트하기 쉬워집니다.
    • 특히 의존성이 인터페이스나 추상 클래스에 기반할 경우, 테스트 시 Stub 또는 Mock 구현체를 사용하기가 용이합니다.

✅ DI의 주요 두 가지 방식

  1. 생성자 기반 의존성 주입(Constructor-based Dependency Injection)
  2. 세터 기반 의존성 주입(Setter-based Dependency Injection)

 

✅ Constructor-based Dependency Injection

생성자 기반 DI(Constructor-based DI) 는 컨테이너가 여러 개의 아규먼트를 가진 생성자를 호출하여 의존성을 주입하는 방식입니다. 여기서 각 아규먼트는 하나의 의존성을 나타냅니다.

특정 아규먼트를 전달하여 정적 팩토리 메서드(static factory method) 를 호출해 빈(Bean)을 생성하는 것도 거의 동일한 방식으로 취급됩니다. 따라서, 이 설명에서는 생성자 아규먼트와 정적 팩토리 메서드 아규먼트를 동일하게 다룹니다.

다음 예제는 오직 생성자 주입을 통해서만 의존성을 주입받는 클래스를 보여줍니다.

public class SimpleMovieLister {

	// the SimpleMovieLister has a dependency on a MovieFinder
	private final MovieFinder movieFinder;

	// a constructor so that the Spring container can inject a MovieFinder
	public SimpleMovieLister(MovieFinder movieFinder) {
		this.movieFinder = movieFinder;
	}

	// business logic that actually uses the injected MovieFinder is omitted...
}
  • 이 클래스에는 특별한 점이 없습니다.
  • POJO (Plain Old Java Object) 이며,
  • Spring 컨테이너에 특화된 인터페이스, 부모 클래스, 애노테이션 등에 전혀 의존하지 않습니다.

 

✅ Constructor-based Dependency Injection 장단점

구분 내용
장점
필수 의존성 보장 생성자 호출 시점에 모든 필수 의존성이 주입되므로, 주입 누락 시 컴파일 오류(또는 초기화 오류)로 바로 확인 가능
불변성(Immutable) 보장 final 필드와 함께 사용하면, 객체가 생성된 이후 의존성이 변경될 수 없도록 강제 가능
테스트 용이성 외부에서 의존성을 주입하기 때문에 테스트 시 Mock, Stub 주입이 간편
명확한 의존성 표현 클래스가 어떤 의존성을 필요로 하는지 생성자 시그니처만 봐도 알 수 있음
순환 참조 조기 감지 컨테이너가 인스턴스화 시점에 순환 참조를 빠르게 감지하고 예외 발생
단점
의존성 수 증가 시 가독성 저하 의존성이 많아지면 생성자 아규먼트가 많아져 코드 가독성이 나빠짐 (Bad Smell: 클래스가 너무 많은 책임을 가짐)
순환 참조 대응 어려움 순환 참조 상황에서 생성자 기반 DI는 해결이 불가능 (Setter-based DI로 우회해야 함)
선택적 의존성 대응 불편 선택적 의존성을 주입받기 어렵고, 기본값을 주는 등의 처리가 번거로움
 

✅ Spring의 Constructor-based DI 과정 흐름도

🔍 핵심 요점:

단계 설명
[1] XML, Java Config, @Component 등으로 빈 정의
[2] 내부적으로 BeanDefinition 생성 (빈의 설계도 역할)
[3] ApplicationContext 초기화
[4] Constructor Injection 수행 (필수 의존성 모두 주입)
[5] Bean 인스턴스화 완료
[6] 초기화 콜백(@PostConstruct 등)
[7] 클라이언트가 빈을 주입받아 사용

 

✅ Constructor Argument Resolution

교재의 설명은 XML 기반 구성 메타데이터에 관한 것이기 때문에,

자바 또는 어노테이션 기반 구성 메타데이터에서는 해당 사항이 없습니다.

그러므로 어노테이션 기반 구성 메타데이터 예제로 대체하겠습니다.

package x.y;

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

@Configuration
public class AppConfig {

    @Bean
    public ThingTwo beanTwo() {
        return new ThingTwo();
    }

    @Bean
    public ThingThree beanThree() {
        return new ThingThree();
    }

    @Bean
    public ThingOne beanOne(ThingTwo beanTwo, ThingThree beanThree) {
        return new ThingOne(beanTwo, beanThree);
    }
}
 

Constructor argument type matching

xml 기반 메타데이터에 국한된 내용이라 생략하도록 하겠습니다

package examples;

public class ExampleBean {

	// Number of years to calculate the Ultimate Answer
	private final int years;

	// The Answer to Life, the Universe, and Everything
	private final String ultimateAnswer;

	public ExampleBean(int years, String ultimateAnswer) {
		this.years = years;
		this.ultimateAnswer = ultimateAnswer;
	}
}
@Configuration
public class AppConfig {

    //  <bean id="exampleBean" class="examples.ExampleBean">
	//    <constructor-arg type="int" value="7500000"/>
	//    <constructor-arg type="java.lang.String" value="42"/>
    //  </bean>
	@Bean
    public ExampleBean exampleBean() {
    	String str = "42";
    	return new ExampleBean(7500000, str);
    }


}

 

✅ Constructor argument index

xml 기반 메타데이터에 국한된 내용이라 생략하도록 하겠습니다

 

 Constructor argument name

다음은 resources 디렉토리에 있는 example.properties 파일입니다.

example.years=42
example.ultimateAnswer=Life, Universe and Everything

 

다음은 AppConfig에 추가된 configure 빈입니다.

@Configuration
@ComponentScan({"com.intheeast.ioc.dependencies.dependencyinjection"})
public class AppConfig {

    // Define MovieFinder bean
    @Bean
    public MovieFinder movieFinder() {
        return new SimpleMovieFinder();
    }

    // Define SimpleMovieLister bean
    @Bean
    public SimpleMovieLister movieLister(MovieFinder movieFinder) {
    	SimpleMovieLister movieLister = new SimpleMovieLister();
        movieLister.setMovieFinder(movieFinder); // Setter-based DI
        return movieLister;
        
        //return new SimpleMovieLister(movieFinder);
    }
    
    // @Value 어노테이션으로 주입되려면, 반드시 다음 configure가 필요함!
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        configurer.setLocation(new org.springframework.core.io.ClassPathResource("example.properties"));
        return configurer;
    }
}

 

다음은 컨스트럭터 파라미터의 아규먼트로 properties 파일에 정의된 값을 주입하는 예제 코드입니다

@Component
public class ExampleBean {

    private final int years;
    private final String ultimateAnswer;

    public ExampleBean(
            @Value("${example.years}") int years,
            @Value("${example.ultimateAnswer}") String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }

    // Getter 생략
}

 

✅ 생성자 기반 DI (Constructor Injection) 예제

Spring이 가장 권장하는 방식이며, 불변 객체를 만들고, 필수 의존성을 강제할 수 있음

@Component
public class Repository {
    public void save() {
        System.out.println("Data saved!");
    }
}

@Component
public class Service {
    private final Repository repository;

    // 생성자를 통한 의존성 주입
    @Autowired
    public Service(Repository repository) {
        this.repository = repository;
    }

    public void performAction() {
        repository.save();
    }
}

📌 특징
✅ 필수 의존성을 강제할 수 있음
✅ 객체를 불변(immutable)하게 유지할 수 있음
✅ @Autowired 생략 가능 (Spring 4.3 이상)

 

✅ Setter-based Dependency Injections

의존성을 선택적으로 주입할 때 사용되며, 초기화 이후 변경이 가능함.

컨테이너가 아규먼트 없는 컨스트럭터나 아규먼트 없는 static 팩토리 메서드를 호출하여, 빈을 인스턴스화한 후 빈에서 세터 메서드를 호출하여 수행됩니다.

@Component
public class Service {
    private Repository repository;

    // 기본 생성자
    public Service() {}

    // Setter 메서드를 통한 의존성 주입
    @Autowired
    public void setRepository(Repository repository) {
        this.repository = repository;
    }

    public void performAction() {
        repository.save();
    }
}

📌 특징
✅ 선택적 의존성 주입 가능
✅ 객체 생성 후 의존성을 변경 가능
❌ 객체의 불완전한 상태(incomplete state) 발생 가능

 

✅ 세터 기반 DI 핵심 개념 요약 테이블

구분 설명 핵심 포인트
DI 방식 ApplicationContext는 생성자 기반 주입(Constructor DI)과 세터 기반 주입(Setter DI)을 모두 지원 둘 다 가능, 혼합 사용 가능
세터 DI 추가 주입 생성자 DI 이후에도 세터를 통해 추가 주입 가능 보완적 DI 지원
BeanDefinition 빈(Bean)의 메타데이터(설정 정보)를 표현하는 내부 구조체 Spring 내부에서 핵심
PropertyEditor 속성(Property)의 형식 변환을 위한 도구 (예: String → Integer) 타입 변환기 역할
일반 사용자 관점 직접 BeanDefinition, PropertyEditor를 다루지 않음 XML, @Component, @Bean 방식 사용
내부 처리 과정 XML, @Component, @Bean 소스 → 내부적으로 BeanDefinition 으로 변환 후 IoC 컨테이너 로딩 개발자는 신경쓰지 않아도 됨

 

✅ Sprng Bean 구성과 주입의 흐름 (개념도)

🔍 설명:

  • 개발자는 XML, @Component, @Bean 방식으로 빈을 정의합니다.
  • Spring은 이 정의들을 내부적으로 BeanDefinition 객체로 변환합니다.
  • property의 값 타입이 필요한 경우 PropertyEditor를 통해 변환 작업이 이뤄집니다.
  • 완성된 BeanDefinition 정보를 바탕으로 ApplicationContext가 빈을 생성하고 의존성 주입(DI)을 수행합니다.
    • 생성자 기반 DI
    • 세터 기반 DI (필요 시 보완적으로 추가 주입 가능)

 

✅ 시각적 한눈 정리

개발자 입장 내부 동작 결과
XML, @Component, @Bean으로 빈 정의 BeanDefinition으로 변환 IoC 컨테이너 초기화
@Value, constructor-arg 값 등 PropertyEditor로 타입 변환 알맞은 타입으로 주입
생성자 방식, 세터 방식 혼합 사용 DI 수행 실제 빈(Bean) 생성 및 주입 완료
 

✅ 생성자 기반 주입(Constructor-based DI) vs 세터 기반 주입(Setter-based DI)?

생성자 기반 주입과 세터 기반 주입은 혼합하여 사용할 수 있기 때문에, 일반적으로 다음과 같은 원칙을 따르는 것이 좋습니다

필수 의존성은 생성자(Constructor)를 통해 주입하고, 선택적(Optional) 의존성은 세터(Setter)나 구성 메서드를 통해 주입하는 것이 좋습니다.

@Autowired 애노테이션을 세터 메서드에 사용하면 해당 속성을 필수 의존성으로 만들 수 있지만, 생성자 주입과 아규먼트에 대한 프로그래밍적 검증(유효성 검사)을 병행하는 것이 더 바람직합니다.

 

✅ 스프링 팀의 권장 사항 (생성자 주입 선호)

  • Spring 팀은 생성자 주입(Constructor Injection)을 권장합니다.
  • 이유:
    • 불변(Immutable) 객체로 애플리케이션 컴포넌트를 구현할 수 있습니다.
    • 필수 의존성이 null이 아님을 보장할 수 있습니다.
    • 생성자 주입을 통해 항상 완전히 초기화된 상태의 객체를 클라이언트(호출하는 코드)에게 반환할 수 있습니다.

또한, 생성자 아규먼트가 과도하게 많다면 그것은 "좋지 않은 코드 냄새(Bad Code Smell)" 로 간주됩니다.
→ 이는 해당 클래스가 너무 많은 책임을 지고 있음을 의미하며, 관심사의 분리(Separation of Concerns) 를 위해 리팩토링이 필요하다는 신호입니다.

 

✅ 세터 주입의 적절한 활용

  • 세터 주입은 디폴트 값(Default Value)을 가질 수 있는 선택적 의존성(옵션) 에 주로 사용해야 합니다.
  • 만약 필수 의존성을 세터로 주입한다면, 그 의존성을 사용할 때마다 null 체크를 직접 수행해야 하는 불편함이 발생합니다.
  • 세터 주입의 장점:
    • 세터 메서드를 통해 해당 클래스의 객체를 나중에 재설정(Reconfiguration)하거나 재주입(Re-injection)하는 것이 용이합니다.
    • 특히 JMX MBean을 통한 관리와 같은 경우에는 세터 주입이 유용한 사례가 됩니다.

 

✅ 상황에 맞게 선택하라

  • 특정 클래스에 적합한 방식(DI 스타일)을 상황에 따라 선택하는 것이 좋습니다.
  • 때로는 서드파티(Third-party) 클래스와 같이 소스 코드를 수정할 수 없는 경우, 선택의 여지가 없습니다.
    • 예를 들어, 서드파티 클래스가 세터 메서드를 제공하지 않는다면 생성자 주입(Constructor Injection) 만이 유일한 DI 방법일 수 있습니다.

 

✅ Dependency Resolution Process

1️⃣ 컨테이너의 의존성 해결 절차

  • ApplicationContext는 모든 빈(Bean)을 설명하는 구성 메타데이터(Configuration Metadata) 로 생성되고 초기화됩니다.
    • 구성 메타데이터는 XML, 자바 코드, 애노테이션을 통해 지정할 수 있습니다.
  • 각 빈(Bean)에 대한 의존성은 프로퍼티(Property), 생성자 아규먼트(Constructor Argument), 또는 정적 팩토리 메서드의 아규먼트 형태로 표현됩니다.
    • (정적 팩토리 메서드를 사용하는 경우 생성자 대신 사용)
  • 이 의존성들은 빈이 실제로 생성될 때 주입됩니다.
  • 각 프로퍼티나 생성자 아규먼트는 실제 값(리터럴 값) 을 설정하거나, 컨테이너 내의 다른 빈에 대한 참조(Reference) 를 가리킵니다.
  • 값으로 주어지는 경우에는, 설정된 형식에서 프로퍼티나 생성자 아규먼트의 실제 타입으로 변환됩니다.
    • 디폴트로 Spring은 문자열 형식으로 제공된 값을 int, long, String, boolean 등 모든 기본 내장 타입으로 변환할 수 있습니다.

2️⃣ 빈의 검증과 생성 시점

  • Spring 컨테이너는 생성 시 각 빈의 구성을 검증합니다.
  • 그러나 빈의 프로퍼티들은 빈이 실제로 생성될 때까지 설정되지 않습니다.
  • 싱글톤(Singleton) 범위로 설정된 빈(기본값)은 컨테이너가 생성될 때 함께 생성됩니다.
  • 기타 범위(Scope)는 요청 시점(Lazy)까지 생성되지 않습니다.

빈이 생성되면서 그 빈의 의존성들, 또 그 의존성들의 의존성들(Dependency Graph)까지 함께 생성되고 주입됩니다.

  • 의존성 해결 과정에서 발생하는 불일치(예: 참조 오류)는 해당 빈이 처음 생성되는 시점에 발생할 수 있습니다.

Spring은 일반적으로 알아서 올바르게 동작한다고 믿어도 됩니다.

Spring은 존재하지 않는 빈에 대한 참조 순환 참조(circular dependencies) 와 같은 구성 오류를 컨테이너 로드 시점에 감지합니다.

Spring은 속성(property) 설정과 의존성 주입을 가능한 한 늦게, 즉 빈이 실제로 생성되는 시점에 수행합니다.
이로 인해 Spring 컨테이너가 정상적으로 로드된 이후에도, 객체를 요청하는 시점에
그 객체나 해당 객체의 의존성을 생성하는 과정에서 예외가 발생할 수 있습니다.
예를 들면, 필수 속성이 누락되었거나 잘못된 값이 설정되어 빈이 예외를 발생시키는 경우입니다.

이와 같은 구성 오류가 늦게 드러나는 문제(delayed visibility of configuration issues) 를 방지하기 위해,
Spring의 ApplicationContext 구현체는 기본적으로 싱글톤 빈을 선 인스턴스화(pre-instantiate) 합니다.
이는 실제로 필요하기 전 미리 빈을 생성하는 것이므로, 초기 메모리 및 시간 측면에서 다소 비용이 발생하지만,
컨테이너 생성 시점에 이러한 오류를 미리 발견할 수 있습니다.

이러한 기본 동작은 변경할 수 있으며,
싱글톤 빈이 지연 초기화(lazy initialization) 되도록 설정하여, 실제 사용 시점까지 생성을 미룰 수도 있습니다.

 

✅ 순환 참조 (Circular Dependencies)

 예제: 생성자 주입으로 인한 순환 의존성 발생

@Component
public class A {
    private B b;

    @Autowired
    public void setB(B b) {
        this.b = b;
    }
}

@Component
public class B {
    private final A a;

    @Autowired
    public B(A a) {
        this.a = a;
    }
}
  • 생성자 주입(Constructor Injection)을 주로 사용하는 경우, 해결할 수 없는 순환 참조 상황이 발생할 수 있습니다.

예시:

  • 클래스 A가 생성자 주입으로 클래스 B를 요구하고,
  • 클래스 B가 생성자 주입으로 클래스 A를 요구하는 경우.
  • 이처럼 서로가 서로를 요구하는 상황에서 Spring IoC 컨테이너는 런타임에 BeanCurrentlyInCreationException 예외를 던집니다.

해결 방법:

  1. 일부 클래스를 수정하여 세터 주입(Setter Injection) 으로 변경.
  2. 혹은 생성자 주입 대신 세터 주입만 사용하는 것도 가능.
    • (권장되지는 않지만, 세터 주입 방식으로 순환 참조를 해결할 수 있습니다.)

✅ 해결 방법 1: 세터 주입으로 변경

@Component
public class A {
    private B b;

    @Autowired
    public void setB(B b) {
        this.b = b;
    }
}

@Component
public class B {
    private final A a;

    @Autowired
    public B(A a) {
        this.a = a;
    }
}

📌 왜 해결되는가?

  • 세터 주입은 객체가 완전히 생성된 후 주입됨
  • Spring이 A와 B 중 하나를 먼저 생성할 수 있음

 해결 방법 2: @Lazy 사용

@Component
public class A {
    private final B b;

    @Autowired
    public A(@Lazy B b) {
        this.b = b;
    }
}

📌 @Lazy를 사용하면?
 B의 객체 생성을 지연 → 즉시 객체를 만들지 않고 필요할 때 생성
 순환 참조 문제 해결

 

주의:

  • 순환 참조가 있는 경우, 두 빈(A, B)이 서로에게 주입되면서 아직 완전히 초기화되지 않은 상태에서 상대에게 주입 되는 "닭이 먼저냐, 달걀이 먼저냐" 상황이 발생합니다.

✅ Spring의 처리 방식

  • Spring은 참조 오류나 순환 참조 같은 구성 문제를 감지합니다.
  • Spring은 빈의 프로퍼티 설정과 의존성 해결을 가장 늦은 시점(Lazy)까지 미룹니다.
    • 즉, 빈이 실제로 생성될 때 해결합니다.

 

그래서 컨테이너가 정상적으로 로드되었더라도, 실제로 빈을 요청할 때 예외가 발생할 수 있습니다.
예를 들어, 빈 생성 시점에 누락된 속성값으로 인해 예외가 발생할 수 있습니다.

 

이러한 지연된 오류 노출(Delayed Visibility)을 줄이기 위해:

  • ApplicationContext는 기본적으로 싱글톤 빈을 미리 인스턴스화(pre-instantiate) 합니다.
    • 메모리와 초기화 비용이 조금 들더라도, 컨테이너 초기화 시점에 문제를 미리 발견할 수 있습니다.
  • 원한다면 이 기본 동작을 변경하여 싱글톤 빈도 지연 초기화(lazy-initialize) 하도록 설정할 수 있습니다.

✅ 순환 참조가 없는 경우의 동작

  • 순환 참조가 없는 경우, 하나 이상의 협력 빈(collaborating beans)이 다른 빈에 주입될 때,
    • 각 협력 빈은 완전히 구성된 상태로 주입됩니다.
  • 예를 들어, 빈 A가 빈 B를 의존하는 경우,
    • Spring IoC 컨테이너는 먼저 빈 B를 완전히 생성 및 초기화하고 (의존성 주입 포함),
    • 이후 빈 A의 세터 메서드를 호출하여 빈 B를 주입합니다.
  • 즉, 주입되는 빈은:
    • 인스턴스화되고 (싱글톤이며 선 인스턴스화가 아닐 경우, 이 시점에 생성),
    • 모든 의존성이 주입되고,
    • 초기화 메서드(예: 설정된 init 메서드, InitializingBean의 afterPropertiesSet 등)가 호출된 이후에야 주입됩니다.

필드 기반 DI (Field Injection)

필드에 @Autowired를 사용하여 직접 주입하는 방식

@Component
public class Service {

    @Autowired
    private Repository repository;

    public void performAction() {
        repository.save();
    }
}

📌 특징
✅ 코드가 간결함
의존성이 명확하지 않음 → 테스트 및 유지보수 어려움
순환 참조(Circular Dependency) 문제 발생 가능
Spring 컨테이너 없이 객체 생성 불가

 

🚀 Spring 공식 문서에서도 "필드 주입은 권장되지 않음"
💡 대신 생성자 주입을 사용하는 것이 더 좋은 방법

 

DI 방식 비교 및 선택 기준

DI 방식 특징 장점 단점
생성자 주입 (권장) 생성자를 통해 의존성 주입 ✅ 필수 의존성 강제
✅ 객체 불변성 유지
❌ 필수 의존성 없는 경우 다소 불편
세터 주입 Setter 메서드를 통해 주입 ✅ 선택적 의존성 주입 가능
✅ 의존성 변경 가능
❌ 객체의 불완전한 상태 가능
필드 주입 (비추천) @Autowired로 직접 주입 ✅ 코드가 간결함

 

 

📌 권장하는 DI 방식

  • 필수 의존성은 생성자 주입 (@Autowired 생략 가능)
  • 선택적 의존성은 세터 주입
  • 필드 주입은 추천되지 않음

 

🎯 Summary (요약)

🔹 Dependency Injection(DI)객체 간 결합도를 줄이고, 유지보수성과 테스트 용이성을 높이는 핵심 개념
🔹 Spring의 DI 방식
     ✅ 생성자 주입 (권장) → 불변성 유지, 필수 의존성 강제
     ✅ 세터 주입 → 선택적 의존성 주입 가능

필드 주입 (비추천) → 유지보수 어려움, 순환 참조 문제 발생

🔹 순환 의존성(Circular Dependency) 해결 방법
     ✅ 세터 주입으로 변경
     ✅ @Lazy 애노테이션 사용

 

🚀 DI를 적절하게 활용하면 유지보수성이 높은 확장 가능한 애플리케이션을 개발할 수 있습니다! 🎯

 

출처: https://docs.spring.io/spring-framework/reference/core/beans/dependencies/factory-collaborators.html

 

Dependency Injection :: Spring Framework

Constructor-based DI is accomplished by the container invoking a constructor with a number of arguments, each representing a dependency. Calling a static factory method with specific arguments to construct the bean is nearly equivalent, and this discussion

docs.spring.io

 

'Spring Framework > Spring IoC' 카테고리의 다른 글

Using depends-on, Lazy-initialized Beans, Autowiring Collaborators  (0) 2024.11.14
Dependencies  (0) 2024.11.14
Bean Overview  (0) 2024.06.11
Using @Autowired  (0) 2023.12.10
Dependencies and Configuration in Detail  (0) 2023.12.10