Using Lombok to Simplify the Code


The Problem
We use configuration-driven approach, that means we store a lot of configuration data in our database, so we can change the configuration at runtime.

To learn more about the feature service please check Building Troubleshooting Friendly Application - Using Feature Toggle.

We store the configuration data as json string in database,  please check Merge JSON Objects: Jackson + BeanUtils.copyProperties to learn how to use jackson and spring BeanUtils to merge two objects.

But one issue is that the class is getting bigger and bigger: it contains fields, their getter, setters, toString, hashCode, equals and extractXXX methods which returns Nonnull value - it read value from database, if not exists, either return coded default value or default value from from property file.

The Solution
Lombok comes to rescue. All we need is to add the @Data annotation, it will generate getter, setter, toString, hashCode, equals. This reduces lines of the class from 300+ to about 100.

Also we use SpringContextBridge to read default value from property file if the field isn't set in db.
@Data
public class SimpleConfig implements Serializable {
  private Boolean xxAsync;
  // more fields ...
  @JsonIgnore 
  //this will first read from db, if not set, read from property file, if still not set, return default hard-coded value
  public boolean extractXXAsync() {
      return MoreObjects.firstNonNull(xxAsyn,
              SpringContextBridge.getProperty("xx.xxAsync", true, Boolean.class));
  }
}

@Component
public class SpringContextBridge implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
        SpringContextBridge.applicationContext = applicationContext;
    }
    public static <T> T getBean(final Class<T> serviceType) {
        return applicationContext.getBean(serviceType);
    }
    public static <T> T getProperty(final String key, final T defaultValue, final Class<T> targetType) {
        return MoreObjects.firstNonNull(applicationContext.getEnvironment().getProperty(key, targetType), defaultValue);
    }
}
Configuration and Install
Add lombok into project's pom.xml. Then go to run java -jar .m2\repository\org\projectlombok\lombok\latest\lombok-latest.jar, install lombok to eclipse you are using. 
You may need run eclipse clean: eclipse4.5/Eclipse.app/Contents/MacOS/eclipse -clean

Lombok features
@Data
@Accessors(chain = true)
Make field readonly
@Setter(AccessLevel.NONE)
@EqualsAndHashCode(callSuper = true)
@Value
@Builder
@NonNull
@Synchronized
synchronized done right: Don't expose your locks.
@Log

@Cleanup

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)