Jarkata Contexts and Dependency Injection (
CDI) Jarkata EE 설명
- Spring Framework에서 지원하는
Jarkata EE에 속한 규격(=Interface).
。CDI는 규격(=Interface)이므로 구현이 없고 , Spring framework는CDI를 상속.
。 Java의Annotation그룹을 정의한 규격.
▶ 의존성 주입 수행 시 해당 Annotation을 활용 가능.
。CDI를 사용하기전에 Spring boot의 xml 파일 (pom.xml)에서 dependency를 추가해서 사용.<dependency> <groupId>jakarta.inject</groupId> <artifactId>jakarta.inject-api</artifactId> <version>2.0.1</version> </dependency>
- 이후 project 폴더를 우클릭 후 Maven - Reload Project 수행 시 해당 dependenct가 자동으로 다운로드되어 설치되며
CDI Injection API Annotation을 사용가능.
- Maven : XML Script를 기반으로
pom.xml파일을 통해 자동으로 library와 dependency(의존성)을 관리.- pom.xml :
。Spring Project에 필요한 library , Dependency를 설정 시 사용하는 파일.
▶ dependency가xml파일 내에 명시됨.
CDI Injection API Annotation종류
。CDIDependency를pom.xml에 정의 후 활용이 가능.
。CDI Injection API Annotation이Spring Annotation을 대체해서 사용이 가능
@Inject: Spring에서의@Autowired역할 수행.@Named: Spring에서의@Component역할 수행.@Qualifier@Scope@Singleton
import jakarta.inject.Named; import jakarta.inject.Inject; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import java.util.Arrays; @Named // Spring의 @Component class DataService{} @Named class BusinessService{ private DataService dataService; public DataService getDataService() { return dataService; } @Inject // Spring의 @Autowired public void setDataService(DataService dataService) { System.out.println("setter"); this.dataService = dataService; } } @Configuration @ComponentScan public class CdiContextLauncherApplication { static public void main(String[] args) { try (var ct = new AnnotationConfigApplicationContext(CdiContextLauncherApplication.class)) { Arrays.stream(ct.getBeanDefinitionNames()).forEach(System.out::println); System.out.println(ct.getBean(BusinessService.class).getDataService()); } } }。기존 Spring의
@Component,@Autowired를CDI의@Named,@Inject로 변경.
- Java Annotations
。class , method , variable 등을 source에 가깝게 정의하여 간결하고 쉽게 작성.
。Spring Framework를 사용하므로 POJO를 가지지 못한다.
。Annotation 수정이 간단.
- XML Configuration
。거의 사용하지 않는다.
。POJO가 단순
。Annotation 수정이 복잡하다.
=> class 의 이름 변경 시 해당 class의 package 주소를 참조하고 있는 XML 등을 모두 변경해야한다.
XML형식으로Spring bean정의하기.
。src/main/resources폴더에 xml 파일을 생성한 후 다음 구문을 입력.
- src/main/resources :
。java code에서 사용되는 resource가 위치하는 경로
( ex : html , css , 설정(properties) 파일 등 )<?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: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"> <!-- bean definitions here --> </beans>。이를 통해 xml 형식으로 정의된 spring bean을 읽기 위해 java의 AnnotationConfigApplicationContext() 가 아닌 , 다음 구문을 사용.
var ct = new ClassPathXmlApplicationContext("contextConfiguration.xml")import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.Arrays; public class XmlConfigurationContextLauncherApplication { public static void main(String[] args) { try(var ct = new ClassPathXmlApplicationContext("contextConfiguration.xml")){ Arrays.stream(ct.getBeanDefinitionNames()).forEach(System.out::println); } } }
- XML로 Bean 생성하기.
。Bean 생성 시 생성자 주입이 필요한 경우 생성자 매개변수를 지정.
。constructor-arg로 생성자를 생성하여 값을 전달 시 value /
Bean을 전달 시 ref를 사용.#1.Bean을 생성하는 경우
<!-- Bean 생성! --> <bean id="name" class="java.lang.String"> <constructor-arg value="Jeongsu" /> <!-- 생성자 주입을 위한 생성자. --> </bean> <bean id="age" class="java.lang.Integer"> <constructor-arg value="26"/> </bean>#2. 특정 package 내 Component를 Bean으로 선언 및 생성자를 통해 Bean을 전달하는 경우.
<!-- 특정 package 내에 있는 특정 Component만 Bean으로 추출할 경우. --> <bean id="PacMan2" class="com.wjdtn747.springframework.game.PacMan"/> <!-- class에 해당 Component 주소를 입력하면 Bean으로 추출이 가능.--> <!-- 특정 package 내 Component를 Bean으로 선언 후 생성자로 Bean을 넣는 경우--> <!-- 이때 생성자로 Bean을 전달하는 경우 value가 아닌 ref로 지정해야한다!--> <bean id="gameRunner" class="com.wjdtn747.springframework.game.GameRunner"> <constructor-arg ref="PacMan2"/> </bean>。Component Scan :
-특정 package 내에서 Component를 Scan시 사용.
-Component Scan을 할 경우 package 내에서 정의된 모든것을 조회.<!-- Component Scan : game package에서 Compnent를 scan하는 경우.--> <!-- Component Scan을 할 경우 package에서 정의된 모든것을 가져옴.--> <context:component-scan base-package="com.wjdtn747.springframework.game"/> <!-- 해당 구문 추가 시 game package 내부에 있는 Component들을 Bean으로 조회할 수 있다.-->import com.wjdtn747.springframework.game.GameRunner; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.Arrays; public class XmlConfigurationContextLauncherApplication { public static void main(String[] args) { try(var ct = new ClassPathXmlApplicationContext("contextConfiguration.xml")){ Arrays.stream(ct.getBeanDefinitionNames()).forEach(System.out::println); System.out.println(ct.getBean("name")); ct.getBean(GameRunner.class).run(); // xml 내에서 정의된 gameRunner2가 PacMan2를 생성자로 전달받아서 실행됨! } } }Java의
@Configuration에서 수행한 작업은 마찬가지로 XML 작업에서도 수행이 가능하다,
。그러나 현재는Java Annotation의 도입으로 최근 spring을 사용 시 거의 사용을 하지않게된다.
。그러나 오래된 프로젝트에서는 아직XML 설정을 사용하는 경우가 존재하므로 이해하는것은 중요하다.