스프링이 추구하고자 하는 가치
•
유연함 -자바의 잃어버린 객체지향 언어적 장점을 다시 살릴 수 있도록 도와주는 도구
•
단순함 - 뛰어난 확장성으로 다른 많은 프레임워크 등과 쉽게 결합하여 사용할 수 있도록 할 것
OOP의 장점을 최대한 살린 것이 스프링이고, 이것을 기반으로한 접근 방법을 사용하면 스프링이 추구하던 아키텍처, 설계의 근간이 흔들릴 일 없이 확장되어 결국은 확장된 코드마저도 스프링과 같이 확장성이 뛰어나고 유지보수가 쉬운 코드가 될 수 있다.
객체지향의 원칙
•
객체지향의 5원칙
◦
SRP(Single Reponsibility Principle) : 단일 책임 원칙
▪
하나의 클래스는 하나의 책임만을 가져야 한다.
◦
OCP(Open Closed Principle) : 개방-폐쇄 원칙
▪
클래스는 확장에는 열려있고, 변경에는 닫혀있어야 한다.
◦
LSP(Liskov Substitution Principle) : 리스코프 치환 법칙
▪
서브 클래스는 언제나 상위 클래스로 교체할 수 있어야한다.
◦
ISP(Interface Segregation Principle) : 인터페이스 분리 원칙
▪
클라이언트는 자신이 사용하지 않는 메소드에 의존 관계를 맺으면 안 된다.
◦
DIP(Dependency Inversion Principle) : 의존 역전 원칙
▪
고차원 모듈은 저차원 모듈에 의존하면 안 된다. 이 두 모듈 모두 다른 추상화된 것에 의존해야 한다.
▪
추상화된 것은 구체적인 것에 의존하면 안 된다. 구체적인 것이 추상화된 것에 의존해야 한다.
•
높은 응집도와 낮은 결합도
응집도는 높을수록 결합도는 낮을수록 이상적인 모듈화이다.
◦
응집도 : 결합도는 서로 다른 모듈 간에 상호 의존하는 정도 또는 연관된 관계를 의미한다.
◦
결합도 : 응집도는 한 모듈 내부의 처리 요소들이 서로 관련되어 있는 정도를 말한다.
디자인패턴
디자인패턴이란 뭘까? 소프트웨어를 설계할 때 특정 맥락에서 자주 발생하는 고질적인 문제들이 또 발생했을 때 재사용할 할 수있는 훌륭한 해결책
•
전략패턴 (Strategy Pattern)
◦
독립적으로 분리된 오브젝트들을 상황에 맞춰 바꿔서 대응할 수 있는 패턴
•
템플릿 메소드 패턴 (Template Method Pattern)
◦
슈퍼클래스에서 기능의 일부를 abstract method 혹은 overriding 가능한 protected method로 만든 뒤 서브클래스에서 필요에 따라 메소드를 구현하도록 하는 패턴
•
메서드 팩토리 패턴 (Factory Method Pattern)
◦
템플릿 메소드 패턴과 원리는 같으나, 구체적인 오브젝트 생성 방법에 대해 결정하게 하는 것. 주로 Interface 타입 오브젝트를 반환하므로 서브 클래스는 다양한 방법으로 오브젝트를 생성하는 메소드를 작성 할 수 있다. 이 때 오브젝트 생성 방법과 클래스를 결정할 수 있도록 미리 정의해둔 메소드를 팩토리 메소드라고 한다.
•
싱글턴 패턴 (Singleton Pattern)
◦
생성자의 접근제한자를 private로 두고 객체를 불러오는 static 메서드를 통해서 메모리상에 하나의 오브젝트만 존재하게 하는 패턴
Inversion of Control (IoC)
제어의 역전이라 불리우는 IoC는 객체 생성의 대한 책임을 외부에 맡기는 패턴이다.
•
IoC를 이용하면 얻을 수 있는 장점
◦
관심사의 분리를 통해 SRP 원칙을 지키며 클래스 작성이 가능해진다.
◦
클래스가 수정되어도 주입받는 객체는 생성에는 관심이 없기 때문에 수정의 여파가 적어진다.
스프링의 IoC
•
Bean
◦
스프링이 제어권을 가지고 직접 만들고 관계를 부여하는 오브젝트
◦
오브젝트 단위의 애플리케이션 컴포넌트
•
Bean Factory
◦
스프링에서 빈 생성과 관계설정 같은 제어를 담당하는 오브젝트
◦
빈을 제어하는 IoC 기본 기능에 초점이 맞춰진 것.
•
Application Context
◦
빈 팩토리를 확장한 오브젝트
◦
애플리케이션 콘텐스트는 별도의 정보를 참고해서 빈의 생성, 관계 설정 등의 제어 작업을 총괄한다.
◦
직접 오브젝트를 생성하여 관계를 맺어주는 코드가 없고, 생성정보와 연관관계 정보를 별도의 설정정보를 통해 얻는다.
◦
애플리케이션 컨텍스트를 이용할때의 장점
▪
클라이언트는 구체적인 팩토리 클래스를 알 필요가 없다.
▪
애플리케이션 컨텍스트는 종합 IoC 서비스를 제공해준다.
▪
애플리케이션 컨텐스트는 빈을 검색하는 다양한 방법을 제공한다.
•
Configuration
◦
애플리케이션 컨텍스트가 IoC를 적용하기 위해 사용하는 메타정보로, 컨테이너의 어떤 기능을 세팅하거나 조정하는 경우에도 사용하지만 보통 IoC 컨테이너에 의해 관리되는 객체를 생성하고 구성할 때 사용된다.
•
Singleton Registry
일반적인 싱글톤 패턴을 이용할 경우 아래와 같은 문제가 발생한다.
•
private 생성자 때문에 상속을 시킬 수 없다.
•
생성자를 통해 객체에 동적으로 정보를 주입할 수 없기 때문에 테스트하기 힘들다.
•
서버 환경에서는 싱글톤이 하나만 만들어지는 것을 보장하지 못한다.
•
전역 변수와 같은 문제점을 발생시킬 수 있다. 특히 OOP에서는 더욱 문제가 된다.
때문에 스프링에서 제공하는 싱글톤 레지스트리를 통해서 자연스럽게 문제를 해결할 수 있도록 도와준다.
•
평범한 자바 클래스를 싱글톤으로 활용하게 해준다.
•
테스트에서 싱글톤 방식으로 사용될 클래스를 활용할 수 있다.
•
Bean Scope
빈이 생성되고 존재하고 적용되는 범위를 빈의 스코프라고 한다.
◦
싱글톤 스코프 : 일반적인 빈스코프로 단 하나의 빈을 만들어 활용한다.
◦
프로토타입 스코프: 컨테이너 빈을 요청할 때마다 매번 새로운 빈을 만든다.
◦
요청 스코프 : HTTP 요청이 생길 때마다 매번 새로운 빈을 만든다.
◦
세션 스코프 : 웹의 세션과 비슷한 스코프를 갖는다.
Dependency Injection (DI)
스프링은 흔히 IoC컨테이너라 불리우지만 그것만으로 스플링을 설명하기엔 다소 부족한 면모가 있다. 때문에 우리는 의존성 주입이라는 단어를 통해 스프링에 대한 설명을 완성할 수 있다.
•
의존관계 설정
◦
의존관계란 방향성이 존재하고, 한 쪽이 변하면 다른 한 쪽도 영향을 받는것을 의미한다.
◦
런타임 의존관계
▪
컴파일 단계에서 이미 정해진 의존관계가 아닌 런타임에서 생기는 의존관계를 의미한다.
•
의존관계 검색
public UserDao() {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(DaoFactory.class);
this.connectionMaker = context.getBean("connectionMaker", ConnectionMaker.class);
}
Java
복사
◦
Denedency Lookup
◦
객체를 스스로 검색해서 의존관계를 맺는것을 의미한다.
◦
DL에서는 검색을 하는 주체 객체는 꼭 스프링 빈일 필요가 없다
•
생성자 주입
◦
생성자 기반 의존성 주입 방식은 생성자의 인수를 사용해 의존성을 주입하는 방식이다.
◦
애너테이션 기반 DI에서 이용하기 적절하다
public class UserDao {
private ConnectionMaker connectionMaker;
public UserDao(ConnectionMaker connectionMaker) {
this.connectionMaker = connectionMaker;
}
}
Java
복사
•
수정자 주입
◦
수정자 메소드는 외부로부터 제공받은 오브젝트 레퍼런스를 저장해뒀다가 내부의 메소드에서 사용하게 하는 DI방식에서 활용하기 적당하다.
◦
Setter 기반의 DI는 XML을 이용한 관계설정에서 이용하기 적절하다.
public class UserDao {
private ConnectionMaker connectionMaker;
...
public void setConnectionMaker(ConnectionMaker connectionMaker) {
this.connectionMaker = connectionMaker;
}
}
Java
복사
XML을 이용한 의존성 설정
자바 코드 설정정보 | XML 설정 정보 | |
빈 설정파일 | @Conriguration | <beans> |
빈의 이름 | @Bean methodName() | <bean id=”methodName” ... |
빈의 클래스 | retrun new BeanClass() | class=”a.b.c.....BeanClass”> |
<?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="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="dirverClass" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/springbook"/>
<property name="username" value="spring"/>
<property name="password" value="book"/>
</bean>
<bean id="userDao" class="toby.springtoby01.UserDao">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
XML
복사
XML을 이용한 어플리케이션 컨텍스트
@Bean
public DataSource dataSource() {
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
dataSource.setDriverClass(com.mysql.jdbc.Driver.class);
dataSource.setUrl("jdbc:mysql://localhost/springbook");
dataSource.setUsername("spring");
dataSource.setPassword("book");
return dataSource;
}
Java
복사
XML을 이용한 Datasource 주입받기
정리
•
스프링은 개발자가 보다 객체지향에 집중할 수 있도록 만들어주는 프레임워크다.
•
스프링 IoC를 통해서 생성과 관계설정에 대한 책임에서 벗어날 수 있다.
•
스프링의 싱글톤 레지스트리는 기존 싱글톤의 단점을 보완한 방법이다.
•
관심사의 분리를 통해서 보다 응집률이 높고 SRP를 지킬 수 있는 클래스를 설계할 수 있다.
•
변경이 잦은 기능들은 인터페이스로 추상화 하여 구현하도록 한다.
프레임워크 vs 라이브러리
•
프레임워크 - 어플리케이션 코드가 프레임워크에 의해 사용된다.
•
라이브러리 - 라이브러리를 사용하는 어플리케이션 코드는 어플리케이션 흐름을 직접 제어한다.
즉, 오브젝트를 생성하고 관리하는 책임의 주체의 관점에 따라서 분류가 가능하다.
오브젝트의 동일성과 동등성
•
동일성 - 두 개의 오브젝트가 완벽하게 동일한지 판별
•
동등성 - 두 개의 오브젝트 내부의 값이 동일한지 판별