본문 바로가기

Java/Java

(JAVA) 애노테이션 프로세서

  • @Getter, @Setter, @Builder 등의 애노테이션과 애노테이션 프로세서를 제공하여 표준적으로 작성해야 할 코드를 개발자 대신 생성해주는 라이브러리.

롬복 사용하기

  • 의존성 추가

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.8</version>
    <scope>provided</scope>
</dependency>
  • IntelliJ lombok 플러그인 설치

  • IntelliJ Annotation Processing 옵션 활성화


롬복이 없다면?

public class Member {
    private String name;

    private int age;

    public boolean isSameAge(Member member) {
        return this.age == member.age;
    }


    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Member)) return false;
        Member member = (Member) o;
        return getAge() == member.getAge() &&
                getName().equals(member.getName());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getName(), getAge());
    }
}

의미없는 코드의 나열이 심해지고 이러한 이유로 비즈니스 코드를 해석하기가 힘들어진다.


getter, setter 생성자 제거 및 애노테이션 추가

@Getter
@Setter
@EqualsAndHashCode
public class Member {
    private String name;

    private int age;

    public boolean isSame(Member member) {
        return this.age == member.age;
    }


}

테스트코드 작성

public class MemberTest {
    private String name;
    private int age;

    @Test
    public void getterSetter() {
        Member member = new Member();
        member.setName("choi");

        Assert.assertEquals(member.getName() , "choi");

    }
}

결과

롬복 동작 원리

자바가 제공하는 애노테이션 프로세서 기반으로 동작

애노테이션 프로세서는 컴파일 시점에 끼어들어서 특정한 애노테이션이 붙어있는 소스코드를 참조하여 또 다른 소스코드를 만들어낼 수 있는 기능

 

문제는 애노테이션이 붙어있는 클래스의 정보를 트리 구조로 참조(AST) 

하지만 해당 AST는 원래 참조만이 가능하다(수정 불가) 

근데 수정이 되버림

 

 

바이트 코드를 살펴보면 애노테이션을 붙인것 만으로 소스코드가 조작이 된다.

 

이게 어떻게 가능한 것일까 수정이 안된다면서!!

 

공개된 API 중에 수정할 수 있는 타입을 이용해 타입 캐스팅을 이용하여 사용한다. (해킹아닌가...?)

 

자바 버전이 올라가면 내부API는 바뀌기 때문에 언제든지 바뀔 수 있다.

 

논란 거리

  • 공개된 API가 아닌 컴파일러 내부 클래스를 사용하여 기존 소스 코드를 조작한다.

  • 특히 이클립스의 경우엔 java agent를 사용하여 컴파일러 클래스까지 조작하여 사용한다. 해당 클래스들 역시 공개된 API가 아니다보니 버전 호환성에 문제가 생길 수 있고 언제라도 그런 문제가 발생해도 이상하지 않다.

  • 그럼에도 불구하고 엄청난 편리함 때문에 널리 쓰이고 있으며 대안이 몇가지 있지만 롬복의 모든 기능과 편의성을 대체하진 못하는 현실이다.

 

Immutables.org

Immutables Java annotation processors to generate simple, safe and consistent value objects. Do not repeat yourself, try Immutables, the most comprehensive tool in this field! Get started! Read guide... v2.8.2 News and announcements

immutables.github.io

 

google/auto

A collection of source code generators for Java. Contribute to google/auto development by creating an account on GitHub.

github.com


Code Link

branch : lombok-demo

https://github.com/mike6321/PURE_JAVA/tree/lombok-demo/TheJava/lombok-demo

 

mike6321/PURE_JAVA

Contribute to mike6321/PURE_JAVA development by creating an account on GitHub.

github.com

References

 

Experiences with the New Java 5 Language Features

Experiences with the New Java 5 Language Features by Jess Garms and Tim Hanson Originally published on BEA Dev2Dev December 2005 Abstract Java 5.0 is here, and many of you will be starting to use some of the new features added to this release of the JDK. E

www.oracle.com

 

SETT January 20 -

Reducing Boilerplate Code with Project Lombok by Michael Kimberlin, Senior Software Engineer Object Computing, Inc. (OCI) Contents Introduction "Boilerplate" is a term used to describe code that is repeated in many parts of an application with little alter

jnb.ociweb.com

 

Can I add a method to a class from a compile time annotation?

If I create a custom annotation (example: @SaveFuncName("saveMe") will add a method called saveMe() with some code my processor generates), can the javac compiler use my annotation processor to add a

stackoverflow.com

 

Lombok Execution Path

 

projectlombok.org

 

Processor (Java Platform SE 8 )

The interface for an annotation processor. Annotation processing happens in a sequence of rounds. On each round, a processor may be asked to process a subset of the annotations found on the source and class files produced by a prior round. The inputs to th

docs.oracle.com

 

 

 

 

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

(JAVA) 쓰레드의 개요(2)  (0) 2020.01.19
(JAVA) 쓰레드의 개요 (1)  (0) 2020.01.19
(JAVA) 클래스의 프록시 생성  (0) 2019.12.24
(JAVA) 다이나믹 프록시  (0) 2019.12.24
(JAVA) 프록시 패턴  (0) 2019.12.24