Spring with lombok - The first sight

 lombok project的誕生,是由於Java在框架實作上有許多無實質價值的code,藉此利用lomok annotation 取代撰寫code內容來增加生產力。

最常見的就是 Getters/setters 與Constructors的撰寫,畢竟在物件導向中用此封裝是常用的做法,如framework依賴Java Bean的模式。

@Entity
@Getter @Setter @NoArgsConstructor // <--- THIS is it
public class User implements Serializable {
...
也可以對物件參數做限制,例如ID只能get不能user set
private @Id @Setter(AccessLevel.PROTECTED) Long id;
還有其他功能像是 lazy getter,以及運用Annotation去創造建構子。而@Accessors(fluent = true) 則是把呼叫的語法變簡潔,如getKey()變成key()。
public class GetterLazy {

@Getter(lazy = true)
private final Map<String, Long> transactions = getTransactions();
...
}

@RequiredArgsConstructor
@Accessors(fluent = true) @Getter
    public class LoginResult {

    private final @NonNull Instant loginTs;
    ...
}
Builder annotation也對build object的行為做了簡化,不必再用一堆setA("test")的與法,直接.a("test")
@Builder
public class ApiClientConfiguration {

    ApiClientConfiguration config = ApiClientConfiguration.builder()
        .host("api.server.com")
        .port(443)
        .useHttps(true)
        .connectTimeout(15_000L)
        .readTimeout(5_000L)
        .username("myusername")
        .password("secret")
        .build();

}
也能藉由@Slf4j的方式省去加上LoggerFactory這一段
public class ApiClientConfiguration {

    private static Logger LOG = LoggerFactory.getLogger(ApiClientConfiguration.class);

    // LOG.debug(), LOG.info(), ...

}
//into
@Slf4j // or: @Log @CommonsLog @Log4j @Log4j2 @XSlf4j
public class ApiClientConfiguration {

    // log.debug(), log.info(), ...

}



回過頭來看 Constructor Injection in Spring with Lombok
在一般狀態中,以下兩個寫法做同樣的事 - 呼叫translator。而第二段在不使用autowired後顯得constructor沒什麼撰寫的價值,繞了一圈。
@Component
public class GreetingService {

    @Autowired
    private Translator translator;

    public String produce() {
        return translator.translate("hello");
    }
}

@Component
public class FarewellService {

    private final Translator translator;

    public FarewellService(Translator translator) {
        this.translator = translator;
    }

    public String produce() {
        return translator.translate("bye");
    }
}

Constructor Injection With Lombok
@AllArgsConstructor  產生所有參數的constructor
@RequiredArgsContructor 只產生所有final屬性的contractor
@NoArgsConstuctor 空的constructor
@Component
@RequiredArgsConstructor
public class ThankingService {

    private final Translator translator;

    public String produce() {
        return translator.translate("thank you");
    }
}
//實際就是產生下面的code

@Component
public class ThankingService {

    private final Translator translator;

    public String thank() {
        return translator.translate("thank you");
    }

    /* Generated by Lombok */
    public ThankingService(Translator translator) {
        this.translator = translator;
    }
}

Multiple Constructor
@Component
@RequiredArgsConstructor
public class ApologizeService {

    private final Translator translator;
    private final String message;

    @Autowired
    public ApologizeService(Translator translator) {
        this(translator, "sorry");
    }

    public String produce() {
        return translator.translate(message);
    }
}
如果自定義contractor(傳入的參數不同 ),除非contractor 使用Autowired, inject, resource,不然則有exception

用@AllArgsConstructor 的 onConstructor 參數來針對Lombok 自動產生的constructor上加上annotation
@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ApologizeService {
// ...
}
實際案例
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ValidateUserServiceImpl implements ValidateUserService {
    private final UserManagementClient userManagementClient;

    @Override
    public ValidateUserClientResponse validatePayPayUser(ValidateUserRequest         validateUserRequest) {
        return userManagementClient.validatePayPayUser(validateUserRequest);
    }
}


references:
https://www.baeldung.com/spring-injection-lombok

留言

這個網誌中的熱門文章

[專案] 銀行端末系統

如何在MacOS 中自由切換不同Python版本 - pyenv + virtualenv

用 C# 控制 Win7 輸入法