001package io.avaje.inject; 002 003import java.util.List; 004 005/** 006 * Provides a global system wide BeanScope that contains all the beans. 007 * <p> 008 * This will automatically get all the beans and wire them all as necessary. It will use 009 * a shutdown hook to fire any <code>@PreDestroy</code> methods on beans. 010 * </p> 011 * 012 * <h3>Example: get a bean</h3> 013 * <pre>{@code 014 * 015 * CoffeeMaker coffeeMaker = ApplicationScope.get(CoffeeMaker.class); 016 * coffeeMaker.brew(); 017 * 018 * }</pre> 019 * 020 * <h3>Example: get all the beans implementing an interface</h3> 021 * <pre>{@code 022 * 023 * // e.g. register all WebRoutes for a web framework 024 * 025 * List<WebRoute> routes = ApplicationScope.list(WebRoute.class); 026 * 027 * // register all the routes ... 028 * 029 * }</pre> 030 */ 031public class ApplicationScope { 032 033 private static final BeanScope appScope = init(); 034 035 private static BeanScope init() { 036 return BeanScope.newBuilder().build(); 037 } 038 039 private ApplicationScope() { 040 // hide 041 } 042 043 /** 044 * Return the underlying BeanScope. 045 */ 046 public static BeanScope scope() { 047 return appScope; 048 } 049 050 /** 051 * Return a single bean given the type. 052 * 053 * <pre>{@code 054 * 055 * CoffeeMaker coffeeMaker = ApplicationScope.get(CoffeeMaker.class); 056 * coffeeMaker.brew(); 057 * 058 * }</pre> 059 * 060 * @param type an interface or bean type 061 */ 062 public static <T> T get(Class<T> type) { 063 return appScope.get(type); 064 } 065 066 /** 067 * Return a single bean given the type and name. 068 * 069 * <pre>{@code 070 * 071 * Heater heater = ApplicationScope.get(Heater.class, "electric"); 072 * heater.heat(); 073 * 074 * }</pre> 075 * 076 * @param type an interface or bean type 077 * @param name the name qualifier of a specific bean 078 */ 079 public static <T> T get(Class<T> type, String name) { 080 return appScope.get(type, name); 081 } 082 083 084 /** 085 * Return the list of beans that implement the interface. 086 * 087 * <pre>{@code 088 * 089 * // e.g. register all web routes with web a framework 090 * 091 * List<WebRoute> routes = ApplicationScope.list(WebRoute.class); 092 * 093 * }</pre> 094 * 095 * @param interfaceType An interface class. 096 */ 097 public static <T> List<T> list(Class<T> interfaceType) { 098 return appScope.list(interfaceType); 099 } 100 101 /** 102 * Return the list of beans that implement the interface ordering based on <code>@Priority</code>. 103 * 104 * <pre>{@code 105 * 106 * // e.g. register all web routes with web a framework 107 * 108 * List<WebRoute> routes = ApplicationScope.listByPriority(WebRoute.class); 109 * 110 * }</pre> 111 * 112 * @param interfaceType An interface class. 113 */ 114 public static <T> List<T> listByPriority(Class<T> interfaceType) { 115 return appScope.listByPriority(interfaceType); 116 } 117 118 /** 119 * Return the list of beans that have an annotation. 120 * 121 * <pre>{@code 122 * 123 * // e.g. register all controllers with web a framework 124 * // .. where Controller is an annotation on the beans 125 * 126 * List<Object> controllers = ApplicationScope.listByAnnotation(Controller.class); 127 * 128 * }</pre> 129 * 130 * <p> 131 * The classic use case for this is registering controllers or routes to 132 * web frameworks like Sparkjava, Javalin, Rapidoid etc. 133 * 134 * @param annotation An annotation class. 135 */ 136 public static List<Object> listByAnnotation(Class<?> annotation) { 137 return appScope.listByAnnotation(annotation); 138 } 139 140 /** 141 * Start building a RequestScope. 142 * 143 * <pre>{@code 144 * 145 * try (RequestScope requestScope = ApplicationScope.newRequestScope() 146 * // supply some instances 147 * .withBean(HttpRequest.class, request) 148 * .withBean(HttpResponse.class, response) 149 * .build()) { 150 * 151 * MyController controller = requestScope.get(MyController.class); 152 * controller.process(); 153 * 154 * } 155 * 156 * ... 157 * 158 * // define request scoped beans 159 * @Request 160 * MyController { 161 * 162 * // can depend on supplied instances, singletons and other request scope beans 163 * @Inject 164 * MyController(HttpRequest request, HttpResponse response, MyService myService) { 165 * ... 166 * } 167 * 168 * } 169 * 170 * }</pre> 171 * 172 * @return The request scope builder 173 */ 174 public static RequestScopeBuilder newRequestScope() { 175 return appScope.newRequestScope(); 176 } 177}