001package io.avaje.inject; 002 003import java.io.Closeable; 004import java.util.List; 005 006/** 007 * Holds beans created by dependency injection. 008 * <p> 009 * The beans have singleton scope, support lifecycle methods for postConstruct and 010 * preDestroy and are created (wired) via dependency injection. 011 * </p> 012 * 013 * <h3>Create a BeanContext</h3> 014 * <p> 015 * We can programmatically create a BeanContext via BeanContextBuilder. 016 * </p> 017 * <pre>{@code 018 * 019 * // create a BeanContext ... 020 * 021 * try (BeanContext context = new BeanContextBuilder() 022 * .build()) { 023 * 024 * CoffeeMaker coffeeMaker = context.getBean(CoffeeMaker.class); 025 * coffeeMaker.makeIt() 026 * } 027 * 028 * }</pre> 029 * 030 * <h3>Implicitly used</h3> 031 * <p> 032 * The BeanContext is implicitly used by SystemContext. It will be created as needed and 033 * a shutdown hook will close the underlying BeanContext on JVM shutdown. 034 * </p> 035 * <pre>{@code 036 * 037 * // BeanContext created as needed under the hood 038 * 039 * CoffeeMaker coffeeMaker = SystemContext.getBean(CoffeeMaker.class); 040 * coffeeMaker.brew(); 041 * 042 * }</pre> 043 */ 044public interface BeanContext extends Closeable { 045 046 /** 047 * Return the module name of the bean context. 048 * 049 * @see ContextModule 050 */ 051 String getName(); 052 053 /** 054 * Return the names of module features this bean context provides. 055 * 056 * @see ContextModule 057 */ 058 String[] getProvides(); 059 060 /** 061 * Return the names of modules this bean context depends on. 062 * 063 * @see ContextModule 064 */ 065 String[] getDependsOn(); 066 067 /** 068 * Return a single bean given the type. 069 * 070 * <pre>{@code 071 * 072 * CoffeeMaker coffeeMaker = beanContext.getBean(CoffeeMaker.class); 073 * coffeeMaker.brew(); 074 * 075 * }</pre> 076 * 077 * @param type an interface or bean type 078 */ 079 <T> T getBean(Class<T> type); 080 081 /** 082 * Return a single bean given the type and name. 083 * 084 * <pre>{@code 085 * 086 * Heater heater = beanContext.getBean(Heater.class, "electric"); 087 * heater.heat(); 088 * 089 * }</pre> 090 * 091 * @param type an interface or bean type 092 * @param name the name qualifier of a specific bean 093 */ 094 <T> T getBean(Class<T> type, String name); 095 096 /** 097 * Return the wiring candidate bean with name and priority. 098 */ 099 <T> BeanEntry<T> candidate(Class<T> type, String name); 100 101 /** 102 * Return the list of beans that have an annotation. 103 * 104 * <pre>{@code 105 * 106 * // e.g. register all controllers with web a framework 107 * // .. where Controller is an annotation on the beans 108 * 109 * List<Object> controllers = SystemContext.getBeansWithAnnotation(Controller.class); 110 * 111 * }</pre> 112 * 113 * <p> 114 * The classic use case for this is registering controllers or routes to 115 * web frameworks like Sparkjava, Javlin, Rapidoid etc. 116 * 117 * @param annotation An annotation class. 118 */ 119 List<Object> getBeansWithAnnotation(Class<?> annotation); 120 121 /** 122 * Return the list of beans that implement the interface. 123 * 124 * <pre>{@code 125 * 126 * // e.g. register all routes for a web framework 127 * 128 * List<WebRoute> routes = SystemContext.getBeans(WebRoute.class); 129 * 130 * }</pre> 131 * 132 * @param interfaceType An interface class. 133 */ 134 <T> List<T> getBeans(Class<T> interfaceType); 135 136 /** 137 * Return the list of beans that implement the interface 138 * sorting by priority (ignoring any Priority annotation). 139 */ 140 <T> List<T> getBeansByPriority(Class<T> interfaceType); 141 142 /** 143 * Sort the beans by javax.annotation.Priority annotation. 144 * 145 * @param list The beans to sort by priority 146 * @return A new list of beans sorted by priority 147 */ 148 <T> List<T> sortByPriority(List<T> list); 149 150 /** 151 * Start the context firing any <code>@PostConstruct</code> methods. 152 */ 153 void start(); 154 155 /** 156 * Close the context firing any <code>@PreDestroy</code> methods. 157 */ 158 void close(); 159}