반응형

Annotation


자바를 사용하며 많은 어노테이션들을 코드에 적용하고 사용해 왔지만 정작 어노테이션이 어떤 의미를 갖는 것인지, 어떻게 사용해야 하고 어떤 식으로 개발자에게 도움을 줄 수 있는지를 몰라 이에 대해 정리를 해보려 한다.

 

우선 어노테이션의 사전적인 의미는 "주석" 이다. 일반적으로 생각하는 주석의 의미와는 사뭇 다른데, 보통 코드에서 주석의 역할은 소스 코드로 표현하기 어려운 개발자의 의도 등을 설명하기 위해 사용되는 것으로 알고 있다. 반면 어노테이션은 자바 코드에 추가될 수 있는 메타데이터라는 의미를 갖는다. 

 

어노테이션의 특징


  • 컴파일러에게 코드 문법 에러를 체크할 수 있도록 정보를 제공
  • 소프트웨어 개발 툴이 빌드나 배치 시 자동으로 코드를 생성할 수 있도록 정보 제공
  • 어노테이션을 만들 때는 용도를 명확하게 해야 한다.
    • 소스 상에서만 유지할 것인지
    • 컴파일된 클래스에서도 유지할 것인지
    • 런타임 시에도 유지할 것인지

 

Built-In Annotation


@Override

  • 메소드가 오버라이드 됐는지 검증
  • 부모 클래스나 구현해야 할 인터페이스에서 해당 메소드를 찾을 수 없을 경우 오류 발생

@Deprecated

  • 메소드를 사용하지 않도록 유도
  • 만약 위 어노테이션이 붙은 메소드를 사용할 경우 컴파일 시 경고를 발생

@SuppresWarnings

  • 컴파일 경고를 무시

@SafeVarargs

  • 제너릭과 같은 가변 인자를 사용할 때 경고를 무시 (Java 7 이상)

@FunctionalInterface

  • 람다 함수 등을 위한 인터페이스를 지정
  • 메소드가 없거나 두 개 이상일 경우 컴파일 오류 발생 (Java 8 이상)

 

Meta Annotations


위의 Built-In Annotation 같은 경우는, 기본적으로 자바에서 제공하는 어노테이션이다. 자바에서는 이 외에도 Meta Annotation 이라는 것을 지원하는데 이들을 활용해 커스텀 어노테이션을 만들고 사용하는 것 또한 지원한다.

 

@Retention

  • 어노테이션의 Life Time 을 의미
  • Class
    • 바이트 코드 파일까지 어노테이션 정보를 유지
    • 하지만 리플렉션을 이용해 어노테이션의 정보를 얻을 수는 없다
  • Runtime
    • 바이트 코드 파일까지 어노테이션 정보를 유지
    • 리플렉션을 이용해 런타임시 어노테이션의 정보를 얻을 수 있다
  • Source
    • 컴파일 이후 사라지는 형태
  • https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/RetentionPolicy.html

@Documented

  • 문서에도 어노테이션의 정보가 표현된다

@Target

  • 어노테이션을 적용할 위치를 결정한다

@Repeatable

  • 반복적으로 어노테이션의 선언을 가능케 한다

 

Annotation 구조


@Inherited // 상속
@Documented // 문서에 정보가 표현
@Retention(RetentionPolicy.RUNTIME) // 컴파일 이후에도 JVM에 의해서 참조가 가능합니다
@Retention(RetentionPolicy.CLASS)   // Compiler가 클래스를 참조할 때까지 유효합니다
@Retention(RetentionPolicy.SOURCE)  // 컴파일 이후 사라집니다
@Target({
		ElementType.PACKAGE, // 패키지 선언시
		ElementType.TYPE, // 타입 선언시
		ElementType.CONSTRUCTOR, // 생성자 선언시
		ElementType.FIELD, // 멤버 변수 선언시
		ElementType.METHOD, // 메소드 선언시
		ElementType.ANNOTATION_TYPE, // 어노테이션 타입 선언시
		ElementType.LOCAL_VARIABLE, // 지역 변수 선언시
		ElementType.PARAMETER, // 매개 변수 선언시
		ElementType.TYPE_PARAMETER, // 매개 변수 타입 선언시
		ElementType.TYPE_USE // 타입 사용시
})
public @interface NesoyAnnotation{
	/* enum 타입을 선언할 수 있습니다. */
	public enum Quality {
		BAD, GOOD, VERYGOOD
	}

	/* String은 기본 자료형은 아니지만 사용 가능합니다. */
	String value() default "NesoyAnnotation : Default String Value";

	/* 배열 형태로도 사용할 수 있습니다. */
	int[] values();

	/* enum 형태를 사용하는 방법입니다. */
	Quality quality() default Quality.GOOD;
}

 

Custom Annotation 만들어보기


Nyang Annotation

  • Annotation 은 Runtime 에 적용한다.
  • 어노테이션의 적용 범위는 Method 로 한다.
@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,})
public @interface NyangAnnotation {
    String value() default "NyangAnnotation : Default String Value";
}

 

Nyang Object

class NyangObject {
    
    @NyangAnnoation(value = "I'm Annotation")
    public void annotationTest() {
        System.out.println("Hello! World!");
    }
}

 

ContextContainer

  • Java 의 Reflection 을 활용해 객체의 어노테이션을 Invoke 하고 Annotation 의 value 를 읽어오는 역할
class MyContextContainer {
	public MyContextContainer(){}
	/**
	 * 객체를 반환하기 전 어노테이션을 적용합니다.
	 * @param instance
	 * @param <T>
	 * @return
	 * @throws IllegalAccessException
	 */
	private <T> T invokeAnnonations(T instance) throws IllegalAccessException {
		Method[] methods = instance.getClass().getDeclaredMethods(); // Reflect으로 해당 클래스의 Method를 전부 조회합니다.

		for(Method method : methods){
			NyangAnnotation annotation = method.getAnnotation(NyangAnnotation.class); // Method들 중에 NyangAnnotation을 찾습니다.
			if(annotation != null) { // NesoyAnnotation이 존재한다면
				System.out.println(annotation.value()); // annotation의 value를 출력합니다.
			}
		}

		return instance;
	}

	/**
	 * 매개변수로 받은 클래스의 객체를 반환합니다.
	 * @param clazz
	 * @param <T>
	 * @return
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public <T> T get(Class clazz) throws IllegalAccessException, InstantiationException {
		T instance = (T) clazz.newInstance();
		instance = invokeAnnonations(instance);
		return instance;
	}
}

 

Main

public class Main {
	public static void main(String[] args) throws InstantiationException, IllegalAccessException {
		MyContextContainer demo = new MyContextContainer(); // Annotation을 호출할 Container를 선언합니다.
		NyangObject object = demo.get(NyangObject.class); // Container에서 클래스를 가져오면서 Annotation을 invoke합니다.
		object.annotationTest(); // Method를 호출합니다.
	}
}

 

결과

  • 기존 Method 에는 "Hello! World!" 만 출력하도록 했지만 어노테이션으로 인해 "I'm Annotation" 이 먼저 출력된다.

 

#Reference.

 

Java Annotation이란?

 

nesoy.github.io

 

'Study > Java' 카테고리의 다른 글

[Java] 서블릿 (Servlet) 과 JSP (Java Server Page)  (0) 2021.09.30
Java Version 별 차이점 정리  (0) 2021.07.04
JPA 란?  (0) 2021.06.18
반응형

서블릿 (Servlet)


서블릿을 한 줄로 정의하면 다음과 같이 표현할 수 있다고 한다.

클라이언트의 요청을 처리하고 그 결과를 반환하는,
Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술

서블릿은, 간단하게 말해 자바를 사용해 웹 애플리케이션을 만들기 위해 필요한 기술이다.

클라이언트가 어떤 요청을 했을 때 웹 서버는 그에 대응하는 응답을 다시 전송해야 하는데, 이러한 역할을 하는 자바 프로그램을 서블릿이라 한다.

예를 들어, 어떤 사용자가 로그인을 하려고 할 때, 사용자는 아이디와 패스워드를 입력한 뒤 로그인 버튼을 누른다. 그 때, 서버는 아이디와 패스워드를 확인하고 다음 페이지를 띄워줘야 하는데 이러한 역할을 수행하는 것이 바로 서블릿이다. 그래서 서블릿은 자바로 구현된 CGI 라 표현한다.

NOTE
CGI (Common Gateway Interface) 란, 웹 서버에서 동적인 페이지를 보여 주기 위해 임의의 프로그램을 실행할 수 있도록 하는 기술이다. 특별한 라이브러리나 도구를 의미하는 것이 아라 별도로 제작된 웹서버와 프로그램 간의 교환방식이다. CGI 방식은 어떤 프로그래밍 언어로도 구현이 가능하며, 별도로 만들어 놓은 프로그램에 HTML 의 Get / Post 로 클라이언트의 데이터를 환경변수로 전달하고, 프로그램의 표준 출력 결과를 클라이언트에 전송하는 것이다.

 

Servlet 의 특징


  • 클라이언트의 요청에 대해 동적으로 작동하는 웹 어플리케이션 컴포넌트
  • HTML 을 사용해 요청에 응답
  • Java Thread 를 이용해 동작
  • MVC 패턴에서 Controller 로 이용됨
  • HTTP 프로토콜 서비스를 지원하는 javax.servlet.http.HttpServlet 클래스를 상속받음
  • UDP 보다 처리 속도가 느림
  • HTML 변경 시 Servlet 을 재컴파일해야 함

일반적으로 웹서버는 정적인 페이지만을 제공한다. 그렇기 때문에 동적인 페이지를 제공하기 위해 웹 서버는 다른 곳에 도움을 요청하고 동적인 페이지를 작성해야 한다. 여기서 웹 서버가 동적인 페이지를 제공할 수 있도록 도와주는 어플리케이션이 서블릿이며, 동적인 페이지를 생성하는 어플리케이션을 CGI 라 한다.

 

Servlet 동작 방식


  1. 사용자가 URL 을 주소창에 입력하면 HTTP Request 가 서블릿 컨테이너로 전송된다
  2. 요청을 전송받은 서블릿 컨테이너는 HttpServletRequest, HttpServletResponse 객체를 생성한다
  3. web.xml 을 기반으로 사용자가 요청한 URL 이 어떤 서블릿에 대한 요청인지 찾는다
  4. 해당 서블릿에서 service 메소드를 호출한 뒤 클라이언트의 HTTP 요청에 따라 doGet() 또는 doPost() 를 호출한다
  5. doGet(), doPost() 메소드는 동적 페이지를 생성한 뒤 HttpServletResponse 객체에 응답을 전송한다.
  6. 응답이 끝나면 생성한 HttpServletRequest, HttpServletResponse 객체를 소멸시킨다.

 

서블릿 컨테이너 (Servlet Container)


서블릿 컨테이너는 서블릿에 대한 이해가 있다면 쉽게 이해할 수 있는데, 간단하게 말해 서블릿을 관리하는 컨테이너이다.

개발자가 서버에 서블릿을 생성했다고 이 서블릿이 알아서 동작하는 것이 아니라 서블릿을 관리해주는 것이 필요한데, 그러한 역할을 하는 것이 서블릿 컨테이너이다. 서블릿 컨테이너는 클라이언트의 요청을 받고 응답할 수 있도록 웹 서버와 소켓으로 통신하며, 대표적인 예로 아파치 톰캣이 있다. 톰캣은 실제로 웹 서버와 통신하며 JSP (Java Server Page) 와 서블릿이 통신하는 환경을 제공해준다.

 

서블릿 컨테이너의 역할


1. 웹 서버와의 통신 지원

서블릿 컨테이너는 서블릿과 웹 서버가 손쉽게 통신할 수 있도록 한다. 일반적으로 어플리케이션 간 통신은 소켓을 만들고 listen, connect, accept, send/recv 등의 작업이 필요하지만 서블릿 컨테이너는 이러한 기능을 API 로 제공해 복잡한 과정을 생략할 수 있도록 해 준다. 그럼으로써 개발자는 서블릿이 가져야 할 비즈니스 로직에만 집중해서 구현을 진행할 수 있도록 도와준다.

2. 서블릿 생명 주기 (Life Cycle) 관리

서블릿 컨테이너는 서블릿의 생성과 소멸을 관리한다. 서블릿 클래스를 로딩해 인스턴스화하고, 초기화 메소드를 호출하고, 요청이 들어오면 적절한 서블릿 메소드를 호출한다. 또한 서블릿이 소멸된 순간에는 적절하게 GC 를 수행해 개발자에게 편의를 제공한다.

3. 멀티쓰레드 지원 및 관리

서블릿 컨테이너는 사용자의 요청이 들어올 때마다 새로운 자바 쓰레드를 생성하는데, HTTP 서비스 메소드를 실행하고 난 뒤 쓰레드는 자동으로 소멸하게 된다. 원래는 이런 쓰레드의 생성과 소멸을 관리해야 하지만 서버가 다중 쓰레드를 생성 및 운영해주니 쓰레드의 안정성에 대해서는 걱정하지 않아도 된다.

4. 선언적인 보안 관리

서블릿 컨테이너를 사용하면 개발자는 보안에 관한 내용을 서블릿 또는 자바 클래스에 따로 구현하지 않아도 된다. 일반적으로 보안 관리는 XML 배포 서술지에 기록하는데, 보안에 대해 수정할 일이 생겨도 자바 소스 코드를 수정하여 다시 컴파일하지 않아도 보안 관리가 가능하다.

 

서블릿의 생명 주기


  1. 클라이언트의 요청이 들어오면, 서블릿 컨테이너 (이하 컨테이너) 는 해당 서블릿 인스턴스가 메모리에 있는 지 확인하고, 없을 경우 init() 메소드를 호출해 메모리에 적재한다. init() 메소드는 초기에 한 번만 실행되기 때문에 서블릿의 쓰레드에서 공통적으로 사용해야 할 것이 있다면 오버라이딩해 구현하면 된다. 실행 중 서블릿이 변경될 경우, 기존 서블릿을 파괴하고 init() 메소드를 다시 호출해 새로운 내용을 다시 메모리에 적재한다.
  2. init() 이 호출된 후 클라이언트의 요청에 따라 service() 메소드를 통해 요청에 대한 응답이 doGet() 또는 doPost() 로 분기된다. 이 때, 서블릿 컨테이너가 클라이언트의 요청이 들어왔을 때 생성한 HttpServletRequest, HttpServletResponse 객체에 의해 request, response 객체가 제공된다.
  3. 컨테이너가 서블릿에 종료 요청을 보내면 destroy() 메소드가 호출되는데, init() 과 마찬가지로 한 번만 실행되며 종료 시에 처리해야 하는 작업들은 destroy() 메소드를 오버라이딩해 구현하면 된다.

 

JSP (Java Server Page)


서블릿에 대해서 정리를 했는데, 그러면 JSP 는 무엇이고 JSP 와 서블릿의 차이는 무엇일까?

구조적인 차이점을 통해 설명을 하자면, 서블릿은 자바 소스 코드 내에 HTML 코드가 들어가는 형태인데 반해 JSP 는 HTML 소스 코드 내에 자바 코드가 들어가는 구조를 갖는 웹 어플리케이션 프로그래밍 기술이다. HTML 코드 내에서 자바 코드는 <% (SourceCode) %> 또는 <%= (SourceCode) =%> 의 형태로 들어가게 된다.

자바 소스 코드로 작성된 이 부분은 웹 브라우저로 보내는 것이 아니라 웹 서버에서 실행되는 부분이다. 웹 프로그래머가 소스 코드를 수정하고자 할 때에도 디자인 부분을 제외하고 자바 소스 코드 부분만 수정하면 되기에 효율적이다. 또한 컴파일 과정이 필요치 않고 JSP 페이지를 작성해 웹 서버의 디렉토리에 추가만 하면 사용이 가능하다.

 

서블릿의 규칙은 꽤나 복잡하기 때문에 JSP 가 등장하게 되었는데, JSP 는 WAS (Web Application Server) 에 의해 서블릿 클래스로 변환되어 사용된다.

 

JSP 동작 구조


웹 서버가 사용자로부터 서블릿에 대한 요청을 받으면 서블릿 컨테이너에 요청을 전달한다. 요청을 받은 컨테이너가 HTTP Request / Response 객체를 만들어, 이들을 통해 서블릿의 doGet() / doPost() 메소드를 호출한다. 만약 서블릿만 사용해 사용자가 요청한 웹 페이지를 보여줄 경우 out 객체의 println 메소드를 사용해 HTML 문서를 작성해야 하는데, 이는 코드의 추가/수정을 어렵게 하고 가독성도 떨어지기 때문에 JSP 를 사용해 비즈니스 로직과 프레젠테이션 로직을 분리한다.

 

여기서 서블릿은 데이터의 입력, 수정 등에 대한 제어를 JSP 에 넘겨 프레젠테이션 로직을 수행한 후 컨테이너에게 Response 를 전달한다. 이렇게 만들어진 결과물은 사용자가 해당 페이지를 요청하면 컴파일되어 자바 파일을 통해 .class 파일이 만들어지고, 두 로직이 결합되어 클래스화 되는 것을 확인할 수 있다.

즉, out 객체의 println 메소드를 사용해 구현해야 하는 번거로움을 JSP 가 대신 수행해준다고 할 수 있다.

 

#Reference.

 

[JSP] 서블릿(Servlet)이란?

1. Servlet(서블릿) 서블릿을 한 줄로 정의하자면 아래와 같습니다.  클라이언트의 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술 간단히 말해

mangkyu.tistory.com

 

'Study > Java' 카테고리의 다른 글

[Java] Annotation 이란?  (0) 2021.11.03
Java Version 별 차이점 정리  (0) 2021.07.04
JPA 란?  (0) 2021.06.18
반응형

Java 는 Version 별로 새로운 기능을 출시하는 등 큰 변경점이 있다. 버전 중에서도 LTS (Long Term Service) 버전들은 장기적으로 업데이트가 보장되므로 호환성이나 안정성 면에서 장점이 있다고 생각해 Java 8 과 11 의 각 변경점에 대해서 간단하게 정리를 해 보려고 한다.

 

Java 8

Java 8 은 2014 년 발표된 Java 버전으로 다음과 같은 주요 변경사항이 있었다.

  • Lambda 표현식
  • Stream API
  • java.time 패키지

람다 표현식 (Lambda Expression)

우선 람다 표현식이란, 익명 클래스의 한 개 메소드를 식으로 표현한 것이다. 여기서 익명 클래스란, 말 그대로 이름이 없는 클래스로 단 한 개의 객체만을 생성할 수 있는 일회용 클래스이다.

// 익명 클래스의 예
new Object() {
	int min(int x, int y) {
    	return x < y ? x : y;
    }
}
// 람다 표현식의 예
(x, y) -> x < y ? x : y;

이러한 람다 표현식은 매개변수로 전달될 수 있으며, 메소드의 결과값으로 반환될 수도 있다. 따라서 람다 표현식을 사용할 경우 기존의 불필요한 코드를 줄이고 작성된 코드의 가독성을 높일 수 있다. Java 8 부터는 이러한 람다 표현식을 사용해 자바에서도 함수형 프로그래밍이 가능하게 되었다.

스트림 API (Stream API)

자바에서는 여러 데이터를 저장하기 위해 배열 / 컬렉션을 사용한다. 그리고 이렇게 저장된 데이터에 접근하기 위한 방법으로 반복문이나 Iterator 를 사용해 매번 코드를 작성해야 했다.

하지만 이렇게 작성된 코드는 길이가 길고 가독성도 떨어지며, 코드의 재사용이 거의 불가능하다. 또한, 정형화된 처리 패턴을 가지지 못하기 때문에 데이터마다 다른 방법으로 접근해야 했다.

이러한 문제를 극복하기 위해 도입된 방법이 바로 스트림 API 이다. 스트림 API 는 데이터를 추상화해서 다루므로, 다양한 형태로 저장된 데이터를 위한 공통된 방법을 제공한다. 따라서 스트림 API 를 사용하면 배열이나 컬렉션 뿐 아니라, 파일에 저장된 데이터도 모두 같은 방법으로 다룰 수 있다.

 

다음은 스트림 API 를 사용한 예제이다.

// 정수형 배열에서의 스트림 생성
int [] arr1 = new int[]{1, 5, 11, 13, 20, 52};
Stream stream1 = Arrays.stream(arr1);
stream1.map(i -> i * 2);
stream1.filter(i -> i % 2 == 0); // 재사용이 불가능하기 때문에 에러 발생

// 정수형 배열에서 스트림 생성
int [] arr2 = new int[]{1, 5, 11, 13, 20, 52};
Stream stream2;
stream2 = Arrays.stream(arr2)
				.filter(i -> i % 2 != 0)	// {1, 5, 11, 13}
                .map(i -> i * 2);			// {2, 10, 22, 26}

java.time 패키지

java.time 패키지는 기존에 사용하던 Date 클래스나 Calendar 클래스의 문제를 해결하기 위해 새롭게 등장한 날짜/시간 API 패키지이다.

 

Java 11

Java 11 은 2018 년에 발표된 Java 버전으로 Java 8 이후 최초로 공개된 Java 의 LTS 버전이다. Oracle 은 Java 8 에 대한 지원을 2019 년에 중단했고, Java 11 은 많은 변화가 있었다.

 

Local-Variable Syntax for Lambda Parameters

jdk 10 버전에서 지역변수로 사용할 수 있는 var 가 새로운 feature 로 추가되었는데, jdk 11 버전에서는 var 를 람다 표현식을 쓰는 경우에, 전달되는 parameter 들의 타입을 추론할 수 있는 Feature 가 추가되었다.

list.stream()
	.map((var s) -> s.toLowerCase())
    .collect(Collectors.toList());

물론 기존의 람다 표현식에서도 타입을 생략하면, 컴파일러가 컴파일 시 s 의 타입을 String 으로 추론한다. 그렇다면, jdk 8 의 추론 방법이 더 간단한데 왜 이런 feature 가 추가되었을까?

Align the syntax of a formal parameter declaration in an implicitly typed lambda expression with the syntax of a local variable declaration.

JEP 323의 Goals 를 보면, 위와 같이 명시되어있는데 jdk 10 에서 명시적으로 선언되던 구문을 var 로 선언할 수 있게 되었고, 이런 특징을 람다 표현식에도 적용해, 암시적으로 선언되던 형태를 var 로 선언해 표현식을 통일할 수 있게 되었다.

또한, 이렇게 명시적으로 선언하면 람다표현식에서 어노테이션을 사용하는 경우 아래와 같이 조금 더 간단하게 코드를 작성할 수 있다.

list.stream()
	.map((@NotNull var s) -> s.toLowerCase())
    .collect(Collectors.toList());

HTTP Client (Standard)

jdk 9 에서 추가되고 jdk 10 에서 업데이트된 java.incubator.http 패키지가 인큐베이터에서 나와 java.net.http 패키지로 표준화되었다. 이 패키지가 개발된 이유는 아래와 같다.

  • 베이스가 되는 URLConnection API 가 현재는 거의 사용되지 않는 프로토콜을 염두에 두고 설계되었다.
  • HTTP/1.1 보다 너무 추상적이다.
  • 문서화가 잘 되어있지 않아 사용이 어렵다.
  • Blocking 형태로만 동작한다.
  • 유지보수의 어려움이 있다.

java.net.http 로 옮겨진 패키지의 기능은 아래와 같다.

  • Non-Blocking request and response 지원 (with CompletableFuture)
  • Backpressure 지원(java.util.concurrent.Flow 패키지를 통해 RX Flow 를 구현체에 적용)
  • HTTP/2 지원
  • Factory method 형태로 지원

ZGC : A Scalable Low-Latency Garbage Collector (Experimental)

jdk 11 에서 새롭게 등장한 가비지 콜렉터이다. ZGC 라고도 불리는 이 가비지 콜렉터는 아래의 몇 가지 목표를 가지고 개발되었다.

  • GC 일시 중지 시간은 10ms 를 초과하지 않는다.
  • 작은 크기(수백 메가) ~ 매우 큰 크기(수 테라) 범위의 힙을 처리한다.
  • G1 에 비해 어플리케이션 처리량이 15% 이상 감소하지 않는다.
  • 향후 GC 최적화를 위한 기반을 마련한다.
  • 처음에는 Linux / x64 를 지원한다. (향후 추가 플랫폼을 추가 지원할 수 있다.)

알다시피, JVM 으로 구동되는 어플리케이션의 경우는 GC 가 동작할 때 어플리케이션이 멈추는 현상은 성능에서 큰 영향을 끼쳐 왔다. 이러한 정지시간을 줄이거나 없앰으로써 어플리케이션의 성능 향상에 기여할 수 있다.

ZGC 의 주요한 원리는 Load Barrier 와 Colored Object Pointer 를 동시에 사용하는 것이다. 이를 통해 Java 의 어플리케이션 스레드가 동작하는 중간에, ZGC 가 객체 재배치 같은 작업을 수행할 수 있게 해준다.

 

이 외에도, 다양한 성능적 향상이 java 8 버전에 비해 제공된다고 한다.

'Study > Java' 카테고리의 다른 글

[Java] Annotation 이란?  (0) 2021.11.03
[Java] 서블릿 (Servlet) 과 JSP (Java Server Page)  (0) 2021.09.30
JPA 란?  (0) 2021.06.18
반응형

JPA 를 사용하지 않고 SQL 을 직접 다루게 되면, CRUD (Create, Read, Update, Delete) 기능 개발을 위해 SQL 을 작성하고, JDBC API (Java DataBase Connectivity API) 를 사용해 SQL 을 실행하고, 실행한 결과를 Java 의 객체로 매핑해야 한다. 하나의 기능을 위해서 이렇게 하는 것은 크게 불편하지 않을 수 있지만 여러 테이블을 다루고자 한다면, 매번 이 과정을 반복하는 것이 지루해질 수 있다. 또한 이렇게 개발한 시스템에서 데이터베이스에 추가적인 데이터를 저장하고자 한다면 SQL 부터 객체까지 모든 내용을 수정해야 한다.

 

비즈니스 요구 사항을 모델링한 객체를 Entity 라 칭하는데, SQL 에 의존한 개발 환경에서는 개발자들이 Entity 를 신뢰하고 사용할 수 없게 된다. 대신 DAO (Data Access Object) 를 열어 어떤 SQL 이 실행되고 어떤 객체들이 조회되는 지를 확인해야 한다. 이는 진정한 의미의 계층 분할이라 할 수 없다. 물리적으로는 SQL / JDBC API 를 DAO 에 숨겼을 지라도 논리적으로는 Entity 와 강한 의존관계를 갖게 되어 CRUD 기능 개발을 위해서나, 테이블의 필드 구성이 변경되었을 때 DAO 의 코드와 SQL 을 수정해야 한다.

 

JPA 를 사용하게 되면, 위의 문제를 간단하게 해결할 수 있다. 개발자는 직접 SQL 을 작성하지 않고 JPA 가 제공하는 API 를 사용할 수 있다. 그러면 JPA 가 개발자 대신 적절한 SQL 을 생성해 데이터베이스에 전달한다.

 

JPA 를 사용하는 간단한 예제는 다음과 같다.

 

// 저장 기능
jpa.persist(object);

// 조회 기능
String objectId = "id1";
Object object = jpa.find(Object.class, objectId);

// 수정 기능
Object object = jpa.find(Object.class, objectId);
object.setName("newName");

// 연관된 객체 조회
Object object = jpa.find(Object.class, objectId);
Group group = object.getGroup();

 

JPA (Java Persistence API) 는 Java 객체와 관계형 DB 사이에서 Data 를 접근, 관리하기 위한 Java 스펙이다. JPA 는 현재 Java 환경에서 ORM Standard 역할을 하고 있다. JPA 는 존재하는 어떤 상품이 아니라 단순한 Spec 이기 때문에, 그 자체로는 Interface 만 제공이 된다.

 

 

- Reference

[WikiBooks] What is JPA ? https://en.wikibooks.org/wiki/Java_Persistence/What_is_JPA%3F

 

Java Persistence/What is JPA? - Wikibooks, open books for an open world

The Java Persistence API (JPA) is a Java specification for accessing, persisting, and managing data between Java objects / classes and a relational database. JPA was defined as part of the EJB 3.0 specification as a replacement for the EJB 2 CMP Entity Bea

en.wikibooks.org

[Book] 자바 ORM 표준 JPA 프로그래밍 https://book.naver.com/bookdb/book_detail.nhn?bid=9252528 

 

자바 ORM 표준 JPA 프로그래밍

자바 ORM 표준 JPA는 SQL 작성 없이 객체를 데이터베이스에 직접 저장할 수 있게 도와주고, 객체와 관계형 데이터베이스의 차이도 중간에서 해결해준다. 이 책은 JPA 기초 이론과 핵심 원리, 그리고

book.naver.com

 

'Study > Java' 카테고리의 다른 글

[Java] Annotation 이란?  (0) 2021.11.03
[Java] 서블릿 (Servlet) 과 JSP (Java Server Page)  (0) 2021.09.30
Java Version 별 차이점 정리  (0) 2021.07.04

+ Recent posts