웹 : C.L와 M.L간의 결합력을 낮추는 스프링의 컨테이너 구조 : 0404, 0405
H/V
db의 E/R/C 의 스키마에 맞춰 자바빈 규약에 맞게 lombok을 이용하여 domain layer를 만든다.
이 domain layer를 가지고 H/V가 Controller Layer 에서 검증하는데 사용한다.
스프링을 이용하여 구성해보고 컨테이너가 왜 필요했는지 경험해보
프레임워크와 라이브러리의 차이점.
프레임워크는 프레임워크 위에 어플리케이션이 얹어져있다. 제어권이 개발자가 아닌 프레임워크에 있다. 제어의 역전구조 IOC. DI(dependency injection) - 프레임웍이 준 기능을 받아서 쓰는 경우. mybatis, framework, 설정파일을 가지고 있다.
라이브러리는 메인 어플리케이션 위에 라이브러리가 쌓아올려져있다. 어플리케이션에 제어권이 있고 라이브러리를 생성하는 권한도 어플리케이션에 있다. 마음대로 사용할 수 있다. beanUtils.population, commons.lang3
스프링의 지향점.
– JavaEE 기반의 어플리케이션 개발을 쉽게 해주는 오픈 소스 어플리케이션 프레임워크
– 전체 애플리케이션을 체계적으로 엮어낼(wire up) 수 있는 프레임워크
– POJO기반의 개발을 통해 의존적인 코드 없이 빈들에 대한 생명주기를 관리
– 트랜잭션 관리를 위한 일관된 방법을 제공
– O/R mapping : Hibernate, iBatis, JDO등과의 연동 시의 필요 작업 최소화
– Lightweight Container 로 시작 시 부하가 적음
– 다양한 3rd 파티 제품과의 연동
– 테스트의 용이성
(wire up) = 의존성 관리
생명주기 : 컨테이너는 대상의 생명주기를 관리한다. 컨테이너로서의 스프링
ORM은 Object Relational Mapping(객체-관계-매핑)의 약자
3rd 파티 제품 : ibatis -> mybatis , 전세계 개발자들이 이것을 가능하게 해줌...
테스트 용이성 : Mock request
Spring 의 기본 전략
– POJO 를 이용한 가볍고 가능한 비침투적인(non-invasive)개발
– DI 와 인터페이스 지향을 통한 느슨한 결합도(loose coupling) `
– Aspect 와 공통 규약을 통한 선언적 프로그래밍
– Aspect 와 템플릿을 통한 상투적인 코드의 축소.
프레임워크에 종속되지않는 pojo
– DI 와 인터페이스 지향을 통한 느슨한 결합도(loose coupling) : 오늘 할일
객체지향 패러다임을 지향하는 언어. 함수지향 8버전 추가 Aspect aop방법론.....
상투적인 코드 : 를 없앨때 템플릿을 많이 쓴다. 템플릿메소드 패턴 : 나중에 공부해보기
스프링 배치는 멀티스레딩과 스케쥴링이 필수적으로 필요하다. + Quartz
1. 전자정부 프레임
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:egovframework/spring/context-*.xml</param-value>
</context-param>
상위 컨테이너 설정파일
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/egovframework/springmvc/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
하위 컨테이너 설정파일
설정파일에도 계층구조가 있다.
application에 db가 포함되어있는 임베디드 db. sql, hsql
1. 강결합 2. 해결 디자인패턴 3. 스프링
1.
//전략의 주읩자가 모든 결합력을 다 떠안게 된다면 어플리케이션 외부에 잇는 컨테이너를 전략의 주입자로 사용해본다.
core Contatiner 전략의 주입자 모음.
웹 mvc : D.S, H,A, H.M, V.R
원자성. 트랜잭션.
코어컨테이너 > 웹 > 데이터 엑세스 모듈 > AOP > test
1. 컨테이너의 사용 순서
2. 내부 객체 관리 방법
3. 컨테이너의 종류 : beanFactory, ApplicationContext, WebApplicationContext p167,168
4. 컨테이너 종류에 따른 자원의 차이
generic : 런타임에 고정적인 위치가 결정된다.
resource loader가 classpath: file: prefix를 해석한다.
▶ ContainerDesc
모든 의존성 주입이 끝나고 마지막에 라이프 사이클 init이 호출된다.
<?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:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="sampleDAO" class="kr.or.ddit.sample.dao.SampleDAOImpl_Oracle" />
<!-- <bean id="service1" class="kr.or.ddit.sample.service.SampleService" -->
<!-- c:dao-ref="sampleDAO" -->
<!-- init-method="init" -->
<!-- destroy-method="destroya" -->
<!-- /> -->
<bean id="service2" class="kr.or.ddit.sample.service.SampleService"
p:dao-ref="sampleDAO"
init-method="init"
destroy-method="destroya"
/>
</beans>
1. spring-context 모듈을 빌드패스에 추가
2. 필요 전략 객체들을 컨테이너 등록 : spring bean configuration file(XML, Java)
3. 등록된 객체들 사이의 의존관계를 DI(의존성 주입) 구조로 형성
1) setter injection : property, p
2) contructor injection : constructor-arg, c
4. container 객체 생성 - entry point //main 어플리케이션 시작될때 제일 먼저 실행하여 준비해둠..
5. 필요 객체를 컨테이너로부터 주입받아 사용함(getBean)
6. 종료 조건 설정.
위 코드를 보면 아래 설명의 순서대로 1-3번까지의 과정이다.
@Slf4j
public class ContainerDesc {
public static void main(String[] args) {
ConfigurableApplicationContext context = new GenericXmlApplicationContext("classpath:kr/or/ddit/container/conf/Container-Desc.xml");
context.registerShutdownHook(); //지금당장말고 종료시점되면 종료해줘.
// SampleService service1 = context.getBean("service1", SampleService.class);
// SampleService service1_1 = context.getBean("service1", SampleService.class);
SampleService service2 = context.getBean("service2", SampleService.class);
SampleService service2_2 = context.getBean("service2", SampleService.class);
// 레퍼런스 주소를 비교하겠다. 같으면 ? 싱글턴, 스프링이 싱글턴으로 만들어줌.
//내가 알던 싱글턴패턴과 스프링의 싱글턴은 다르다. 컨테이너의 빈관리특성을 알아야한다.
// 싱글턴패턴의 대상은 클래스다. 그런데 스프링의 싱글턴의 대상은 bean이다.
// log.info("service1==service2 : {}", (service1==service2));
// log.info("service1==service2 : {}", (service1==service1_1));
// log.info("service1==service2 : {}", (service2==service2_2));
service2.retreieveData(); //setter injection : 필수전략이 안들어와도 모르는 단점.
}
}
이 코드에서 6번까지의 사용방법이다.
⛑️싱글턴
싱글턴으로 클래스가 관리가 되면 단 한번 생성된 것으로 사용하게 된다. 그런데 Spring에서의 싱글턴에서는 대상이 내부객체인 bean이다. 그래서 bean을 다르게 등록한다면 각자 다른 싱글턴으로 움직이게 되어 주소값을 비교해도 false가 나온다.
▶ResourceVO
resource의 종류는 3가지가 있다. file system resource, class path resource, web resource가 있다.
각 자원을 다루는 인터페이스가 원래는 각자 있었는데 spring을 사용하면 자원의 형태와 상관없이 Resource 인터페이스로 다룰 수 있다.
public class ResourceVO {
private Resource fsResource;
private Resource cpResource;
private Resource webResource;
}
그래서 자원의 리턴값이 모두 resource이다.
컨테이너 사용 예 : 1. 객체 내가 주입 2 자원 주입하여 주입된 객체 사용