프로그램이 거대해 짐에 따라 XML
을 이용하여 IOC Container
를 설정하는 것이 점점 어려워졌고 때문에 Annotation(@)
이란 것이 등장했다(이하 어노테이션). 어노테이션은 코드에 메타데이터를 작성하여 직관적인 코딩이 가능하게 만들어주며 이에 따라 생산성이 증대되는 장점을 가지고 있다.
1. @Configuration
@Configuration
Configuration 어노테이션은 스프링 IOC Container
에게 해당 클래스를 Bean 구성 Class임을 알려주는 것이다.
2. @Bean vs @Component
@Bean
어노테이션과 @Component
어노테이션 둘다 Spring(IOC) Container
에 Bean을 등록하도록 하는 메타데이터를 기입하는 어노테이션이다. 그렇다면 왜 두개나 만들어 놓았을까? 정답은 둘의 용도가 다르기 때문
이다.
2.1. @Bean
@Bean
어노테이션의 경우 개발자가 직접 제어가 불가능한 외부 라이브러리등을 Bean
으로 만들려할 때 사용된다.
public class ApplicationConfig {
public ArrayList<String> array(){
return new ArrayList<String>();
}
}
위는 @Bean
어노테이션을 이용하여 Bean을 생성한 예제이다. 위와 같이 ArrayList
같은 라이브러리등을 Bean으로 등록하기 위해서는 별도로 해당 라이브러리 객체를 반환하는 Method
를 만들고 @Bean
어노테이션을 붙혀주면 된다. 위의 경우 Bean어노테이션에 아무런 값을 지정하지 않았으므로 Method 이름을 CamelCase
로 변경한 것이 Bean id
로 등록된다. (ex. 메소드 이름이 arrayList()인 경우 arrayList
가 Bean id)
xxxxxxxxxx
public class ApplicationConfig {
(name="myarray")
public ArrayList<String> array(){
return new ArrayList<String>();
}
}
위와 같이 @Bean
어노테이션에 name
이라는 값을 이용하면 자신이 원하는 id로 Bean을 등록
할 수 있다. 어노테이션 안에 값을 입력하지 않을 경우 메소드의 이름을 CamelCase로 변경한
것이 Bean의 id
가 된다.
xxxxxxxxxx
public class ApplicationConfig {
public ArrayList<Integer> array(){
return new ArrayList<Integer>();
}
public Student student() {
return new Student(array());
}
}
의존관계가 필요할 때에는 어떻게 해결할 수 있을까? Student
객체의 경우 생성자에서 ArrayList를 주입 받도록 코드를 짜놓았다 이럴때에는 Bean으로 선언된 array()메소드를 호출함으로써 의존성을 주입할 수 있다.
2.2. @Component
@Component
어노테이션의 경우 개발자가 직접 작성한 Class를 Bean으로 등록하기 위한 어노테이션이다. 아래의 예제를 보자
xxxxxxxxxx
public class Student {
public Student() {
System.out.println("hi");
}
}
Student
Class는 개발자가 사용하기 위해서 직접 작성한 Class이다 이러한 클래스를 Bean으로 등록하기 위해 상단에 @Component
어노테이션을 사용한것을 볼 수 있다.
xxxxxxxxxx
value="mystudent") (
public class Student {
public Student() {
System.out.println("hi");
}
}
@Component
역시 아무런 추가 정보가 없다면 Class의 이름을 Camelcase로 변경한 것이 Bean id로
사용된다. 하지만 @Bean
과 다르게 @Component
는 name이 아닌 value를 이용해 Bean의 이름을 지정
한다.
@Autowired
value="mystudent") (
public class Student {
@AutoWired
private Pencil pencil;
public Student() {
System.out.println("hi");
}
}
@Component를 사용한 Bean의 의존성 주입은 @AutoWired 어노테이션을 이용하여 할 수 있다. 위와 같이 Student가 Pencil에 대한 의존성을 가지고 있는 경우 @AutoWired 어노테이션을 이용하여 의존성을 자동으로 주입할 수 있다. 이때 당연히 Pencil도 @Component 어노테이션을 가지고 있어야 한다. 그래야만 IOC Container에 Bean으로 등록이되기 때문이다.
@Autowired 어노테이션의 경우 형(타입)을 통해 해당 자리에 들어올 객체를 판별하여 주입해준다. 따라서 해당 자리에 들어올 수 있는 객체가 여러개인 경우, 즉 다형성을 띄고있는 객체타입에 @Autowired를 사용한 경우에는 @Qualifier("Bean이름") 을 이용하여 해당 자리에 주입될 Bean을 명시해주어야 한다.
위의 그림에서는 Goods라는 인터페이스를 Computer 와 Book이 구현하고 있으므로 Person클래스의 goods 참조변수에 위치할 수 있는 Bean이 Book,Computer 두가지 이다 때문에 @Qualifier("Bean이름")을 통해 해당 자리에 위치할 빈을 명시했다
3. 사용방법
3.1 @Bean
xxxxxxxxxx
public class Student {
public Student() {
System.out.println("hi");
}
}
우선 의존성 주입 대상 Class를 생성한다. 생성자가 호출될 때 콘솔창에 "hi"를 출력하도록 했다.
xxxxxxxxxx
public class ApplicationConfig {
public Student student() {
return new Student();
}
}
Student
를 Bean으로 등록하기 위해 Config Class
를 임의로 만들고 @Configuration
어노테이션을 부여했다. 그 후 Student 객체를 반환하는 Method를 작성하고 @Bean
어노테이션을 부여한다.
xpublic class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
Student student = context.getBean("student", Student.class);
}
}
Annotation을 기반으로 Bean을 등록했으므로 AnnotationConfigApplicationContext
객체를 생성하고 매개변수로 @Configuration
어노테이션을 부여한 ApplicationConfig 클래스를 넘겨준다. 그 후 getBean을 이용하여 사용하면 된다.
3.2 @Component
@Component
어노테이션이 부여된 Class들은 자동으로 IOC Container
에 Bean으로 등록이 되는데 IOC Container 에게 이러한 어노테이션이 부여된 Class를 자동으로 Bean으로 등록하라고 하기 위해서 XML파일에 따로 설정이 필요하다.
우선 xml파일을 연뒤 하단에 Namespaces
탭을 클릭한뒤 context
를 체크한 다음 저장을 한다.
xxxxxxxxxx
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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-3.2.xsd">
<context:component-scan base-package="com.java.ex"></context:component-scan>
</beans>
다시 Source 탭으로 돌아와 <context:component-scan base-package="com.java.ex"></context:component-scan>
코드를 추가해주면 준비는 완료된다.
xxxxxxxxxx
import org.springframework.stereotype.Component;
value="mystudent") (
public class Student {
public Student() {
System.out.println("hi");
}
}
@Component
어노테이션을 부여한 Student 클래스이다.
xxxxxxxxxx
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("scan.xml");
Student student = context.getBean("mystudent", Student.class);
}
}
Main 클래스에서는 기존 XML을 이용하여 의존성을 주입하듯 객체를 생성하면 된다.
4. 요약
@Component
는 개발자가 직접 작성한 Class
를 Bean
으로 만드는 것이고. @Bean
은 개발자가 작성한 Method
를 통해 반환되는 객체를 Bean
으로 만드는것 이다. 또한 각자의 용도가 정해져있으므로 정해진 곳에서만 사용가능하며 다른곳에서 사용하려한다면 Compile 에러를 내뱉는다.
'FrameWork > Spring' 카테고리의 다른 글
Spring - AOP관련 Annotation - 4 (0) | 2019.03.29 |
---|---|
Spring - Spring을 왜 사용하나요?(AOP) - 3 (2) | 2019.03.29 |
Spring - Spring을 왜 사용하나요?(DI) - 1 (15) | 2019.03.26 |
SpringBoot - JSP 환경 설정(Gradle , Maven) (0) | 2019.01.29 |
톰캣 Error copying file to C:/Program Files/ , Publishing to Tomcat v8.0 Server 에러 (0) | 2018.11.11 |