오늘부터 스프링 공부를 하면서 만난 문제점들과, 앞으로 공부하는 내용을 공유하고자 합니다.
시작하기에 앞서 내가 뭘 공부하는지는 알아야 하기 때문에 스프링이 무엇인지 부터 알아봅시다
탄생 배경
엔터프라이즈급 시스템이 실패하는 이유 "복잡성을" 보고 해결하기 위해 나온 프레임워크입니다.
Spring이 등장하기 전 EJB(Enterpirse JavaBeans)을 사용했는데 하나의 기능을 구현하기 위해 상속, 인터페이스 구현 등 의존도가 너무 커짐에 따라 로드 존슨의 예제코드등을 통해 만든 프레임워크이다.
2002년 로드 존슨이 EJB의 문제점을 지적하면서 고품질의 확장 가능한 애플리케이션을 개발할 수 있음을 보여주고, 30,000 라인 이상의 기반 기술 예제 코드를 선보이면서 시작되었다
이후 유겐 휠러와 얀 카로프가 오픈소스 프로젝트를 제안하고 이후 지금까지 스프링의 핵심 코드 개발을 담당하고 있다.
엔터프라이즈(Enterprise)
대규모 조직에서 강력하고 여러 사용자에게 이용 가능하도록 설계된 응용 프로그램을 나타내는 전문 용어
프레임워크(FrameWork)
축구를 할 때 가장 필요한 도구 또는 공을 잘 차게 해주는 것은 무엇일까? 바로 "축구화"이다.
그런 것 처럼 개발자들이 프로그램을 만들 때에도 그 프로그램을 만들기 쉬운 프레임워크를 사용하여 개발한다
스프링 부트란?
처음 스프링을 시작할 때 용어가 정말 많아서 헷갈렸는데 그중 하나가 바로 스프링부트였습니다.
스프링부트는 웹 프로그램을 쉽고 빠르게 만들어 주는 웹 프레임워크다
개발의 반은 환경설정이라고 합니다. 만약 처음 스프링을 해보시거나 또는 환경설정이 아직 어렵다면 Spring initializr을 통해 스프링 부트를 생성해봅시다!
https://start.spring.io/에 접속하면 이러한 화면을 볼 수 있습니다
초기 스프링 환경설정을 할 때 번거로움을 많이 줄여줍니다.
하지만 사용법까지 들어가려면 글이 너무 길이질 거 같아 다음 글에서 이용해보도록 하겠습니다
스프링 특징 4가지
여기서는 용어들이 많이 등장해서 잘 이해가 안 가신다면 각 용어들에 대해 자세히 알아보신다면 더 이해가 잘 되실 거라고 생각합니다!
POJO (Plain Old Java Object)
스프링의 가장 큰 특징이라고 생각합니다 바로 POJO 프로그래밍을 지향한다는 것 POJO란 순수, Java만을 통해서 생성한 객체를 의미합니다.
좀 더 쉽게 말하면 다른 클래스. 인터페이스를 상속/implements 받아 메서드가 추가된 클래스가 아닌 일반적으루 우리가 알고 있는 getter, setter같이 기본적인 기능만 가진 자바 객체를 말합니다
public class Member {
private int id;
private String password;
private String email;
public int getId() {
return id;
}
public String getpassword() {
return password;
}
public String getName() {
return name;
}
public void setId(int id) {
this.id = id;
}
public void setPassword(String password) {
this.password = password;
}
public void setName(String name) {
this.name = name;
}
}
↑는 POJO 지향 코드 ↓POJO기반 코드가 아님
@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private MemberRepository memberRepository;
@Override
public UserDetails loadUserByUsername(String memberId) throws UsernameNotFoundException {
System.out.println("load");
Member member = memberRepository.findByMemberId(memberId);
if(member == null){
throw new UsernameNotFoundException(memberId + " : 사용자 존재하지 않음");
}
return new MyDetails(member);
}
}
이렇게요! 위와 같이 상속을 받지 않고 만들어지는 객체이기 의존성이 없고, 추후 유지보수에 효율적입니다.
-> 왜 유지보수에 효율적일까? 상속을 받지 않는다는 것은 신경 쓸 코드가 Member객체가 하나 뿐이다라고 생각할 수 있습니다.
만약 상속받고 있는게 많고 코드들을 바꿔야 한다면 그 코드들을 다 수정하는 일이 발생할 수도 있겠죠?
그렇다면 POJO는 유지보수가 편하며, 객체지향적인 다양한 설계가 가능하구나! 알고 넘어가시면 될 거 같습니다.
POJO를 위해 지원하는 기술 IOC/DI
IoC(Inversion of control)
제어의 역전이라고 불리는 IoC를 코드로 설명해보겠습니다.
class A {
public void methodOfA() {
B b = new B();
b.example();
}
}
class B {
public void example() {
...
}
}
위처럼 A는 B클래스의 메소드를 호출하고 있다면 "의존 관계를 맺는 것"이라고 볼 수 있습니다.
둘의 관계는 A가B에 의존하는 관계라고 표현할 수 있죠 A가 B클래스의 메소드(기능)을 가져다 쓰니까요
위의 의존 관계는 개발자의 의해 직접 만들어집니다, 왜냐하면 개발자가 직접 new 키워드를 사용해서 인스턴스를 생성하는 코드를 작성했기 때문입니다.
그런데 만약
class A {
public void methodOfA() {
B b = new B();
b.example();
C c = new C();
c.example();
}
class B {
public void example() {
...
}
}
class C {
public void example() {
...
}
}
위 예제처럼 A가 사용할 예제를 C로 바꿔주려면 어떻게 해야 할까요? 코드를 한줄 정도 바꿔주면 되겠죠..
하지만 그게 수십 수백개라면 이야기가 달라집니다, 수십 수백번 그러한 일을 해야겠죠
interface I {
void example();
}
class A {
private I i;
public A(I i){
this.i=i;
}
public void methodOfA(){
i.example();
}
}
class B implements I {
public void example() {
...
}
}
class C implements I{
public void example() {
...
}
}
하지만 스프링에서는 위 코드처럼 A는 자신이 사용할 객체를 스스로 생성하지 않고, 생성자를 통해 외부로부터 받아올 수 있습니다.
즉 A는 자신이 이용할 객체를 알지 못하고 할당된 example()메소드만 존재한다라고 알고 있습니다.
그렇다녀 A가 인스턴스화될 때 인자를 받아야겠죠 어떤 객체를 불러올 것인지
이처럼 개발자가 아닌 스프링이 A가 사용할 객체를 생성하여 의존 관계를 맺어주는 것을 IoC(Inversion of Control, 제어의 역전)라고 하며, 그 과정에서 C를 A의 생성자를 통해 주입해주는 것을 DI(Dependency Injection, 의존성 주입)라고 합니다.
AOP
AOP (Aspect Oriented Programming) 관점 지향 프로그래밍이라고 불리죠, 관점 지향은 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 모듈화 하겠다는 것입니다.
A의 주황색 부분을 수정해야 한다면 B,C에서도 일일히 찾아 수정해야겠죠? 하지만 이는 유지보수를 어렵게 만듭니다..
결국 AOP에서 각 관점을 기준으로 로직을 분리해네 필요한 부분만 모아서 어디에 적용시킬지 정의해주는 것입니다.
이렇게 오늘은 스프링에 특징 4가지 정도를 알아보았는데요..
어렵죠 저도 처음이론을 볼 때는 정말 어려웠는데 계속 보다보니까 조금은 이해가 더 되는 거 같습니다.
그러면 오늘은 여기서 끝내고 다음글에서 봅시다!
만약 글에 틀린내용, 궁금한 점 있으시다면 꼭 댓글 부탁드립니다! (대환영..)
'스프링' 카테고리의 다른 글
[Spring] TDD vs BDD 무엇인지알고 비교하기 (0) | 2023.03.12 |
---|---|
[Spring] Slice를 이용하여 무한스크롤 구현하기 (0) | 2023.02.12 |
[Spring] Spring Security이용한 JWT 로그인 구현기 (1) | 2023.01.28 |
[Spring] JWT Refresh Token 어디에 저장해야 할까? 그리고 꼭 저장해야 할까? (0) | 2023.01.25 |
[Spring] 자바의 대표적인 빌드 관리 도구 Maven vs Gradle 차이 (0) | 2023.01.04 |