Spring
Spring Framework 등장배경
- EJB를 통해서 다른 레이어들의 구성요소를 몰라도 사용할수 있었지만, 이는 현실에서 반영하기 힘들다.
- 복잡한 스펙으로 인해 개발의 효율성이 떨어진다.
- EJB를 돌리기 위한 별도의 EJB서버가 필요하다
- 웹 규모가 커지면서, 엔터프라이즈급의 서비스가 필요해짐
- 점차 POJO + 경량 프레임워크를 사용하기 시작하면서 발전함
About Spring
- 엔터프라이즈급 애플리케이션을 만들기 위한 기능을 종합적으로 제공하는 경량화 된 솔루션이다.
- 한국 전자정부표준프레임워크의 기반 기술이며 한국정보화진흥원
에서는 공공기관의 웹 서비스 제공 시 스프링을 권장하고 있다
- Spring Framework 는 JEE(Java Enterprise Edition)이 제공하는 다수의 기능을 지원하고 있다.
- 개발자가 복잡하고 실수하기 쉬운 Lowlevel 에 신경 쓰지 않고 Business Logic 개발에 전념할 수 있도록 해준다.
특징 정리
- 경량컨테이너
- DI(Denpendency Injection) 패턴 지원
- AOP(Aspect of Programming) 지원
- 문제를 해결하기 위한 핵심관심 사항과 전체에 적용되는 공통관심 사항을 기준으로 프로그래밍함으로서 공통 모듈을 여러 코드에 쉽게 적용할 수 있도록 한다.
- POJO(Plain Old Java Object) 지원
- IoC(Inversion of Control)
- 스프링은 트랜잭션 처리를 위한 일관된 방법을 제공한다.
- JDBC, JTA 또는 컨테이너가 제공하는 트랜잭션을 사용하든, 설정파일을 통해 트랜잭션 관련정보를 입력하기 때문에 트랜잭션 구현에 상관없이 동일한 코드를 여러 환경에서 사용이 가능하다.
- 스프링은 영속성과 관련된 다양한 API를 지원한다.
- 스프링은 JDBC를 비롯하여 iBatis, myBatis, Hibernate, JPA등 DB처리를 위해 널리 사용되는 라이브러리와 연동을 지원하고 있다.
- 스프링은 다양한 API에 대한 연동을 지원한다.
- JMS, 메일, 스케쥴링 등 EE(Enterprise Environment) 어플리케이션 개발에 필요한 다양한 API를 설정 파일과 어노테이션을 통해서 손쉽게 사용할 수 있도록 지원하고 있다.
Framework vs Library
Spring 구조
- POJO
- 특정 환경이나 기술에 종속적이지 않은, 객체지향 원리에 충실한 자바객체로서 테스트하기 용이하다는 장점을 갖는다.
- PSA
- 환경과 세부기술의 변경과 관계없이 일관된 방식으로 기술에 접근할 수 있게 해주는 설계 원칙을 뜻한다.
- 트랜잭션 추상화, OXM 추상화, 데이터 액세스의 Exception 변환기능등 기술적인 복잡함은 추상화를 통해서 이를 분리했다.
- Low Level은 기술의 구현부로, 기술을 사용하는 부분은 Interface로 분리하여 사용하기 쉽도록 했다.
- IoC/DI
- DI 는 유연하게 확장 가능한 객체를 만들어 두고, 객체 간의 의존관계는 외부에서 동적으로 설정한다.
- AOP
- 관심사의 분리를 통해서 SW의 모듈성을 향상시킨 것.
- 공통 모듈을 여러 코드에 쉽게 적용할 수 있다.
Spring Module
- Spring Core
- Spring Framework의 핵심 기능을 제공하며, Core 컨테이너의 주요 컴포넌트는 Bean Factory 이다.
- Spring Context
- Spring을 컨테이너로 만든 것이 Spring Core의 Bean Factory라면, Spring Framework로 만든 것은 Context Module이며, 이 Moudle은 국제화된 메시지, Application 생명주기 이벤트, 유효성 검증 등을 지원함으로써 BeanFactory의 개념을 확장한다.
- Spring AOP
- 설정 관리기능을 통한 AOP기능을 Spring Framework에 통합
- Spring DAO
- Spring JDBC DAO 추상 레이어는 다른 데이터베이스 벤더들의 예외 핸들링과 오류 메시지를 관리하는 중요한 예외계층을 제공
- Spring ORM
- Spring은 여러 ORM(Object Relation Mapping) 프레임워크에 내장되어 Object Relational 툴(JDO, Hibernate, iBatis)을 제공
- Spring Web
- Web Context Module은 Application Context Module 상위에 구현되어, Web 기반 Application 에 Context를 제공한다.
- Spring Web MVC
- Spring Framework 는 자체적으로 MVC 프레임워크를 제공하여 웹 어플리케이션에 개발이 용이하도록 지원한다.
https://docs.spring.io/spring-framework/docs/4.2.8.RELEASE/spring-framework-reference/html/overview.html
Spring IoC Type
- Dependency Lookup
- JNDI Lookup
- Dependency Injection
- Setter Injection
- Constructor Injection
- Method Injection
Denpendency Lookup
의존관계를 외부에서 주입 받는 것이 아닌, 직접 필요한 의존 관계를 조회한다는 것을 뜻한다. Spring 의 Application Context 전체를 주입받게 되면, Spring Container에 종속적인 코드가 되고 이로 인해 단위테스트도 어려워지게 된다.
런타임시에 의존관계를 결정한다는 점에서 의존관계 주입과 비슷하지만, 의존관계를 맺는 방법이 외부로부터의 주입이 아니라 스스로 검색을 이용한다는 점에서 차이가 있다.
즉, DL(Dependency Lookup) 은 컨테이너가 lookup context를 통해서 필요한 Resource나 Object를 얻는 방식을 뜻한다.
✅ 의존관계 검색은 런타임 시 의존관계를 맺을 오브젝트를 결정한다.
✅ 오브젝트의 생성 작업은 외부 컨테이너에게 IoC로 맡기지만, 이를 가져올 때는 메소드나 생성자를 통한 주입 대신 스스로 컨테이너에게 요청하는 방법을 사용한다.
Dependency Injection
-
XML
-
xml 파일에서 <bean>
으로 설정
속성 | description |
---|
name | 주입받을 곳에서 호출 할 이름 설정 |
id | 주입 받을 곳에서 호출 할 이름 설정(유일) |
class | 주입 할 객체의 클래스 |
factory-method | Singleton 패턴으로 작성된 객체의 factory 메소드 호출 |
| |
-
생성자 주입
public Player(int num, String name){
this.num = num;
this.name = name;
}
<bean id = "" name="" class="com.Player">
<constructor-arg>
<value>31</value>
</constructor-arg>
<constructor-arg>
<value>홍길동</value>
</constructor-arg>
</bean>
or
<bean>
<constructor-arg value="31"/>
<constructor-arg value="홍길동"/>
</bean>
!# index나 type 이 다를 경우 문제가 생김
# 순서와 type을 지정한 경우
<bean>
<constructor-arg type="int">
<value>8</value>
</constructor-arg>
<constructor-arg index="0">
<value>8</value>
</constructor-arg>
<constructor-arg name="name">
<value>홍길동</value>
</constructor-arg>
</bean>
## 주입받는 대상이 객체(Reference) 인경우
<bean id="dao" class="com.dao.PlayerDao"/>
<bean>
<constructor-arg>
<ref bean="dao">
</constructor-arg>
</bean>
-
Setter 메소드로 주입 (Property 이용)
- 하위태그 이용
- 객체 주입시
- 문자열 또는 Primitive 주입시
- 속성 이용 : name 값을 주입할 property 이름(Setter의 이름)
- 객체 주입시
<property name="propertyName" ref="beanName"/>
- 문자열
- xml namespace 를 이용하여 설정
-
Collection 계열 주입
# List
<bean id="listdi" class="">
<property name="myList">
<list>
<value>20</value>
<value type="java.lang.Integer>20</value>
<ref bean="player"/>
</list>
</property>
</bean>
# (Set도 List와 동일)
# Map
<bean>
<property name="myMap">
<map>
<entry key="key1" value="hi"/>
<entry key="py" value-ref="player"/>
</map>
</property>
</bean>
<property>
를 통해서 setter 주입을 한다.
-
Annotation
-
@Resource
JSR-250 표준 Annotation으로 Spring 2.5.* 부터 지원하는 Annotation 이다. JNDI 리소스와 연관지어 생각할 수 있으며, 특정 Bean이 JNDI 리소스에 대한 injection을 필요로 하는 경우에는 @Resource
를 사용할 것을 권장한다.
- Spring 2.5부터 지원
- 타입 에 맞춰서 연결
-
@Autowired
Spring Framework 에서 지원하는 Dependency 정의 용도의 Annotation으로, Spring Framework에 종속적이긴 하지만 정밀한 Dependency Injection이 필요한 경우에 유용하다
- Spring 2.5부터 지원
- Spring만 사용가능
- 타입 에 맞춰서 연결
-
@Inject
JSR-330 표준 Annotation으로 Spring 3부터 지원하는 Annotation이다. 특정 Framework에 종속되지 않은 애플리케이션을 구성하기 위해서는 @Inject
를 사용할 것을 권장한다.
- Spring 3.0부터 지원
- Framework에 종속적이지 않음
- javax.inject-x.x.x.jar 필요
- 이름 으로 연결
-
<context:component-scan>
을 반드시 붙여준다.
Spring Bean Life Cycle
- 빈 생성
- 의존성 주입
- init callback
- Usage
- destroy callback
- 빈 소멸