IOC
IOC란, Inversion of Control의 약자로 프로그램을 구동하는데 필요한 객체에 대한 생성, 변경 등의 관리의 프로그램을 개발하는 사람이 아닌 프로그램을 구동하는 컨테이너에서 직접 관리한느 것을 말한다.
IOC 컨테이너
스프링에서 관리하는 객체를 'Bean'이라고 하고, 해당 빈들을 관리한다는 의미로 컨테이너를 Bean Factory 라고 한다.
IOC 컨테이너의 역할
1. 객체의 생명주기와 의존성을 관리한다.
2. VO 객체의 생성, 초기화, 소멸 등의 처리를 담당한다.
3. 개발자가 직접 객체를 생성할 수 있지만 해당 권한을 컨테이너에 맡김으로써 소스 코드 구현의 시간을 단축할 수 있다.
DI(의존성 주입)
DI란, Dependency Injection의 약자로 IOC 구현의 핵심 기술이라고 할 수 있다.
사용하는 객체를 직접 생성하여 만드는 것이 아니라 컨테이너가 빈의 설정 정보를 읽어와 자동으로 해당 객체에 연결하는 것을 의미 한다.
이렇게 의존성을 주입 받게 되면 이후 해당 객체를 수정해야 할 상황이 발생했을 경우 소스 코드의 수정을 최소화 할수 있따.
장점으로는 개발자가 작성해야할 코드가 단순해지고, 각 객체 간의 종속 관계를 해소시킬수 있다.
생성자를 통한 의존성 주입
Constructor를 통해 의존 관계가 있는 Bean을 주입하려면 <constructor-arg> 태그르 사용한다.
xml 방식
spring-context.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="member" class="spring_study.chap01_bean_factory.xmlconfig.Member">
<!-- 생성자쪽으로 값으 전달할때 index와 name 속성을 사용할 수 있음 -->
<constructor-arg index="0" value="1"/>
<constructor-arg name="id" value="user01"/>
<constructor-arg index="2"><value>pass01</value></constructor-arg>
<constructor-arg name="name"><value>홍길동</value></constructor-arg>
</bean>
</beans>
위의 코드를 작성할때 bean id는 호출할 이름을 지정해주고 class에는 지정할 클래스를 지정해준다
만약 빈 설정할때 id의 값을 입력하지않을시 class Rule에맞게 Member 클래스의 첫글자는 소문자로해 자동으로 member로 인식한다.
생성자를 이용한 빈 생성시 생성자는 Member 객체에 4개의 매개변수를 맞출수있는 생성자가 반드시 있어야한다.
<constructor-arg> 에서 옵션으로 index 는 0번인덱스라는뜻이고 value에는 값이 들어가면된다.
Application.java
package spring_study.chap01_bean_factory.xmlconfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
public class Application {
public static void main(String[] args) {
ApplicationContext context = new GenericXmlApplicationContext("spring_study/chap01_bean_factory/xmlconfig/spring-context.xml");
// 방법1
//Member member = (Member) context.getBean("member");
// 방법2
// Member member = context.getBean(Member.class);
// 방법3
Member member = context.getBean("member", Member.class);
System.out.println(member);
}
}
Member객체를 Bean이용해 반환받는 방법은 3가지가 존재한다 .
방법 1에는 강제형변환을안했을시 반환값은 Object 이기 때문에 강제형변환 해주어야한다.
방법 2에는 Member.class 이용해 설정해주는 방법이고,
방법 3은 Bean의 아이디와 클레스위치를 설정해주는방법이다 제일 안정적이고 깔끔한 방법은 3번이다.
출력해보면 아래와 같이 출력이된다.
따로 new Member로 값을 지정하지 않았는데 출력되는것을 확인할수 있다.
java 방식
xml과 또다르게 java 방식이존재한다.
java파일에 애너테이션 이용한 작업방식이다.
ContextConfiguration.java
항상 @Configuration 애너테이션작성하여 이파일은 컨피규레이션 이라는 설정을해줘야한다.
package spring_study.chap01_bean_factory.javaconfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ContextConfiguration {
@Bean(name="member")
public Member getMember() {
return new Member(1, "user01", "pass01", "홍길동");
}
}
Application.java
package spring_study.chap01_bean_factory.javaconfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Application {
public static void main(String[] args) {
/* AnnotationConfigApplicationContext : 어노테이션 설정 정보를 읽어와서 컨테이너 설정 */
ApplicationContext context = new AnnotationConfigApplicationContext(ContextConfiguration.class);
// Member member = context.getBean(Member.class);
Member member = context.getBean("member", Member.class);
System.out.println(member);
}
}
xml방식과 다르게 ApplicationContext 인터페이스의 객체생성은 AnnotationConfigApplicationContext() 이용하여 설정해줘야한다.
Component-scan
Configuration 기준으로 Bean을 스캔하는데 같은 패키지(폴더)내에서만 스캔을 실시한다.
만약 같은폴더에 Bean을 설정해둔 파일이 없다면 없다는 파일이라고 예외가발생하게된다.
그래서 @CompoentScan 애너테이션을이용해 스캔위치를 설정해준다.
java버전
폴더구조는 아래와 같다
MemberDao.interface
package spring_study.chap02_component_scan.javaconfig;
public interface MemberDao {
// 회원 번호로 회원 정보를 조회하는 메소드
Member selectMember(int sequence);
// 회원 정보를 저장하고 결과를 리턴하는 메소드
boolean insertMember(Member newMember);
}
MemberDaoImpl.java
package spring_study.chap02_component_scan.javaconfig;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Component;
/*
* 인터페이스로 메소드를 강제화한 후 구현하여 사용하면 "강제성이 부여" 된다.
* */
@Component(value="memberDao")
public class MemberDaoImpl implements MemberDao{
private Map<Integer, Member> memberMap;
public MemberDaoImpl() {
memberMap = new HashMap<>();
memberMap.put(1, new Member(1, "user01", "pass01", "홍길동"));
memberMap.put(2, new Member(2, "user02", "pass02", "유관순"));
}
@Override
public Member selectMember(int sequence) {
// 매개 변수로 전달 받은 회원 번호를 map에서 조회 후 해당 객체 리턴
return memberMap.get(sequence);
}
@Override
public boolean insertMember(Member newMember) {
int before = memberMap.size();
memberMap.put(newMember.getSequence(), newMember);
int after = memberMap.size();
return after > before ? true : false;
}
}
Application.java
ApplicationContext context = new AnnotationConfigApplicationContext(ContextConfiguration1.class);
String[] beanNames = context.getBeanDefinitionNames();
for(String beanName : beanNames) {
System.out.println("beanName : " + beanName);
}
MemberDao memberDao = context.getBean(MemberDao.class);
System.out.println(memberDao.selectMember(1));
System.out.println(memberDao.insertMember(new Member(3, "user03", "pass03", "이순신")));
System.out.println(memberDao.selectMember(3));
ConfigurationContext.java
package spring_study.chap02_component_scan.javaconfig.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages="spring_study.chap02_component_scan.javaconfig")
public class ContextConfiguration1 {
}
아래의 사진과같이 스캔의 위치를 설정해준다. javaconfig의 폴더에서 스캔하라는 말과 같다.
다풀어써보면 javaconfig 폴더에서 Bean id가 MemberDao인 파일을 스캔하라는 의미이다.
2. @Component.Filter 애너테이션
스캔하는데 지정하는 형식의 타입을 스캔하지 말아라 라는 애너테이션입니다.
ContextConfiguration.java
1. 타입으로 설정 javaconfig 폴더에서 MemberDao.class 파일을 스캔하지 말아라 라는뜻입니다.
2. 어노테이션 종류로 설정 javaconfig 폴더에서 @Componet() 로 지정된 애너테이션을 스캔하지 말아라 라는뜻입니다.
3. 표현식으로 설정 은 chap02_component_scan폴더의 전체를 스캔하지 말아라 라는 뜻입니다.
package spring_study.chap02_component_scan.javaconfig.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import spring_study.chap02_component_scan.javaconfig.MemberDao;
@Configuration
@ComponentScan(basePackages="spring_study.chap02_component_scan.javaconfig",
excludeFilters= {
@ComponentScan.Filter(
// 1. 타입으로 설정
// type=FilterType.ASSIGNABLE_TYPE,
// classes= {MemberDao.class}
// 2. 어노테이션 종류로 설정
// type=FilterType.ANNOTATION,
// classes= {org.springframework.stereotype.Component.class}
// 3. 표현식으로 설정
// type=FilterType.REGEX,
// pattern= {"spring_study.chap02_component_scan.*"}
// ASPECTJ : 포인트컷 표현식으로 클래스를 매치
)
})
public class ContextConfiguration2 {
}
useDefaultFilters
아무것도 스캔하지 말라는 기능
ContextConfiguration3.java
아래의 스캔 뜻은 javaconfig 폴더에서 아무것도 스캔하지말고, includeFilters 이용해 MemberDao의 클래스만 스캔하라는 뜻입니다.
package spring_study.chap02_component_scan.javaconfig.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import spring_study.chap02_component_scan.javaconfig.MemberDao;
@Configuration
@ComponentScan(basePackages="spring_study.chap02_component_scan.javaconfig",
useDefaultFilters = false, //아무것도 스캔하지 마세요!
includeFilters= {@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, classes= {MemberDao.class})}
)
public class ContextConfiguration3 {
}
xml버전
xml 버전의 폴더구조는 다음과 같습니다.
spring-config1.xml
아래의 폴더에서 다른점은 context를 이용해 작업하는것인데
xml파일의 하단에보면 Namespaces 라는 탭이 보이는데 클릭합니다.
그후 context 체크하고 다시확인하여 작업합니다.
아래의 뜻은 xmlconfig의 폴더에서 스캔을 하라는 말과 같습니다.
<?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-4.3.xsd">
<context:component-scan base-package="spring_study.chap02_component_scan.xmlconfig"></context:component-scan>
</beans>
'프로그래밍 > Spring' 카테고리의 다른 글
Spring - 6_1. Spring JDBC (Annotation) (0) | 2021.10.22 |
---|---|
Spring - 5. Spring IOC (0) | 2021.10.18 |
Spring - 3. Spring 개요 (0) | 2021.10.15 |
Spring - 2. STS3 다운,설치하기 (0) | 2021.10.15 |
Spring - 1. jar파일 다운로드 (0) | 2021.10.15 |