먼저 src - main - java 하위에 Car이라는 패키지를 만들어주고, Car안에 main과 CarRepository와 CarService를 생성해준다.
CarService는 setter를 통해 CarRepository를 주입받아 사용한다고 가정한다.
// main
package Car;
public class CarMain {
public static void main(String[] args){
}
}
// CarService
package Car;
public class CarService {
CarRepository carRepository;
public void setCarRepository(CarRepository carRepository){
this.carRepository = carRepository;
}
}
// CarRepository
package Car;
public class CarRepository {
}
src - main - resources를 우클릭하여, Spring Config 파일을 만든다. 이름은 application.xml로 만들어준다.
이것이 xml bean 설정 파일이다.
안에 태그를 사용하여 bean을 정의해 줄 수 있다. 아까 만들어 둔, CarService와 CarRepository를 Bean으로 등록해준다.
id, class, scope를 비롯한 다양한 설정을 줄 수 있다. 기본적인 Bean 정의는 아래와 같다.
그러나 이렇게만 하는 경우, 아까 만들어 준, CarService는 CarRepository를 주입받아야하지만, 주입받지 못한다.
주입을 해주기 위해 값을 설정해줘서 reference로 주입해줘야한다.
property의 name 값은 아까 만들어 준, CarService의 setter에서 가져온 것이다.
ref의 값도 name값과 동일하지만, ref의 값은 다른 bean의 id를 통해 참조한다는 뜻이다.
지금 CarService의 setter가 CarRepository를 받아오므로, CarRepository Bean을 ref로 참조하여 주입할 수 있는 것이다.
위에서 만들었던 Bean 파일들을 사용하기 위해 main에서 ApplicationContext를 사용해보겠다.
ApplicationContext를 아까 만들어준 xml 설정파일(application.xml)을 넣어 ClassPathXmlApplicationContext로 선언해준다.
그 후, xml 설정 파일에 정의 된 bean들을 읽어 String 배열에 담고 출력해보면 아래와 같이 나온다.
CarService는 xml설정파일에 의해, CarRepository를 의존성을 주입받은 것이기 때문에, application.xml에서 id 값으로 정의된 bean을 가져와 제대로 의존성 주입이 되었는 지 확인해 볼 수 있다.
carService 값이 null이 아니므로 의존성주입이 제대로 된 것을 볼 수 있다.
그러나, 위의 방법은 잘 쓰이지 않는다. 하나하나 xml파일에 Bean으로 등록하는 것이 번거롭기 때문이다.
그래서 쓰는 것이 <context:component-scan base-package="">이다. base-package에 적어준 package부터 하위까지 모두 스캔하여 Bean을 등록해주는 것이다.
(src - main - java - Car 패키지부터 하위 모든 패키지를 스캔)
기본적으로 @Component annotation을 사용하여 Bean으로 등록할 수 있다. @Service와 @Repository는 @Component를 확장한 것이기 때문에 마찬가지의 효과를 볼 수 있다.
@Service, @Repository annotation을 붙여주면 bean으로는 등록이 되지만, 의존성이 주입된 것은 아니다.
의존성 주입은 @Autowired 라는 annotation을 사용해서 받을 수 있다.
다시 main을 실행시켜보면, bean을 제대로 읽어옴을 볼 수 있다.
Bean설정 파일을 xml이 아닌, 자바로도 만들 수 있다.(@Service, @Repository 등의 annotation을 사용하지 않는다)
@Configuration annotation을 사용한다.
먼저, Car 패키지에 ApplicationConfig라는 클래스를 만들어주고, @Configuration을 붙여준다.
그 다음 @Bean annotation을 이용하여, bean을 정의해준다. 노란색으로 적힌 부분이 아까 xml파일로 보면 bean의 id값이고, return 되는 값이 실제 객체이다.
CarService는 의존성주입을 받아야하므로 아래와 같이 바꿔준다.
의존성 주입은 세 가지 방법이 있다.
첫 번째는 메소드 이름으로 주입해주는 방법
두 번째는 파라미터로 받아 주입해주는 방법
세 번째는 @Autowired를 쓰는 방법이 있다.
(첫 번째, 두 번째 방법)
(세 번째 방법)(이 경우는 setter이기 때문에 가능. 생성자인 경우는 @Autowired로 할 수 없다)
이것을 메인에서 실행해보기 위해서는 xml파일을 가져오기위해 사용한 ClassPathXmlApplicationContext 대신, AnnotationConfigApplicationContext를 사용하여 아까만들어준 ApplicationConfig로 선언해준다.
실행시켜보면 잘 나오는 것을 볼 수 있다.
그러나 이 경우도, 첫 번째 경우와 같이 하나하나 Bean을 등록해주어야한다.
@ComponentScan(basePackageClasses = )을 사용하여 <context:component-scan base-package="">를 사용하는 것과 같은 효과를 낼 수 있다.
basePackageClasses에 특정 클래스를 적어주면, 해당 클래스가 위치한 곳부터 @Service, @Repository 등 특정 annotation을 스캔하여 클래스들을 Bean으로 등록시켜준다.
CarRepository
CarService