'뉴렉처' 님의 채널(www.youtube.com/user/newlec1)을 바탕으로 제작한 블로그 글입니다:)
저번 강의부터 이어서 xml에 있는 DI를 어노테이션으로 바꾸는 작업들을 하고 있습니다.
지난번에는 setter를 annotation으로 어떻게 변경하는지에 대해서 알아보았는데요,
이번 시간에는 xml 내에서 객체를 생성하는 부분을 어노테이션을 이용하여 바꾸는 방법에 대해서 알아보려고 합니다!
우선, 기존의 코드같은 경우에는 xml 파일을 읽으면 동시에 IoC 컨테이너에서 객체들이 생성되고,
그 생성된 객체 내의 autowired에서 객체를 이어주는 부분을 찾아 연결해주는 작업을 했었습니다.
이번에는 IoC 컨테이너의 객체들 생성 또한 xml 대신 어노테이션으로 할 수 있도록 바꿔줄 것인데,
그러기 위해서 필요한 어노테이션이 바로 @Component입니다.
class 이름 위에 @Component를 붙이면, 이는 해당 class의 객체를 생성하라는 의미를 갖게 되는데요,
xml에서 autowired를 사용 할 때에 <context:annotation-config/> 를 붙여주었듯이
Component 또한 <context::component-scan /> 이라는 것을 붙여주어야합니다.
<context:component-scan base-package="객체화할 클래스들이 있는 패키지명"/> 과 같이 사용되는데,
이는 "내가 적어준 패키지명에 찾아가면 component 어노테이션이 있는데, 그 class를 생성해달라' 라는 의미가 됩니다.
이 때 짚고 넘어가야 하는 부분이 있습니다.
<context:component-scan base-package="객체화할 클래스들이 있는 패키지명"/> 을 적어주면 autowired가 사용되고 있음을 알려주는 <context:annotation-config/> 를 xml에 적어주지 않아도 됩니다.
그 이유는, <context:annotation-config/> 는 내가 xml에서 객체를 생성하면, 그 객체의 안까지 들어가서 autowired가 있는지 확인하고, 그거에 따라서 객체를 연결(set) 해줘! 라는 의미에서 사용되었기 때문입니다.
지금은 객체를 생성하는 부분 또한 xml에서 지워졌으니, <context:annotation-config/> 를 붙이는 것은 의미가 없겠죠?
따라서 setting.xml와 AnimalPrintName.java, Animal.java의 코드는 아래와 같이 바꿀 수 있습니다.
이전에 xml에서 Animal class와 AnimalPrintName class 객체를 생성하던 부분을 어노테이션으로 변경하였습니다.
- setting.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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<context:component-scan base-package="spring.console, spring.entity"/>
</beans>
위의 코드를 보면 package에 두개의 패키지명이 콤마로 구분되어 있는 것을 볼 수 있는데요,
이렇듯이 객체를 만드는 class들이 각각 다른 패키지에 있다면 이처럼 모두 적어주어야 합니다.
- AnimalPrintName.java
@Component
public class AnimalPrintName implements AnimalPrint {
@Autowired(required = false)
@Qualifier("none")
Animal animal;
public AnimalPrintName() {
// TODO Auto-generated constructor stub
}
public AnimalPrintName(Animal animal) {
this.animal = animal;
}
@Override
public void print() {
if (animal == null)
System.out.printf("동물이 없습니다");
else
System.out.printf("Name is %s", animal.getName());
}
@Override
public void setAnimal(Animal animal) {
this.animal = animal;
}
}
- Animal.java
@Component
public class Animal {
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public Animal() {
super();
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
}
이제 Program.java의 코드를 조금 수정해야합니다.
그 이유는 AnimalPrint console = (AnimalPrint) context.getBean("console"); 부분을 살펴보면,
우리는 이제 setting.xml에서 객체를 생성하지 않으니 id가 console인 bean 객체는 찾을 수 없어 에러가 나기 때문입니다.
대신에 id로 찾지 않고 아래와 같이 내가 적어준 class와 형이 맞는 객체를 가져오도록 해야합니다.
- Program.java
public class Program {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("spring/di/setting.xml");
AnimalPrint console = context.getBean(AnimalPrint.class);
console.print();
}
}
실행하면 아래와 같이 출력됩니다.
현재 Animal.java 에서 Component를 이용하여 객체 생성까지는 해주었지만, 내부에 있는 변수에 setter를 이용해 값을 주지 않았기 때문에 null이 나오게 됩니다.
다음과 같이 Animal.java의 필드 위에 @Value를 붙여주면 원하는 값을 기본값으로 설정할 수 있습니다.
- Animal.java
@Component
public class Animal {
@Value("_TECH")
private String name;
private int age;
...
실행시키면 아래와 같은 결과를 확인할 수 있습니다.
'Spring > Dependency Injection' 카테고리의 다른 글
[Spring Framework] XML을 Java Configuration으로 (0) | 2021.01.20 |
---|---|
[Spring Framework] @Autowired 사용 위치와 Required (0) | 2021.01.18 |
[Spring Framework] @Qualifier 를 사용하는 이유 (0) | 2021.01.17 |
[Spring Framework] 어노테이션과 @Autowired 사용하기 (0) | 2021.01.15 |
[Spring Framework] collection 타입의 bean 생성 (0) | 2021.01.11 |