: 자바 플랫폼을 위한 오픈소스 어플리케이션 프레임워크로 엔터프라이즈급 어플리케이션 개발을 위한 모든 기능을 종합적으로 제공하는 경량화된 솔루션.
: 의존성에 대한 컨트롤이 뒤바꼈다고?
class OwnerController{
private OwnerRepository repository = new OwnerRepository();
}
class OwnerController{
private OwnerRepository repo;
public OwnerController(OwnerRepository repo){
this.repo = repo;
}
//이후에는 repo를 사용하는 코드 작성
}
class OwnerContorllerTest{
@Test
public void create(){
OwnerRepository repo = new OwnerRepository();
OwnerController controller = new OwnerController(repo);
}
}
누군가 생성자에서 생성자로 주겠지라는 마인드로 만들어짐.
OwnerContorleerTest에서 OwnerRepository를 만들어서, OwnerController한테 생성자를 통해 넘겨줌. 이것이 바로 의존성 주입. 이런 형태가 바로 Inversion of Control.
: spring은 Ioc용 컨테이너를 제공해 줌. 빈(bean)을 만들고 엮어주며 제공해주는 역할.
ApplicationContext(Beanfactory) : 컨테이너의 가장 핵심적인 인터페이스
class OwnerController{
private OwnerRepository repo;
public OwnerController(OwnerRepository repo){
this.repo = repo;
}
//이후에는 repo를 사용하는 코드 작성
}
이런 코드들을 동작하게 만들어 주는 역할. 실제 코드에 ApplicationContext라는 단어는 찾아볼 수 없음. 빈들의 의존성을 관리해 줌.
빈 : 자기가 컨테이너 내부에 만든 객체들
OwnerController와 OwnerRepository를 예로 들면, 둘은 다 ApplicationContext 내부에서 만들어 주는 빈! 그래서 둘의 의존성은 Ioc 컨트롤러가 관리해 줌. 오로지 빈만 관리 가능.
하지만, Owner는 빈이 아님. 어떻게 알 수 있냐? => 인텔리제이에서 오른쪽에 초록 콩이 붙어있으면 빈ㅎㅎ
Ioc 컨테이너 자체도 빈으로 되어있음. 자기자신이. 따라서 볼려면 가져와서 볼 수 있음. 하지만 보통 직접 쓸일도, 볼일도 딱히 없음.
IOC는 DI와 DL에 의해 구현됨.
: 스프링 IoC 컨테이너가 관리하는 객체.
@Bean
public String keesun(){ // 메서드 이름이 빈의 이름이 됨.
return "keesun";
}
단, 이렇게 직접 bean을 등록하기 위해선 Configuration이라는 어노케이션을 가진 class안에 적용해야 함.빈을 꺼내서 쓰는 방법은?
@RestController
public class SampleController {
//@Autowired를 사용하여 bean을 꺼내 쓸 수 있음.
@Autowired
String keesun;
@GetMapping("/context")
public String context(){
return "hello" + keesun;
}
}
point. 오로지 빈들만 의존성을 관리해 줌!!!
빈을 사용하고 싶으면, 해당 class도 bean이 되어야 함.
오로지 bean만 bean을 의존할 수 있음
Bean Scope
: Bean이 존재할 수 있는 범위
스프링 컨테이너에서 함께 시작되어 종료될 때까지 스프링이 관리해주는데 이유는 스프링 빈들을 singleton scope로 관리되기 때문.
singleton
prototype
: 필요한 의존성을 어떻게 받아올 것인지?
객체가 서로 의존하는 관계가 되게 의존성을 주입함.
객체지향에서의 의존성 : 하나의 객체가 어떠한 다른 객체를 사용하고 있음을 의미.
IOC에서의 DI : 각 클래스 사이에 필요로 하는 의존관계를 빈 설정 정보를 바탕으로 컨테이너가 자동으로 연결해 줌.
@Autowired/ @Inject를 어디에 붙일지?
: 컨테이너에서는 객체들을 관리하기 위해 별도의 저장소에 빈을 저장하는데, 개발자들이 컨테이너에서 제공하는 API를 이용해 저장소에 저장되어있는 사용하고자 하는 빈을 검색하는 방법.
: 흩어진 코드를 한 곳으로 모으는 코딩 기법.
관점 지향 프로그래밍.
대부분의 소프트웨어 개발 프롯스는 OOP를 사용.
OOP는 객체지향 원칙에 따라 관심사가 같은 데이터를 한곳에 모아 분리하고 낮은 결합도를 갖게 하여 독립적이고 유연한 모듈로 캡슐화를 하는 것.
-> 하지만, 중복된 코드들이 많아져 가독성, 확장성, 유지보수성을 떨어뜨림. (?)
-> 자바의 장점과 정반대되는거 아닌가
이러한 문제를 보완하기 위해 핵심기능과 공통기능을 분리시켜 핵심 로직에 영향을 끼치지 않게 공통기능을 끼워 넣는 개발 형태로, 무분별하게 중복되는 코드를 한 곳에 모아 중복 되는 코드를제거할 수 있음.
공통 기능을 한 곳에 보관하여 공통 기능 하나의 수정으로 모든 핵심기능들의 공통기능을 수정할 수 있어 효율적인 유지보수가 가능하며 재활용성이 극대화 됨.
물론 OOP로도 AOP를 구현 가능하나, spring에서는 좀 더 편리하게 AOP를 사용할 수 있도록 지원중임.
: 잘 만든 인터페이스, 일관된 서비스 추상화
MySQL을 사용하다 Maria DB로 데이터베이스를 바꿔야하는 상황에서 데이터베이스마다 사용방법이 다르면? 아마 기존에 작성한 코드를 전부 지우고 새로 작성하거나, 다른 코드를 모두 찾아 일일이 수정해 주어야 함.
-> 그러나 스프링을 사용하면, 동일한 사용법을 유지한 채로 데이터베이스를 바꿀 수 있음.
- 스프링이 데이터베이스 서비스를 추상화한 인터페이스를 제공해주기 대문에 가능!
즉, 스프링은 Java를 사용하여 데이터베이스에 접근하는 방법을 규정한 인터페이스인 JDBC(Java DataBase Connectivity)를 제공하고 있음! 이러한 JDBC를 사용하면 이후 데이터베이스를 바꿔도 기존 작성한 데이터베이스 접근 로직을 그대로 사용할 수 있음.
이처럼 특정 기술과 관련된 서비스를 추상화하여 일관된 방식으로 사용될 수 있도록 한 것을 PSA라고 함.
@EnableCaching으로 사용.
@Cacheable, @CacheEvict 등등을 사용 가능.
CacheManager를 사용.
JCacheManager, ConcurrentMapCacheManager, EhCacheCacheManager ...
MVC란 Model view controller 구조로, 사용자 인터페이스와 비지니스 로직을 분리하여 개발하는 것.
우리의 코드는 서블릿일수도 있고 리엑티브일수도 있음. 이건 코드를 봐선 모르고 의존성을 확인해봐야함.
스프링의 핵심은 IOC, AOP, PSA. 대부분의 라이브러리는 PSA. spring framework가 제공해주고 있는 api는 90프로가 PSA로 추상화되어있는 abstraction 계층. 조금 더 유연한 코드를 작성할 수 있도록 좋은 인터페이스를 제공.
IoC는 OwnerControlloer가 OwnerRepository를 사용할 때, 오너컨트롤러가 직접 만들어서 사용하는 것이 아닌 누군가로부터 주입을 받아 디펜던시가 (오너레파지토리가 생성자를 통해) 들어온다 가정하고 코딩을 하면 됨. 실제 오너레파지토리 의존성을 주입해주는건 스프링이 하는 일! 구체적으로는 spring의 ApplicationContext가 해주는 것.
-> 왜 이렇게 할까?
: test를 작성하기가 더 쉬움.
AOP는 사방으로 흩어져서 존재하는 코드들이 있음. 다양한 인증, 권한확인 같은 것들을 한곳으로 모아 코딩할 수 있도록 해주는 프로그램 기법. 그 중 spring APO는 프록시를 사용해서 구현.
PSA는 대부분의 스프링이 제공해주는 api들이 PSA임. 컨트롤러, getMapping()같은 것들도 전부.
: 스프링 부트는 단독적이고, 상용화 수준의 스프링 기반 어플리케이션을 단지 실행할 수 있을 정도로 쉽게 만들 수 있음.
spring framework의 경우, dependency를 설정해 줄 때 설정 파일이 매우 길고, 모든 dependency에 대해 버전 관리도 하나하나 해주어야 함.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.5</version>
</dependency>
하지만, spring boot의 경우에는 dependency를 spring framework보다 쉽게 설정해 줄 수있으며, 버전 관리도 자동으로 해줌.
implementation 'org.springframework.boot:spring-boot-starter-web'
더해서, test 프레임워크를 사용하고자 하는 경우 spring framework의 경우에는 spring test, JUnit, Hamcrest, Mockito 등 모든 라이브러리를 추가해줘야 하지만, spring boot에서는 spring boot starter test만 추가해주면 됨.
configuration
: spring framework의 경우 configuration을 설정할 때도 매우 길고, 모든 어노테이션 및 빈 등록을 설정해 주어야 함.
- Thymeleaft 템플릿을 사용하기 위한 코드 작성 예시)
@Configuration
@EnableWebMvc
public class MvcWebConfig implements WebMvcConfigurer {
@Autowired
private ApplicationContext applicationContext;
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver =
new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
registry.viewResolver(resolver);
}
}
대신 spring boot에서는 applicationproperties파일이나 application.yml파일에 설정하면 됨.
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf
AutoConfiguration
: spring frame과 달리 spring boot에는 autoconfiguration이라는 것이 있음.
spring boot로 실행할 수 있는 어플리케이션을 만들기 시작하면, 클래스에 @SpringBootAplication이라는 어노테이션을 확인할 수 있음. 이를 통해 많은 외부 라이브러리, 내장 톰캣 서버 등이 실행될 수 있음.
@ComponentScan
: @Component, @Controller, @Repository, @Service라는 어노테이션이 붙어있는 객체들을 스캔하여 자동으로 Bean에 등록해줌.
@EnableAutoConfiguration
: @ComponentScan 이후 사전에 정의한 라이브러리들을 Bean에 등록해줌.
편리한 배포
: spring framework로 개발한 어플리케이션의 경우, war 파일을 web application server에 담아 배포한반면, spring boot framework는 Tomcat이나 Jetty 같은 내장 WAS를 가지고 있어, jar 파일로 간편하게 배포 가능.
이러한 장점들을 통해 spring boot framework는 spring framework보다 개발자가 더더욱 개발에만 집중할 수 있도록 도와줌.
요약하자면 spring boot는 표준 spring 프레임워크의 모든 기능을 포함하는 동시에 어플리케이션 개발을 훨씬 쉽게 만들어주는 프레임워크임.
spring과 비교할 때 모든 spring boot의 속성이 자동 구성되기 때문에 훨씬 더 짧은 시간에 어플리케이션을 시작하고 실행할 수 있음.