내가 보려고 정리하는/Spring

웹 : C.L와 M.L간의 결합력을 낮추는 스프링의 컨테이너 구조 : 0404, 0405

보동이용용 2023. 4. 4. 09:32
반응형

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 자원 주입하여 주입된 객체 사용

반응형