Skip to content

Instantly share code, notes, and snippets.

@bsideup
Created December 14, 2016 19:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bsideup/294862e3fa276fd1363f0f5026bfee44 to your computer and use it in GitHub Desktop.
Save bsideup/294862e3fa276fd1363f0f5026bfee44 to your computer and use it in GitHub Desktop.
import java.util.Date;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Function;
class Application {
public static void main(String[] args) throws Exception {
System.out.println("[" + new Date() + "] initialized");
ApplicationContext context = new ApplicationContext();
context.registerBean(DBTemplate.class, ctx -> ctx.getBeanAsync(Connection.class).thenApply(DBTemplate::new));
context.registerBean(Application.class, ctx -> ctx.getBeanAsync(CachedRepository.class).thenApply(Application::new));
context.registerBean(CachedRepository.class, ctx -> {
CompletableFuture<DBTemplate> dbTemplate = ctx.getBeanAsync(DBTemplate.class);
CompletableFuture<CachingTemplate> cachingTemplate = ctx.getBeanAsync(CachingTemplate.class);
return CompletableFuture
.allOf(dbTemplate, cachingTemplate)
.thenApply(unused -> new CachedRepository(dbTemplate.getNow(null), cachingTemplate.getNow(null)));
}
);
context.registerBean(Connection.class, ctx -> CompletableFuture.supplyAsync(() -> {
try {
// Simulate slow connection creation
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return new Connection();
}));
context.registerBean(CachingTemplate.class, ctx -> CompletableFuture.supplyAsync(() -> {
try {
// Simulate cache warmup
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return new CachingTemplate();
}));
System.out.println("[" + new Date() + "] configured");
context.start();
System.out.println("[" + new Date() + "] started");
Application scratch_6 = context.getBean(Application.class);
System.out.println("[" + new Date() + "] resolved");
scratch_6.doSomething();
System.out.println("[" + new Date() + "] completed");
}
public Application(CachedRepository cachedRepository) {
System.out.println(this + " is created with cachedRepository: " + cachedRepository);
}
public void doSomething() {
System.out.println("I do something");
}
}
class ApplicationContext {
private final CompletableFuture<ApplicationContext> latch = new CompletableFuture<>();
private final ConcurrentMap<Class, CompletableFuture> beans = new ConcurrentHashMap<>();
public <T> CompletableFuture<T> getBeanAsync(Class<T> type) {
return beans.get(type);
}
public <T> T getBean(Class<T> type) {
try {
return getBeanAsync(type).get(1, TimeUnit.MINUTES);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
throw new BeanNotFoundException();
}
}
public <T> void registerBean(Class<T> type, Function<ApplicationContext, CompletableFuture<T>> future) {
beans.put(type, latch.thenComposeAsync(future));
}
public void start() {
latch.complete(this);
}
}
class Connection {
public Connection() {
System.out.println(this + " is created");
}
}
class DBTemplate {
public DBTemplate(Connection connection) {
System.out.println(this + " is created with connection: " + connection);
}
}
class CachedRepository {
public CachedRepository(DBTemplate dbTemplate, CachingTemplate cachingTemplate) {
System.out.println(this + " is created with dbTemplate: " + dbTemplate + " and cachingTemplate: " + cachingTemplate);
}
}
class CachingTemplate {
public CachingTemplate() {
System.out.println(this + " is created");
}
}
class BeanNotFoundException extends RuntimeException {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment