멀티캠퍼스 백엔드 과정42일차[8월 3일] - intellj, 스프링을 쓰는 이유, 스프링

GoldenDusk·2023년 8월 3일
0
post-thumbnail

✋ 스프링 쓰기 전에 잠깐

꼭.. Classpath에서 필요한 라이브러리 추가할 것

lib에도 추가해줄 것!

📌개념

객체지향 설계 5원칙(SOLID)

1. SCR

  • 단일 책임 원칙
  • 하나의 클래스는 하나의 책임을 가져야 한다.
  • 어떤 변화에 의해서 클래스를 변경해야 하나는 이유는 오직 하나 뿐이어야 한다.
    • 파생되는 변경만이 변경될 수 있다.
class Human{
	public void Sing(){}
	public void running(){}
	public void Cook(){}
	public void Study(){}

}

class Singer{
	public void sing(){}
}

class Student{
	public void study(){}
}

2. OCP [재사용성의 극대화]

  • 개방-폐쇄 원칙
  • 소프트웨어 구성요소(컴포넌트, 클래스, 모듈, 함수..)
  • 확장은 OPEN, 변경에는 닫혀 있어야 한다.
  • 기존은 최대한 재사용하게 설계한 후 최소한으로 받아들여 확장

3. LSP

  • 리스코프 치환의 원칙
  • 상속을 통한 재사용을 부모클래스와 서브 클래스 사이에 IS-A 관계가 있는 경우로 제한한다.
public interface Bird{
	public void fly(){}
}

public class Eagle implements Bird{ //Eagle is A Bird
	public void fly(){}
}

public class Tiger implements Bird{ //IS-A원칙 위반
	public void fly(){}
}

4. ISP

  • 인터페이스 분리의 원칙
  • 한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 말자
  • 최소한의 인터페이스로 설계해라

5. DIP

  • 의존 관계 역전의 원칙
  • 프로그래머는 추상화(인터페이스)에 의존해야지, 구체화(클래스)에 의존하면 안된다.
  • 요리사 객체는 피자레시피(인터페이스)에 의존하도록 하고

📌spring

1. 프레임워크의 중요성

💡 프레임워크는 말 그대로 뼈대나 근간을 이루는 코드들의 묶음으로 개발자 능력에 따라 결과 역시 큰 차이를 낳는데 이런상황을 극복하기 위해 나온 것이 프레임워크다. 프레임워크를 이용한다는 것은 프로그램의 기본 흐름이나 구조를 정하고, 모든 팀원이 이 구조에 자신의 코드를 추가하는 방식

  • 즉, 프레임워크의 최대 장점은 개발에 필요한 구조를 이미 코드로 만들어 놓았기 때문에, 실력이 부족한 개발자라 해도 반쯤 완성된 상태에서 필요한 부분을 조립하는 형태의 개발이 가능

2. 나오게 된 계기

💡 2000년대 초반부터 시작된 엔터프라이즈급의 개발은 안정된 품질의 개발이 절실했고, 그 결과 많은 프레임워크의 전성시대

  • spring은 가장 성공한 경량 프레임워크이다.

경량 프레임워크

  • 90년대 말에 복잡한 구동 환경과 하드웨어적인 구성이 필요한 프레임워크의 반대되는 개념으로 등장
  • 특정 기능을 위주로 간단한 jar 파일 등을 이용해서 모든 개발이 가능하도록 구성된 프레임워크
  • 클라이언트 중심, 모바일 중심, Light weight, 생산성, 안전성, 다양한 개발 언어

그렇다면 그 많은 것 중에 왜 성공했을까?

  1. 복잡함에 반기를 들어서 만들어진 프레임워크로 일반적으로 java클래스와 인터페이스를 이용하는 구조이기 때문에 진입장벽이 높지 않았기 때문이다.
  2. 프로젝트의 전체 구조를 설계할 때 유용한 프레임워크로 스프링은 어느 한 분야에 집중하지 않고, 전체를 설계하는 용도로 사용하며 근본적인 사상 자체가 OOP 구조를 뒷받침하고 구조를 설계하는 사상
  3. 다른 프레임워크들의 포용으로 다른 프레임워크들은 특정 프레임워크를 채택하면 해당 영역 전체를 수정해야 하는 고질적인 문제가 있으나, 스프링은 다른 프레임워크들과의 통합 지원했기 때문에 최소한의 수정이 가능했다. 스프링의 최대 장점은 기본 뼈대가 흔들지 않고 여러 종류의 프레임워크 혼용해서 사용 가능
  4. 개발 생산성과 개발도구의 지원으로 플러그인도 빠른 업데이트 되었기에 별도의 개발도구에 적응 없이도 개발 가능

3. 그렇다면 스프링의 특징은..?

제어 역행(IoC, Inversion of Control) 기술

  • 이용해 애플리케이션 간의 느슨한 결합을 제어함

의존성 주입(DI, Dependency Injection) 을 통한 객체 간의 관계 구성

  • 의존성(dependency)
    • 하나의 객체가 다른 객체 없이 제대로 된 역할을 할 수 없는 것을 말한다.
    • 하나의 객체가 다른 객체의 상태에 따라 영향을 받는 것을 의미
  • 주입(Injection)
    • 말 그대로 외부에서 밀어 넣는 것
  • 의존성 주입
    • 어떤 객체가 필요한 객체를 외부에서 밀어 넣는다.
  • 왜 사용하는 걸까?
    • 주입을 받는 입장에서는 어떤 객체인지 신경 쓸 필요가 없다.
    • 어떤 객체를 의존하든 자신의 역할은 변하지 않는다.
    • 스프링은 이러한 구조를 만드는데 적합한 구조로 설계되어 있다.
    • ApplicationContext라는 존재가 필요한 객체 생성하고 필요한 객체 주입시켜줌
    • ApplicationContext 이 관리하는 객체는 빈(bean)이라고 부름

영속성과 관련된 다양한 서비스를 지원함

수 많은 라이브러리와의 연동 기능을 지원함

APO의 지원

  • 반복적인 코드를 줄이고 핵심 비즈니스 로직에만 집중할 수 있게 해줌
  • APO 지원 관련은 여기서 적어둠

트랜잭션의 지원

  • 스프링은 이런 트랜잭션의 관리를 어노테이션이나 XML로 설정할 수 있기 때문에 매번 맞는 코드 작성 할 필요 없

POJO 방식 프레임워크

  • 내부에는 객체 간의 관계를 구성할 수 있는 특징을 지님
  • 다른 프레임워크와 달리 이 관계 구성 시 별도의 API를 사용하지 않는 POJO(Plan Old Java Object)의 구성이 가능하도록 제작
  • 즉, 일반적인 Java 코드를 이용해서 객체 구성하는 방식을 그대로 스프링에서 사용 가능
  • 코드를 개발 시 개발자가 특정 라이브러리나 컨테이너의 기술에 종속적이지 않기 때문에, 생산성에도 유리하고, 코드에 대한 테스트 작업 역시 좀 더 유연하다.

📌DI(Dependency Injection)

  • 스프링이 다른 프레임워크와 차별화되는 가장 큰 특징이다.
  • 객체를 직접 생성하는 게 아니라 외부(스프링 컨테이너)에서 생성 한 후 주입 시켜주는 방식
  • 모듈간의 결합도가 낮아지고 유연성이 높아지면 확장이 용이해진다.
  • 스프링 개념 이해

스프링(Spring) 프레임워크 기본 개념 강좌 (2) - 주요 구성 요소 & DI

1. 방법 1)

  • A객체가 B와 C 객체를 New 생성자를 통해서 직접 생성하는 방법

2. 방법 2)

  • 외부에서 생성된 객체를 setter()를 통해서 사용하는 방법
  • A객체에서 B, C 객체를 사용(의존)할 때 A객체에서 직접 생성하는 것이 아니라 IOC컨테이너에서 생성된 B,C 객체를 조립(주입)시켜 setter 방식 또는 생성자를 통해 사용하는 방식

3. Ioc(inversion of Control) : 제어의 흐름을 바꾼다.

  • 메소드나 객체의 호출작업을 개발자가 결정하는 것이 아니라, 외부(컨테이너)에서 결정된다.
  • 객체의 의존성을 역전시켜 객체간의 결합도를 줄이고 유연한 코드 작성 가능
  • 가독성 및 코드 중복, 유지보수의 편의성이 높아진다.

4. 기존 객체 생성하고 실행 절차

  • 객체 생성
  • 의존성 객체 생성( 클래스 내부에서 생성)
  • 의존성 객체 메소드 호출
class JDBConnection{

          public  JDBConnection(){

                      con;

                }

      }

    class MemberDAO(){

       MemberDAO(){

         JDBConnection connect = new JDBConnection();

           con = connect.getConnection();

           }

    }

5. 바뀌는 방식

  • 객체생성
  • 의존성 객체 주입
  • 의존성 객체 메소드 호출 (빈들은 싱글턴 패턴의 특징을 갖는다.)

의존성 주입 실습하기

1. property 이용

setter를 이용해서 값을 주입시 사용

  1. Person.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
                             "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>
<bean id="personService" class="com.spring.ex01.PersonServiceImpl">
	<property name="name">
		<value>홍길동</value>
	</property>
		<property name="age">
		<value>20</value>
	</property>
	</bean>
</beans>
  1. PersonServiceImpl.java
  • 빈이 관리하는 실제 값을 가지고 있는 PersonServiceImpl
package com.spring.ex01;

public class PersonServiceImpl implements PersonService {
	private String name;
	private int age;

	public void setName(String name) {
		this.name = name;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public void sayHello() {
		System.out.println("이름 : " + name);
		System.out.println("나이 : " + age);
	}
}
  1. PersonService.java
package com.spring.ex01;

public interface PersonService {
	public void sayHello();
}
  1. PersonTest.java
  • 실제 동작하는 빈에 대한 정보[데이터]를 알 수 없음, 인터페이스에서 껍데기[메소드]만 알 수 있음
package com.spring.ex01;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

public class PersonTest {

	public static void main(String[] args) {
		BeanFactory factory = new XmlBeanFactory(new FileSystemResource("person.xml"));
		PersonService person = (PersonService) factory.getBean("personService");
		// PersonService person = new PersonServiceImpl();
		person.sayHello();
	}

}

2. constructor-arg 이용

생성자를 이용해 값을 주입할 때 사용

  1. Person.xml
  • <bean>이 컨테이너 풀
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
                             "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>
<bean id="personService1" class="com.spring.ex01.PersonServiceImpl">
	<constructor-arg value="아이유" />
	</bean> 
	
<bean id="personService2" class="com.spring.ex01.PersonServiceImpl">
	<constructor-arg value="손흥민" />
	<constructor-arg value="24" />
	</bean> 
</beans>
  1. PersonServiceImpl.java
package com.spring.ex01;

public class PersonServiceImpl implements PersonService {
	private String name;
	private int age;
	
	public PersonServiceImpl() {}
	public PersonServiceImpl(String name) {
		this.name = name;
	}
	public PersonServiceImpl(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public void sayHello() {
		System.out.println("이름 : " + name);
		System.out.println("나이 : " + age);
	}
}
  1. PersonService.java
package com.spring.ex01;

public interface PersonService {
	public void sayHello();
}
  1. PersonTest2.java
package com.spring.ex01;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

public class PersonTest2 {

	public static void main(String[] args) {
		BeanFactory factory = new XmlBeanFactory(new FileSystemResource("person.xml"));
		PersonService person1 = (PersonService) factory.getBean("personService1");
		person1.sayHello();
		
		PersonService person2 = (PersonService) factory.getBean("personService2");
		person2.sayHello();
		
		// 빈을 프로그래머가 만드는 것이 아닌 모든 빈의 운영권을 컨테이너에게 위임
	}

}

3. 회원 기능 이용해 의존성 주입 실습

  1. MemberDAO.java : 인터페이스
package com.spring.ex02;

public interface MemberDAO {
	
	public void listMembers();
}
  1. MemberDAOImpl.java : 구현하는 객체
package com.spring.ex02;

public class MemberDAOImpl implements MemberDAO{

	@Override
	public void listMembers() {
		System.out.println("listMembers 메소드 호출");
		System.out.println("회원의 정보를 조회합니다.");
		
	}

}
  1. MemberService.java : 인터페이스
package com.spring.ex02;

public interface MemberService {
	
	public void listMembers();
}
  1. MemberServiceImpl.java : 구현하는 객체
package com.spring.ex02;

public class MemberServiceImpl implements MemberService{ //MemberService 구현 
	private MemberDAO memberDAO; //property name : memberDAO, 주입되는 빈을 저장할 memberDAO 타입의 속성 선언

	public void setMemberDAO(MemberDAO memberDAO) {
		this.memberDAO = memberDAO; //설정파일에서 memberDAO 빈을 생성한 후 setter 속성 memberDAO 주입
	}

	@Override
	public void listMembers() {
		memberDAO.listMembers();
		
	}
	
	
}
  1. MemberTest1.java : 메인 클래스
package com.spring.ex02;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

public class MemberTest1 {

    public static void main(String[] args) {
        BeanFactory factory = new XmlBeanFactory(new FileSystemResource("member.xml"));
        MemberService service = (MemberService) factory.getBean("memberService");
        service.listMembers();
    }

}
  1. member.xml
  • memberDAO가 memberService에게 주입(injection)된다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
                             "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>
<!-- 관계도를 등록한 것 -->
<!-- MemberSeviceImpl클래스를 이용하여 id가 "memberService"인 빈을 생성 -->
<bean id="memberService" class="com.spring.ex02.MemberServiceImpl">
	<!-- 빈을 만들면서 setter 주입방식으로 id가 "memberDAO"인 빈을 자신의 속성에 주입한다. -->
	<property name="memberDAO" ref="memberDAO" /> <!-- 포넌트 멤버 서비스 -->
</bean>
<!-- id가 "memberDAO"인 빈을 MemberDAOImpl을 이용해서 생성 -->
<bean id="memberDAO" class="com.spring.ex02.MemberDAOImpl" /> <!-- 꽂아주기 -->
</beans>

<!-- 의존하는 빈을 주입할 때는 주입되는 타입이 기본형데이터가 아닌 참조형 데이터일 경우 ref 속성을 이용해서 주입해야 한다.   -->

4. lazy-init

  1. lazy.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
                             "http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>
<!-- 동작 순서대로 작성하나 초기화 시점을 조정 가능 -->
<bean id="firstBean" class="com.spring.ex03.First" lazy-init="false" />
<bean id="secondBean" class="com.spring.ex03.Second" lazy-init="true" />
<bean id="thirdBean" class="com.spring.ex03.Third" lazy-init="default" />
</beans>
  • lazy-init

5. The IoC container

  1. First, Second, Third 다 똑같은 구조
package com.spring.ex03;

public class First {
	public First() {
		System.out.println("First 생성자 호출");
	}
}
  1. LazyTest : 메인
package com.spring.ex03;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class LazyTest {

	public static void main(String[] args) {
		ApplicationContext context = new FileSystemXmlApplicationContext("lazy.xml");
		System.out.println("SecondBean 얻기");
		context.getBean("secondBean");
	}

}
  1. 여기서 알아야 할 것!
  • 기본적으로 ApplicationContext 구현체들은 모든 싱글톤 빈을 초기화 과정의 일부로서 즉시 생성하고 구성
  • 지연 초기화된 빈은 IoC 컨테이너에 첫 요청시에 빈 인스턴스를 생성하도록 지시하며, 시작 시점에는 생성하지 않는다.
  • 지연 초기화
<bean id="secondBean" class="com.spring.ex03.Second" lazy-init="true" />
  • 즉시 초기화
<bean id="firstBean" class="com.spring.ex03.First" lazy-init="false" />
  • 그렇기 때문에 SecondBean이 먼저 나오지 않는 것

스프링 AOP 기능

관점 지향 프로그래밍의 등장

1. 웹 어플리케이션 개발 시 해킹에 대비한 보안기능 구현은 필수

  • 로깅 기능
    • 사용자의 접속 내역을 로그로 기록하는 기능
  • 트랜잭션
  • 예외처리
  • 이메일 통보 기능
  • 메세지 전송 기능
  • 규모가 있는 웹 애플리케이션일 경우 클래스의 메서드마다 이런 작업을 일일이 수작업으로 하기에는 시간도 많이 걸리고 소스 코드도 복잡해짐
    • 이렇게 되면 배보다 배꼽이 더 큰꼴로 보안 기능을 넣어줘야 함

2. AOP(Aspect-Oriented Programming)

  • 관점 지향 프로그래밍으로 해결 제시
  • 공통으로 사용하는 기능
  • 주기능과 보조 기능을 분리해서 메서드에 적용

3. AOP 관련 용어

용어설명
aspect구현하고자 하는 보조 기능을 의미합니다.
advice[2]aspect의 실제 구현체(클래스)를 의미
메서드 호출을 기준으로 여러 지점에서 실행됩니다.
joinpoint[4]advice를 적용하는 지점을 의미
스프링은 method 결합점만 제공합니다
pointcut[3]advice가 적용되는 대상을 지정

패키지이름/클래스이름/메서드이름을 정규식으로 지정하
여 사용 |
| target[1] | advice가 적용되는 클래스를 의미합니다. |
| weaving | advice를 주기능에 적용하는 것을 의미합니다. |

4. 스프링 프레임워크에서 AOP 기능을 구현하는 방법

  • 스프링 프레임워크에서 제공하는 API를 이용하는 방법
  • @Aspect애너테이션을 이용하는 방법

스프링에서 AOP 기능 사용하기

library 넣기

그 후에 라이브러리 넣어주면 됨!!

Intellj 설치

  • 서버 : application server를 apache-tomcat 누르고 설정

  • 라이브러리 추가

  • 서버 설정

  • 경로 보안상 설정 /로 바꿈

회고

오늘은 인텔리제이깔고 스프링했다. 인텔리제이가 내가 예전에 많이 쓴 안드로이드 프로그래밍이랑 비슷해서 반가웠다.

전에도 깔짝 만져보긴 했는데...이제는 이클립트에서 벗어나서 인텔리제이로 인텔제이로 다양한 툴을 만져보는 게 좋다고 한다. 이것저것 만져봐야지 오늘은 끝나고 cs 기술 면접 대비 스터디 진행했다. 내가 만든 노션 템플릿으로 진행!!! 발표 후 방향성에 대해서도 서로 대화를 나눴다.

일주일에 한 번씩 만나 발표하고 질문도 만들어오기로 했다. 며칠 공부한다고 늦게 잤더니 너무 피곤하다 내일 강의를 위해 오늘은 일찍 자자...

profile
내 지식을 기록하여, 다른 사람들과 공유하여 함께 발전하는 사람이 되고 싶다. gitbook에도 정리중 ~

0개의 댓글