-
-
Save bsideup/294862e3fa276fd1363f0f5026bfee44 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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