반응형
IOC(Inversion of Control)
제어 역전
프레임워크가 사용하는 파일에 작성하면 이를 토대로 객체를 생성하여 반환하고 코드가 동작하는 순서를 결정하게 됨
- IoC 컨테이너 종류
- BeanFactory : 현재 사용 x
- 클래스를 통해 객체를 생성하고 이를 전달
- 상속 등 객체 간의 관계를 형성하고 관리
- Bean에 관련된 설정을 위한 xml 파일은 즉시 로딩하지만 객체는 개발자가 요구할 때 생성
- ApplicationContext : 현재 사용
- 클래스를 통해 객체를 생성하고 이를 전달
- 상속 등 객체 간의 관계를 형성하고 관리
- 국제화 지원 등 문자열에 관련된 다양한 기능 제공
- 리스너로 등록되어 있는 Bean에 이벤트를 발생시킬 수 있음
- Bean에 관련된 설정을 위한 xml 파일은 즉시 로딩하면서 객체를 미리 생성해서 가지고 있음
- ClassPathXmlApplicationContext
- FileSystemXmlApplicationContext
- XmlWebApplicationContext
- BeanFactory : 현재 사용 x
POJO Class
자바 모델이나, 기능, 프레임워크 등에 따르지 않고 홀로 독립적이며 단순한 기능만을 가진 객체들을 의미
- 자바에서 이러한 객체들을 Bean이라 부름
- Metadata : xml 혹은 자바 코드를 가지고 설정한 정보
- Java POJO Classes : 만들어 놓은 클래스
- The Spring container : Metadata(설정 정보)들을 읽어서 그 정보를 토대로 Java POJO Classes를 가지고 객체를 만듦
Spring Bean 객체 생성
Spring에서는 사용할 Bean 객체를 bean configuration file에 정의를 하고 필요할 때 객체를 가져와 사용하는 방법을 이용
- bean 태그 : 사용할 Bean을 정의하는 태그
- bean 태그 기본 속성
- class : 객체를 생성하기 위해 사용할 클래스를 지정
- id : Bean 객체를 가져오기 위해 사용하는 이름을 지정
- lazy-init : 싱글톤인 경우 xml을 로딩할 때 객체 생성 여부를 설정
- scope : 객체의 범위를 설정
- singleton : 객체를 하나만 생성해서 사용
- prototype : 객체를 가져올 때 마다 객체를 생성
- bean 태그 기본 속성
- Bean 객체의 생명 주기
- Spring의 Bean은 다음과 같은 상황일 때 객체가 생성
- Singleton인 경우 xml파일을 로딩할 때 객체 생성
- Singleton이고 lazy-init 속성이 true일 경우 getBean 메서드를 사용할 때 객체 생성
- prototype 일 경우 getBean 메서드를 사용할 때 객체 생성
- IoC 컨테이너가 종료될 때 객체가 소멸
- 객체 생성과 소멸 시 호출될 메서드 등록
- 객체가 생성되면 가장 먼저 생성자 호출
- init-method : 생성자 호출 이후 자동으로 호출
- destory-method : 객체가 소멸될 때 자동으로 호출
- default-init-method : init-method를 설정하지 않은 경우 자동으로 호출
- default-destory-method : destroy-method를 설정하지 않은 경우 자동으로 호출
BeanPostProcessor
Bean 객체를 정의할 때 inti-method 속성을 설정하면 객체가 생성될 때 자동으로 호출될 메서드를 지정 가능
- postProcessBeforeInitialization : inti-method에 지정된 메서드가 호출되기 전에 호출
- postProcessAfterInitialization : init-method에 지정된 메서드가 호출된 후에 호출
- init-method가 지정되어있지 않더라도 자동으로 호출
DI(Dependency Injection)
의존성 주입
Bean 객체를 생성할 때 Bean 객체가 관리할 값이나 객체를 주입하는 것
- Bean 객체 생성 후 Bean 객체가 가질 기본 값을 자바 코드로 설정하는 것이 아닌 Bean을 정의하는 xml 코드에서 정의하는 개념
- Bean 객체를 만들고 난 후 객체가 관리할 값들을 변수에다 넣는 작업을 해주는 것(xml등으로 값 설정해준것을 주입)
생성자를 통한 주입
constructor-arg 를 이용해서 생성자의 파라미터 대입
<bean id='xml1' class='kr.co.softcampus.beans.TestBean1' lazy-init="true">
<constructor-arg value="100" type='int' index='0'/>
<constructor-arg value="문자열 1" index='1'/>
<constructor-arg ref="data_bean1" index='2'/>
</bean>
<bean id='data_bean1 class='kr.co.softcampus.beans.DataBean1'/>
- value : 기본 자료형 값과 문자열 값을 설정
- ref : 객체를 설정
- type : 저장할 값의 타입을 설정
- index : 지정된 값을 주입할 생성자의 매개변수 인덱스 번호
Setter 메서드를 통한 주입
property를 이용해서 주입
컬렉션 주입
- Bean을 정의할 때 주입해야 하는 멤버가 컬렉션인 경우 컬렉션이 관리할 객체를 초기에 설정 가능
- List. Map, Set, Property
<List>
...
<bean id='t1' class='kr.co.softcampus.beans.TestBean'>
<property name="list1">
<list>
<value type='int'>100</value> //문자열이 아닌 경우 type을 지정
<value type='int'>200</value> //문자열은 그냥 type 없이 지정
<value type='int'>300</value>
</list>
<property>
<property name="list2">
<list>
<bean class='kr.softcampus.beans.DataBean'/>
<bean class='kr.softcampus.beans.DataBean'/>
</list>
<property>
...
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("kr/co/softcampus/beans")
TestBean t1 = ctx.getBean("t1", TestBean.class);
List<Integer> list1 = t1.getList1();
for(int value : list2){
System.out.printf("list1 : %d/n", value);
}
List<DataBean> list2 = t1.getList2();
for(DataBean obj : list2){
System.out.printf("list2 : %d/n", obj);
}
자동 주입
- Spring에서는 객체를 주입할 때 자동으로 주입될 수 있도록 설정 가능
- 자동 주입 = 이름, 타입 생성자를 통할 수 있으며 auto wire라는 용어로 부름
1. 이름을 통한 주입
- byName : 빈 객객체의 프로퍼티 이름과 정의된 빈의 이름이 같은 것을 찾아 자동으로 주입
<bean id='obj2' c;ass='kr.co.softcampus.beans.TestBean1' autowire='byName'/>
<bean id ='data1' class='kr.co.softcampus.beans.TestBean1'/>
<bean id ='data2' class='kr.co.softcampus.beans.TestBean1'/>
- byType : 빈 객체의 프로퍼티 타입과 정의된 빈의타입이 일치할 경우 자동으로 주입
- 이 때, 동일 타입의 빈이 2개 이상 정의되어 있으면 오류 발생
- constructor : 생성자의 매개 변수 타입과 정의된 빈의 타입이 일치하는 경우 주입
- 이 때, 동일 타입의 빈이 2개 이상 정의되어 있으면 오류가 발생
- 객체타입이 아닌 String, int와 같은 타입은 직접 constructor_arg를 지정
자바를 이용한 빈 등록
- beans.xml 파일을 만들어 이를 통해 빈 객체를 생성하고 java 코드에서 가져와서 사용
- 이제 beans.xml 파일 등록 대신 java파일에서 작업하는 방법 사용
@Configuration
- 현재 자바 파일이 빈 등록을 위한 자바파일임을 알려줌
@Bean
- bean 객체를 정의할 때 사용
- Spring은 해당 어노테이션이 붙은 메서드를 확인 후 해당 메서드를 자동 호출&해당 메서드의 반환값을 가지고 있음
- 메서드 이름이 bean 이름이 됨(해당 메서드 이름으로 getBean을 하면 위에서 반환값을 가지고있다가 해당 값을 이용)
- @Bean(name=이름) : bean 이름을 새롭게 정의
- @Lazy : lazy-init 속성을 지정(getBean메서드 사용 시 bean 객체 생성)
- @Scope("prototype") : bean의 scope를 prototype으로 설정
- @Primary : primary 속성을 지정(클래스타입을 가지고 bean객체 선별 시 primary가 true인 bean을 사용)
- init, destroy 메서드
- 객체가 생성되거나 소멸될 때 호출되는 메서드를 등록
- @Bean(initMethod="bean2_init", destroyMethod="bean2_destroy")
@Required
- 빈드시 주입해야 할 프로퍼티
- 스프링 5.1 부터 Deprecated 되었음(사용불가)
- Required 대신 생성자를 통해 주입 권장
@Required
public void setData1(int data1){
this.data1 = data1;
}
@Autowired
- 자동주입(타입)
- 객체 타입을 통해 등록된 bean 객체중 타입에 맞는 것을 자동으로 주입
- 변수 자체에 @Autowired 사용시 setter가 자동 주입, getter 메서드만 작성하면 됨
- @Autowired(required = false)
- Bean이 있으면 주입하고 아니면 말고(required가 없다면 bean을 못 찾을 시 오류 발생)
@Autowired
private DataClass1 data3;
@Autowired
public void setData2(DataClass1 data2){
this.data2 = data2;
}
@Autowired
public TestBean1(DataClass2 data4){
this.data4 = data4;
}
@Qualifier
- @Autowired로 주입 시 같은 타입의 Bean이 여러 개 정의되어 있다면 Qualifier에 설정되어 있는 bean을 찾아 주입
@Autowired
@Qualifier("obj1")
private DataClass4 data6;
@Autowired
@Qualifier("obj2")
private DataClass4 data7;
@Value
- 생성자 주입 시 참조변수 타입의 변수들은 자동으로 주입되고 기본 자료형 및 문자열 값을 주입할 때 설정
public TestBean2(@Value("100") int data1, @Value("문자열") String data2, DataBean data3){
this.data1 = data1;
this.data2 = data2;
this.data3 = data3;
}
@Component
- Bean Configuration 파일에 Bean을 등록하지 않아도 자동으로 등록
@Component
public class TestBean3{
...
}
Spring Context 생성
- xml을 쓸떄는 ClassPathXmlApplicationContext를 사용함
- java를 통해 빈 등록 시 AnnoationConfigApplicationContext 사용
- beans.xml 클래스의 역할을 대신할 BeanConfigClass를 생성해야함
AnnotationConfigApplicationContext ctx
= new AnnotationConfigApplicationContext("kr/co/softcampus/config/beans.xml");
ctx.register(BeanConfig.class);
ctx.refresh();
자바를 이용한 빈 주입
Bean에 대한 주입은 생성자를 직접 호출하거나 setter 메서드를 직접 호출하여 값 주입
- 생성자를 통한 주입
@Bean
public TestBean1 java1(){
return new TestBean1(200, "문자열", new DataBean1());
}
- Setter를 이용한 주입
@Bean
public TestBean1 java2(){
TestBean1 t1 = new TestBean1();
t1.setData1(400);
t1.setData2("문자열4");
t1.setData3(new DataBean1());
return t1;
}
- 자동 주입
@Bean(autowire=주입방식) : 자동 주입 방식 설정Autowire.BY_NAME : 이름을 통한 자동 주입Autowire.BY_TYPE : 타입을 통한 자동 주입- 스프링 5.1 부터 Deprecated 되었음
- 5.1부터는 Bean에 직접 설정하는 방식을 추천
BY_NAME 사용
...
@Bean
public DataBean2 data1(){
return new DataBean2();
}
@Bean
public DataBean2 data2(){
return new DataBean2();
}
@Bean(autowire = Autowire.BY_NAME)
public TestBean2 java3(){
return new TestBean2();
}
JSR-250 어노테이션
스프링에서 기본으로 제공되지는 않지만 자바 플랫폼 공통 어노테이션인 JSR-250을 적용 가능
라이브러리 추가
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>${javax.annotation-version}</version>
</dependency>
@PostConstruct
- 생성자 호출 후 자동으로 호출될 함수를 등록
@PostConstruct
public void postConstruct(){
System.out.println("생성자가 호출된 후 자동으로 호출");
}
@PreDestroy
- 객체가 소멸 전 자동으로 호출될 함수 등록
@PreDestroy
public void PreDestroy(){
System.out.println("생성자가 소멸되기 직전에 호출");
}
@Resource
- Bean의 이름을 통해 주입
- @Autowired 는 타입을 통해 주입이라면 @Resource는 이름을 통해 주입
- 가져올 Bean 객체의 이름과 정의하고 싶은 변수명이 다를경우
- @Resource(name="obj3") -> obj3이라는 이름의 bean을 주입한다고 명시
@Resource
private DataClass5 data8;
@Resource(name = "obj3")
private DataClass5 data9;
반응형
'Spring' 카테고리의 다른 글
Spring Security 1 (0) | 2022.06.24 |
---|---|
Spring - RestController 1 (0) | 2022.06.15 |
Spring - logging (0) | 2022.06.08 |
Spring 구성 속성 2 (0) | 2022.06.02 |
Spring - 구성 속성 (0) | 2022.05.30 |