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
留言
張貼留言