아마 자바에서 책이나 이런데에는 설명이 없고 보통 spring공부를 할때 처음 만나보는것일거다.
아마 그나마 책에서 몇번 봣던게 @override일텐데 학부생때는 당시 어노테이션이란게 그냥 있구나 하고 넘어갔었다.
이거저것 일하면서 공부하는김에 어노테이션의 동작 원리 문득 궁금해졌다.
먼저 @override 생김새는 어떻게 생겼고 어떻게 구동될까?
@ovrride의 내부 모습이다.
package java.lang;
import java.lang.annotation.*;
/**
* Indicates that a method declaration is intended to override a
* method declaration in a supertype. If a method is annotated with
* this annotation type compilers are required to generate an error
* message unless at least one of the following conditions hold:
*
* <ul><li>
* The method does override or implement a method declared in a
* supertype.
* </li><li>
* The method has a signature that is override-equivalent to that of
* any public method declared in {@linkplain Object}.
* </li></ul>
*
* @author Peter von der Ahé
* @author Joshua Bloch
* @jls 8.4.8 Inheritance, Overriding, and Hiding
* @jls 9.4.1 Inheritance and Overriding
* @jls 9.6.4.4 @Override
* @since 1.5
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
그렇다면 저기서 @Target @Retetion, @interface등이 존재한다. 우리 입장에선 @Override 형태를 쉽게 썻던형태들이 저런 형태들로 계속해서 이루어진다 다른것들도 확인해보자
@GetMapping은 Spring에서 굉장히 많이쓰는 어노테이션이다
/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
/**
* Annotation for mapping HTTP {@code GET} requests onto specific handler
* methods.
*
* <p>Specifically, {@code @GetMapping} is a <em>composed annotation</em> that
* acts as a shortcut for {@code @RequestMapping(method = RequestMethod.GET)}.
*
* @author Sam Brannen
* @since 4.3
* @see PostMapping
* @see PutMapping
* @see DeleteMapping
* @see PatchMapping
* @see RequestMapping
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.GET)
public @interface GetMapping {
/**
* Alias for {@link RequestMapping#name}.
*/
@AliasFor(annotation = RequestMapping.class)
String name() default "";
/**
* Alias for {@link RequestMapping#value}.
*/
@AliasFor(annotation = RequestMapping.class)
String[] value() default {};
/**
* Alias for {@link RequestMapping#path}.
*/
@AliasFor(annotation = RequestMapping.class)
String[] path() default {};
/**
* Alias for {@link RequestMapping#params}.
*/
@AliasFor(annotation = RequestMapping.class)
String[] params() default {};
/**
* Alias for {@link RequestMapping#headers}.
*/
@AliasFor(annotation = RequestMapping.class)
String[] headers() default {};
/**
* Alias for {@link RequestMapping#consumes}.
* @since 4.3.5
*/
@AliasFor(annotation = RequestMapping.class)
String[] consumes() default {};
/**
* Alias for {@link RequestMapping#produces}.
*/
@AliasFor(annotation = RequestMapping.class)
String[] produces() default {};
}
마찬가지로 엄청 나게 많은 내부소스코드가 존재한다. 이런걸 하나하나따라가기 힘들다 그래서 우리는 검색의 힘과 어떻게 구동되는지 알아보자
@Target , @Retention ,@interface 를 공통적으로 쓰는걸 볼수있다.
이중에서 @Target 이 뭔지 알아보자 보면 Element 타입을 리턴해준다고 한다.
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
또 여기서도 넘어가기전 궁금하게 생긴다.
@interface,interface의 차이점은 뭘까 우리가 자바에서는 평상시에 interface를 통해서 자바의 다형을 높여 개발코드 유지보수나 코드를 깔금히 정리하기 위해 많이 사용된다 그렇다면 @interface는 차이가 뭘까 ?
스택오버플로우의 말을 빌려보자
@interface는 사실상 우리가는 annotation type 정의이다 실제 인터페이스처럼 사용하는게 아니라 @override 같은 함수
수정자로 사용되는 새로운 annotation type이라고합니다. 댓글들을 보니 @inteface는 annotation type들의 확장을 위한 기능이고 interface는 class를 위한 확장이라고 하는듯 하다. 그래서 @Target이 annotation type의 기능성을 확장시켜준것이다. 그렇다면 어떤 타입이이 존재할까?
public enum ElementType {
/** Class, interface (including annotation type), enum, or record
* declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE,
/**
* Module declaration.
*
* @since 9
*/
MODULE,
/**
* {@preview Associated with records, a preview feature of the Java language.
*
* This constant is associated with <i>records</i>, a preview
* feature of the Java language. Programs can only use this
* constant when preview features are enabled. Preview features
* may be removed in a future release, or upgraded to permanent
* features of the Java language.}
*
* Record component
*
* @jls 8.10.3 Record Members
* @jls 9.7.4 Where Annotations May Appear
*
* @since 14
*/
@jdk.internal.PreviewFeature(feature=jdk.internal.PreviewFeature.Feature.RECORDS,
essentialAPI=true)
RECORD_COMPONENT;
}
내부에 여러가지 타입으로 정의되어 있지만 기능은 정확히는 아직 모르겠다 그나마 자주 쓰는것은 Method나 type을 주로 사용했던것 같다.
현실적으로 온라인 '네트워크'의 지분 중 태반을 차지하는게월드 와이드 웹이기 때문에'웹' 기반의 전송을 위해 쓰이는 경우가 대부분이다.태생 자체가 데이터 송수신에 최적화 되어 있다보니 이를 위한 웹API쪽에서 굉장히 많이 쓰인다. 이를 'REST API'라고 부르는데, 이제는 그냥 '웹 API'와 동일하다고 볼 수 있을 정도로 보편화되었다.
-위키-
즉 웹개발에서 HTTP기반의 웹 API를 구현하면 그건 Rest를 준수한다고 생각하면된다.
좀더 쉽게 말하면 네트워크 웹 구조 설계를 의미한다.
그렇다면 Rest Api의 조건은 뭘까 ?
이것도 위키에서 빌려오겠다.
Client-Server
가장 심플하며 프로그래밍에서 네트워크 통신의 기본중에 기본 즉 서버와 클라이언트 관계이다.
Stateless
상태 정보를 따로 저장하지않고 다수의 이용자가 어디서든 접근해도 관계없이 동일한 결과를 얻는것이다.
이것도 네이버,다음 같은 웹도 다수의 사람들이 여러곳에서 접근해도 변하지않고 동일한 웹사이트를 보여준다.
Cache
Http를 비롯한 네트워크 프로토콜에서 제공하는 케싱 기능을 적용한다.
케시는 말그대로 빠르게 데이터를 가지고 오는 역활을 하는데 일반적으로 이미지 같은것들이나 반복적인 작업이 보여주는것들은 Cache를 사용한다.
Uniform Interface
데이터가 표준 형식으로 전송될수 있도록 구성 요소 간 통합 인터페이스이다.
(이부분은 조금 추후에 설명하도록 하겠다 이걸 설명하려면 일단 좀 길어져서 다음에 설명하도록 하겠다)
Self-descriptiveness
API를 통해 전송되는 내용은 별도 문서 없이 쉽게 이해할 수 있도록 자체 표현 구조를 지녀야 한다.