ApplicaitonContext is a complete superset of the BeanFactory.IoC container are called beans.BeanFactory.getType call for the specified bean name. This takes all of the above cases into account and returns the type of object that a BeanFactory.getBean call is going to return for the same bean name. Explains how you go from defining a number of bean definitions that stand alone to a fully recognized application where object collaborate to achieve a goal.
my summary
defining: a number of bean definitions that stand alone -> collaborate
Dependency Injection is a process in which a bean receives its dependencies from an external source instead of creating them itself.
Service Locator pattern과의 차이(참고: https://martinfowler.com/articles/injection.html#UsingAServiceLocator)
서비스 로케이터 패턴은 읽기 쉽고 명확하다는 특징이 있지만, 단점이 있다. 구현에 의존한다.
POJO
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라고 한다. 인터페이스, 애노테이션, 특정 클래스에 대한 dependencies가 없다.
Because of DI, objects are decoupled from the responsibility of managing their dependencies. This makes your classses easier to test, as you can use stub or mock implementations of the dependencies.
Construct argument resolution matching occurs by using the argument's type.
public class SimpleMovieLister {
// the SimpleMovieLister has a dependency on the MovieFinder
private MovieFinder movieFinder;
// a setter method so that the Spring container can inject a MovieFinder
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// business logic that actually uses the injected MovieFinder is omitted...
}
이 class 역시 POJO다. 특정한 것에 종속성이 없기 때문이다.
not nullThe Spring team advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null.
The container performs bean dependency resolution as follows:
The Spring container validates the configuration of each bean as the container is created. However, the bean properties themselves are not set until the bean is actually created. Beans that are singleton-scoped and set to be pre-instantiated (the default) are created when the container is created. Scopes are defined in Bean Scopes. Otherwise, the bean is created only when it is requested. Creation of a bean potentially causes a graph of beans to be created, as the bean’s dependencies and its dependencies' dependencies (and so on) are created and assigned. Note that resolution mismatches among those dependencies may show up late — that is, on first creation of the affected bean.
-> 스프링 컨테이너가 생성될 때, 빈 설정을 확인한다. 그러나 빈의 속성들은 실제로 생성될 때까지 설정되지 않는다. 싱글톤 스코프의 빈만 컨테이너가 생성될 때 생성된다.
Circular dependencies
public class ACircularObject {
private final BCircularObject bCircularObject;
public ACircularObject(BCircularObject bCircularObject) {
this.bCircularObject = bCircularObject;
}
}
public class BCircularObject {
private final ACircularObject aCircularObject;
public BCircularObject(ACircularObject aCircularObject) {
this.aCircularObject = aCircularObject;
}
}
@Configuration
public class CircularDependencyConfig {
@Bean
public ACircularObject aCircularObject(BCircularObject bCircularObject) {
return new ACircularObject(bCircularObject);
}
@Bean
public BCircularObject bCircularObject(ACircularObject aCircularObject) {
return new BCircularObject(aCircularObject);
}
}
public class CircularMain {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(CircularDependencyConfig.class);
ACircularObject aCircularObject = context.getBean(ACircularObject.class);
BCircularObject bCircularObject = context.getBean(BCircularObject.class);
System.out.println("aCircularObject = " + aCircularObject);
System.out.println("bCircularObject = " + bCircularObject);
// Requested bean is currently in creation: Is there an unresolvable circular reference?
// 이라고 에러가 발생한다.
}
}
정말 필수적인 빈만 컨테이너 생성시에 생성하고 나머지는 요청에 따라 생성할 수 있도록 하여, 초반 빌드 시간을 단축시키고 에러가 어느곳에서 나는지 알기 쉽게해준다.
The Spring container can autowire relationships between beans by inspecting the information in the ApplicaitonContext