[JAVA] 개념 정리6

NaSC·2022년 12월 21일
0

JAVA 기본개념

목록 보기
6/6

객체주입

  • 객체 주입 방식
// 1. 생성자주입(Constructor Injection)
@Component
public class MadExample {

    // final로 선언할 수 있는 보너스
    private final HelloService helloService;

    // 단일 생성자인 경우는 추가적인 어노테이션이 필요 없다.
    public MadExample(HelloService helloService) {
        this.helloService = helloService;
    }
}

// 2. 필드주입(Field Injection)
@Component
public class MadExample {

    @Autowired
    private HelloService helloService;
}

// 3. 수정자주입(Setter Injection)
@Component
public class MadExample {

    private HelloService helloService;

    @Autowired
    public void setHelloService(HelloService helloService) {
        this.helloService = helloService;
    }
}
  • 생성자주입을 권장하는 이유는?
  1. 순환참조를 방지할 수 있다.
  • 순환참조를 한 경우 다른방식은 애플리케이션이 아무 오류나 경고없이 구동이되서 문제가될 수 있지만, 생성자주입방식으로 실행시 BeanCurrentlyInCreationException이 발생하며 애플리케이션이 구동조차안된다. 생성자 주입 방법은 필드 주입이나 수정자 주입과는 을 주입하는 순서가 다르기 때문.
    ** 빈이란?

  • Spring IoC 컨테이너가 관리하는 자바 객체를 빈(Bean)이라는 용어로 부른다.

  • 우리가 new 연산자로 어떤 객체를 생성했을 때 그 객체는 빈이 아니다.

  • ApplicationContext.getBean()으로 얻어질 수 있는 객체는 빈이다.

  • 즉 Spring에서의 빈은 ApplicationContext가 알고있는 객체, 즉 ApplicationContext가 만들어서 그 안에 담고있는 객체를 의미한다.

    즉 순환참조가 발생하는 경우 애플리케이션이 구동되지 않는다.

  1. 테스트에 용이하다
  • 독립적으로 인스턴스화가 가능한 POJO(Plain Old Java Object)를 이용한 테스트 코드를 만들수있다.
  1. 가독성이 좋아진다.
  • 의존성이 명시적으로 드러나는 장점이있음.
  1. 불변성
  • 필드를 final로 선언함으로써 객체를 변경해 발생할 수 있는 오류를 사전에 방지할 수 있다.

redirect vs forward

— redirect

  • web container는 redirect 명령이 들어오면 웹브라우저에게 다른 페이지로 이동하라는 명령을 내린다.
  • 웹브라우저는 url을 지시된 주소로 바꾸고 그 주소로 이동한다.
  • 다른 web container에 있는 주소로 이동이 가능하다.
  • 새로운 페이지에서는 request, response 객체가 새롭게 생성된다.
  • < 최초 요청 받은 url1에서 클라이언트에 redirect할 url2를 리턴하고, 클라이언트에게 전혀 새로운 요청을하여 url2에 다시 요청을 보냄. 따라서, 처음 보냈던 최초의 요청정보는 더이상 유효하지 않음 >

—forward

  • web container 차원에서의 페이지 이동, 실제로 웹브라우저는 다른 페이지로 이동했는지 알수없다.
  • 웹 브라우저에는 최초 호출한 url만 표시되고, 이동한 페이지의 url정보는 볼수없다.
  • 동일한 web container에 있는 페이지로만 이동이 가능하다.
  • 현재 실행중인 페이지와 forawrd에 의해 호출될 페이지는 request, response객체를 공유한다.
  • < 말그대로 forward(건내주기) 이동한 url로 요청정보를 그대로전달. >

— 차이점

  • URL의 변화여부 ( redirect → 변화 , forward → 변화 X )
  • 객체의 재사용 여부 ( redirect → 재사용X, forward → 재사용 )

jpa vs mybatis

— JPA

  • JAVA ORM 기술에 대한 API 표준명세.
  1. 장점

    1-1. 쿼리를 하나하나 작성할 필요가 없어 코드량이 줄어든다

    1-2. 가독성이 좋다.

    1-3. 간편하게 수정이 가능하다. (유지보수, 리팩토링 용이)

    1-4. 동일한 쿼리에 대한 캐시기능을 사용하기 때문에 더욱 높은 성능을 낼 수 있다.

  2. 단점

    2-1. 매핑설계를 잘못했을 때 성능저하

    2-2. JPA를 제대로 사용하려면 학습하는데 오래걸린다.

    2-3. 다수의 테이블 조인시 신경써야할게 많다.

— Mybatis

  • SQL 실행결과를 자바 빈즈 또는 Map 객체에 매핑해주는 Persistence 솔루션으로 관리한다. SQL을 소스코드가 아닌 XML로 분리한다.
  • SQL문과 프로그래밍 코드를 분리해서 구현한다.
  • 데이터소스 기능과 트랜잭션 처리 기능을 제공한다.
  1. 장점

    1-1. 접근이 쉽고 코드가 간결하다.(배우기 쉽다.)

    1-2. SQL문과 프로그래밍 코드가 분리되어있어서 SQL문에 변경이 있을 때마다 자바 코드를 수정하거나 컴파일 하지 않아도 된다.

    1-3. 다양한 프로그래밍 언어로 구현이 가능하다.(이식성이 뛰어나다)

  2. 단점

    2-1. 스키마 변경시 SQL 쿼리를 직접 수정해야 한다.

    2-2. 반복된 쿼리가 발생하여 반복작업이 있다.

    2-3. 쿼리를 직접 작성하기 때문에 데이터베이스에 종속된 쿼리문이 발생할 수 있다.

    2-4. 데이터베이스 변경 시 로직도 함께 수정해주어야 한다.

페이지 교체 알고리즘(FIFO/OPT/LRU/LFU/MFU)

  • 필요한 페이지가 메모리에 없을 때 page-fault가 발생하고 Backing Store에서 해당 페이지를 찾아 빈 프레임에 로딩해야하는데, 이때 빈 프레임이 없을 경우 희생당할 프레임(victim frame)을 고르는 알고리즘이 페이지 교체 알고리즘이다.
  1. FIFO알고리즘(First In First Out)
  • FIFO 알고리즘은 말그대로 가장 먼저 메모리에 올라온 페이지를 가장 먼저 내보내는 알고리즘이다.
  • 구현은 간단하지만 성능은 좋지 않은편이다.
  • 들어온 시간을 저장하거나 올라온 순서를 큐를 이용해 저장할 수 있다.
  • Belady’s Anomaly( 프레임 개수가 많아져도 page-fault가 줄어들지 않고 늘어나는 현상)
    현상이 발생할 수 있다.
  1. OPT(Optimal)알고리즘
  • 가장 오랫동안 사용하지 않을 페이지를 교체하는 알고리즘
  • 모든 페이지 교체 알고리즘 중 page-fault 발생이 가장 적다.
  • Belady’s Anomaly 현상이 발생하지않는다.
  • 프로세스가 앞으로 사용할 페이지를 미리 알아야한다.
  • 실제로 구현하기 거의 불가능한 알고리즘이다.
  • 실제로 사용하기보다 연구목적을 위해 사용된다.
  1. LRU(Least Recently Used) 알고리즘
  • 가장 오랫동안 사용하지 않은 페이지를 교체하는 알고리즘이다.
  • 최적 알고리즘과 비슷한 효과를 낼 수 있다.
  • 성능이 좋은 편이다.
  • 많은 운영체제가 채택하는 알고리즘이다.
  1. LFU(Least Frequently Used) 알고리즘
  • 참조횟수가 가장 적은 페이지를 교체하는 알고리즘
  • 교체대상이 여러개라면 가장 오랫동안 사용하지 않은 페이지를 교체한다.
  1. MFU(Most Frequently User) 알고리즘
  • LFU와 반대로 참조횟수가 가장 많은 페이지를 교체하는 알고리즘이다.

mybatis cache

  • local session cache

  • 임의로 켜거나 끌 수 없고 ,무조건 활성화

  • SqlSession 객체마다 가지고 있는 캐시… 켜거나 끌 수없지만 적용범위는 조정 가능

    default는 적용범위는 SESSION으로 되어있음.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
	PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
	<settings>
		<setting name="localCacheScope" value="STATEMENT" /> <!-- STATEMENT / SESSION -->
	</settings>
</configuration>

SESSION 적용시

  • 세션을 적용했을 때, 캐시정보의 생존범위는 세션이 유지되는순간까지이다. 즉, 트랜잭션이 끝나거나 insert, update, delete가 실행되면 로컬캐시가 보유하고있던 캐시정보는 사라진다.

STATEMENT 적용시

  • statement 하나가 끝나면 바로 캐시데이터를 폐기하고 다음번 데이터 찾을 때 다시 새로운 데이터를 찾는데 시간을 소모한다.

  • 따라서 statement로 설정하고 일반적으로 mapper를 구성해서 사용하면 거의 캐시를 사용하지 않는것과 비슷한 효과를 낼것..

  • second level cache

  • mapper namespace단위로 동작하여 켜거나 끌 수 있음.

( mapper.xml 파일안에 입력하면 됨 )

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
	PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.TestMapper">
	<cache/>
	...
</mapper>

위의 mapper의 namespace는 “mapper.TestMapper”이며, 여기서 선언한 모든 SQL에 대해서는 Cache가 적용된다. 각 mapper에서 설정한 cache 기능을 일괄적으로 disable하고 싶으면, Global configuration에 선언하면됨.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
	PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<settings>
		<setting name="cacheEnabled" value="false"/>
	</settings>
	<environments default="testdb">
		<environment id="testdb">
		<transactionManager type="JDBC" />
		<dataSource type="POOLED">
			<property name="driver" value="com.mysql.jdbc.Driver" />
			<property name="url" value="jdbc:mysql://localhot:3306/test?characterEncoding=utf8" />
			<property name="username" value="test" />
			<property name="password" value="test" />
		</dataSource>
	</environments>
	<mappers>
		<mapper resource="mybatis/test_mapper.xml" />
	</mappers>
</configuration>

cacheEabled 값 false처리.. default는 true이다.

local cache는 statement 실행후 commit이 되면 캐시를 지우는데, second level cache는 commit을 해도 캐시데이터가 살아있다.

lombok 사용시 주의사항

  1. @ALLArgsconstructor, @RequiredArgsConstructor 사용금지
  2. 무분별한 @EqualsAndHashCode 사용 자제
  3. @Data 사용 금지
  4. @Value 사용 금지
  5. @Builder 를 생성자나 static 객체 생성 메소드에
  6. @LOG
  7. @NonNull 사용 금지
  8. @ToString , @EqaulsAndHashCode 필드명 지정 시 오타 문제
  • lombok.config 를 통해 애노테이션 사용금지 및 각종 설정이 가능하다.
config.stopBubbling = true
lombok.data.flagUsage=error
lombok.value.flagUsage=error
lombok.val.flagUsage=error
lombok.var.flagUsage=error
lombok.nonNull.flagUsage=error
lombok.allArgsConstructor.flagUsage=error
lombok.requiredArgsConstructor.flagUsage=error
lombok.cleanup.flagUsage=error
lombok.sneakyThrows.flagUsage=error
lombok.synchronized.flagUsage=error
# experimental 전체 금지
lombok.experimental.flagUsage=error

참고: https://kwonnam.pe.kr/wiki/java/lombok/pitfall

resultMap

  • myBatis에서 제공하는 자동 매핑으로 해결이 어려운 경우를 위해 구조를 설계할 수 있도록 만들어진 도구.
  • 계층형 구조를 불러올때 적합(객관식 시험같은..)

참조: http://www.sysout.co.kr/home/webbook/page/read/643;jsessionid=54B3D5320E73A41FC4088D5E3D322141

# vs $ 차이점

  • SpEL( Spring expression language ) 을 표기할 때 사용,

    #{표현식}

  • ${ } 표기는 SpEL이 아니라 프로퍼티를 참조할때 사용

    ${property.name}

  • 표현식은 프로퍼티를 가질 수 있지만, 프로퍼티는 표현식을 가지지 못한다
    #{${my.data} + 1}

connection pool

  1. 웹 컨테이너(WAS) 실행
  2. DB와 미리 connection 해놓은 객체들을 pool에 저장
  3. 클라이언트 요청으로 connection을 빌려줌
  4. 처리 후 다시 connection 반납받아 pool에 저장

사용자가 요청할때마다, connect, disconnect를 반복하는 것이 비효율적이기 때문에

커넥션풀(DBCP) 사용

참조 : https://linked2ev.github.io/spring/2019/08/14/Spring-3-커넥션-풀이란/

spring mvc 라이프 사이클

  1. Filter
  • WEB 어플리케이션의 전역적인 로직 담당
  1. DispatcherServlet
  • 모든 Request를 우선적으로 받아 처리해주는 서블릿
  • request에 대해 어느 컨트롤러로 매핑할것인지 배치하는 역할
  1. HandlerMapping
  • DispatcherServlet으로부터 검색을 요청받은 컨트롤러를 찾아 정보 리턴
  1. HandlerInterceptor
  • request가 컨트롤러에 매핑되기 전 앞단에서 부가적인 로직 끼워넣음
  1. Controller
  • Request에 대해 어떤 로직으로 처리할 것인지 결정하고 그에 맞는 service 호출
  1. Service
  • 데이터 처리 및 가공을 위한 비즈니스 로직 수행
  1. Repository
  • DB에 접근하는 객체
  1. ViewResolver
  • 컨트롤러에서 리턴한 뷰의 이름을 DispatcherServlet으로부터 넘겨받고 해당 뷰를 렌더링한다.
  • 렌더링한 뷰는 DispatcherServlet으로 리턴하고, DispatcherServlet에서는 해당 뷰 화면을 Response함.

참조: https://velog.io/@damiano1027/Spring-Spring-MVC-Request-Lifecycle

profile
데이터엔지니어 😘

0개의 댓글