001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.commons.inject; 018 019import static java.lang.annotation.ElementType.*; 020import static java.lang.annotation.RetentionPolicy.*; 021 022import java.lang.annotation.*; 023 024/** 025 * Bean injection annotation. 026 * 027 * <p> 028 * Used on methods and fields of {@link BeanStore}-managed objects to denote methods and fields that override and 029 * customize beans used by the framework. 030 * 031 * <h5 class='figure'>Example</h5> 032 * <p class='bcode'> 033 * <jc>// Rest resource that uses a customized logger.</jc> 034 * <ja>@Rest</ja> 035 * <jk>public class</jk> MyRest <jk>extends</jk> BasicRestServlet { 036 * 037 * <jc>// Option #1: As a field.</jc> 038 * <ja>@Bean</ja> 039 * RichLogger <jf>myLogger</jf> = RichLogger.<jsm>getLogger</jsm>(<js>"mylogger"</js>); 040 * 041 * <jc>// Option #2: As a method.</jc> 042 * <ja>@Bean</ja> 043 * <jk>public</jk> RichLogger myLogger() { 044 * <jk>return</jk> RichLogger.<jsm>getLogger</jsm>(<js>"mylogger"</js>); 045 * } 046 * } 047 * </p> 048 * 049 * <p> 050 * The {@link Bean#name()}/{@link Bean#value()} attributes are used to differentiate between named beans. 051 * </p> 052 * <h5 class='figure'>Example</h5> 053 * <p class='bcode'> 054 * <jc>// Customized default request headers.</jc> 055 * <ja>@Bean</ja>(<js>"defaultRequestHeaders"</js>) 056 * HeaderList <jf>defaultRequestHeaders</jf> = HeaderList.<jsm>create</jsm>().set(ContentType.<jsf>TEXT_PLAIN</jsf>).build(); 057 * 058 * <jc>// Customized default response headers.</jc> 059 * <ja>@Bean</ja>(<js>"defaultResponseHeaders"</js>) 060 * HeaderList <jf>defaultResponseHeaders</jf> = HeaderList.<jsm>create</jsm>().set(ContentType.<jsf>TEXT_PLAIN</jsf>).build(); 061 * </p> 062 * 063 * <p> 064 * The {@link Bean#methodScope()} attribute is used to define beans in the scope of specific {@code @RestOp}-annotated methods. 065 * </p> 066 * <h5 class='figure'>Example</h5> 067 * <p class='bcode'> 068 * <jc>// Set a default header on a specific REST method.</jc> 069 * <jc>// Input parameter is the default header list builder with all annotations applied.</jc> 070 * <ja>@Bean</ja>(name=<js>"defaultRequestHeaders"</js>, methodScope=<js>"myRestMethod"</js>) 071 * <jk>public</jk> HeaderList.Builder myRequestHeaders(HeaderList.Builder <jv>builder</jv>) { 072 * <jk>return</jk> <jv>builder</jv>.set(ContentType.<jsf>TEXT_PLAIN</jsf>); 073 * } 074 * 075 * <jc>// Method that picks up default header defined above.</jc> 076 * <ja>@RestGet</ja> 077 * <jk>public</jk> Object myRestMethod(ContentType <jv>contentType</jv>) { ... } 078 * </p> 079 * 080 * <p> 081 * This annotation can also be used to inject arbitrary beans into the bean store which allows them to be 082 * passed as resolved parameters on {@code @RestOp}-annotated methods. 083 * </p> 084 * <h5 class='figure'>Example</h5> 085 * <p class='bcode'> 086 * <jc>// Custom beans injected into the bean store.</jc> 087 * <ja>@Bean</ja> MyBean <jv>myBean1</jv> = <jk>new</jk> MyBean(); 088 * <ja>@Bean</ja>(<js>"myBean2"</js>) MyBean <jv>myBean2</jv> = <jk>new</jk> MyBean(); 089 * 090 * <jc>// Method that uses injected beans.</jc> 091 * <ja>@RestGet</ja> 092 * <jk>public</jk> Object doGet(MyBean <jv>myBean1</jv>, <ja>@Name</ja>(<js>"myBean2"</js>) MyBean <jv>myBean2</jv>) { ... } 093 * </p> 094 * 095 * <p> 096 * This annotation can also be used on uninitialized fields. When fields are uninitialized, they will 097 * be set during initialization based on beans found in the bean store. 098 * </p> 099 * <h5 class='figure'>Example</h5> 100 * <p class='bcode'> 101 * <jc>// Fields that get set during initialization based on beans found in the bean store.</jc> 102 * <ja>@Bean</ja> RichLogger <jf>logger</jf>; 103 * <ja>@Bean</ja> BeanStore <jf>beanStore</jf>; <jc>// Note that the BeanStore itself can be accessed this way.</jc> 104 * </p> 105 * 106 * <h5 class='section'>Notes:</h5><ul> 107 * <li class='note'>Methods and fields can be static or non-static. 108 * <li class='note'>Any injectable beans (including spring beans) can be passed as arguments into methods. 109 * <li class='note'>Bean names are required when multiple beans of the same type exist in the bean store. 110 * <li class='note'>{@code @Bean} methods and fields may have any visibility (public, protected, package-private or private). 111 * Non-public members are made accessible before use, so the containing package must be opened to 112 * module <c>org.apache.juneau.commons</c> when running on the module path. 113 * <li class='note'>By default, the injected bean scope is class-level (applies to the entire class). The 114 * {@link Bean#methodScope()} annotation can be used to apply to method-level only (when applicable). 115 * </ul> 116 * 117 * <h5 class='section'>Bean names:</h5> 118 * <p> 119 * Each {@code @Bean} method registers its own result. Two methods returning the same type are distinguished by name, 120 * and both beans are kept. Factory methods on <ja>@Rest</ja> resources and <ja>@Configuration</ja> classes 121 * are the common use. 122 * </p> 123 * <h5 class='section'>Example:</h5> 124 * <p class='bjava'> 125 * <jc>// Two beans of the same type, distinguished by name. Each method's own result is registered.</jc> 126 * <ja>@Rest</ja> 127 * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet { 128 * 129 * <ja>@Bean</ja>(name=<js>"db"</js>) 130 * HealthIndicator dbIndicator() { 131 * <jk>return</jk> () -> Health.<jsm>up</jsm>(<js>"db"</js>).build(); 132 * } 133 * 134 * <ja>@Bean</ja>(name=<js>"cache"</js>) 135 * HealthIndicator cacheIndicator() { 136 * <jk>return</jk> () -> Health.<jsm>up</jsm>(<js>"cache"</js>).build(); 137 * } 138 * } 139 * </p> 140 * 141 * <h5 class='section'>Precedence (since 10.0.0):</h5> 142 * <p> 143 * {@code @Bean} acts as a <i>programmable default</i>, analogous to Spring's 144 * <c>@ConditionalOnMissingBean</c>. When a REST context resolves a framework-managed bean 145 * (<c>RichLogger</c>, <c>EncoderSet</c>, <c>SerializerSet</c>, <c>ParserSet</c>, <c>ThrownStore</c>, 146 * <c>Config</c>, <c>VarResolver</c>, <c>HttpPartSerializer</c>, <c>HttpPartParser</c>, etc.), the lookup 147 * walks the following tiers in order, returning the first hit: 148 * </p> 149 * <ol> 150 * <li><b>Overriding-parent bean store</b> — Spring beans (in <c>juneau-rest-server-springboot</c> deployments, 151 * via <c>SpringBeanStore</c>), or any bean reachable through the configured overriding-parent 152 * bean-store chain.</li> 153 * <li><b>{@code @Bean} method/field on the resource class</b> — registered as a regular bean-store 154 * entry, beating the framework default.</li> 155 * <li><b>Memoizer-backed framework default</b> — built into the context as a default supplier.</li> 156 * </ol> 157 * <p> 158 * In other words: a Spring <c>@Bean</c> of type <c>RichLogger</c> wins over a {@code @Bean RichLogger} 159 * method on the same servlet, which in turn wins over the framework's built-in class-name-based default logger. 160 * Non-Spring deployments have an empty overriding-parent layer, so the chain naturally collapses to 161 * {@code @Bean > default}. 162 * </p> 163 * <p> 164 * Prior to 10.0 the order was {@code @Bean > Spring > default}. See the 10.0.0 release notes for migration 165 * guidance if you need to keep that legacy behavior (typically by removing the Spring <c>@Bean</c> or marking the 166 * {@code @Bean} method's type with a Spring-native override such as <c>@Primary</c>). 167 * </p> 168 * 169 * <h5 class='section'>See Also:</h5><ul> 170 * <li class='jc'>{@link BeanStore} 171 * <li class='jc'>{@link WritableBeanStore} 172 * </ul> 173 */ 174@Target({ METHOD, FIELD }) 175@Retention(RUNTIME) 176@Inherited 177public @interface Bean { 178 179 /** 180 * Optional description for the exposed API. 181 * 182 * @return The annotation value. 183 * @since 9.2.0 184 */ 185 String[] description() default {}; 186 187 /** 188 * The short names of the methods that this annotation applies to. 189 * 190 * <p> 191 * Can use <js>"*"</js> to apply to all methods. 192 * 193 * <p> 194 * Ignored for class-level scope. 195 * 196 * @return The short names of the methods that this annotation applies to, or empty if class-scope. 197 */ 198 String[] methodScope() default {}; 199 200 /** 201 * The bean name to use to distinguish beans of the same type for different purposes. 202 * 203 * <p> 204 * For example, there are two {@code HeaderList} beans: <js>"defaultRequestHeaders"</js> and <js>"defaultResponseHeaders"</js>. This annotation 205 * would be used to differentiate between them. 206 * 207 * @return The bean name to use to distinguish beans of the same type for different purposes, or blank if bean type is unique. 208 */ 209 String name() default ""; 210 211 /** 212 * Same as {@link #name()}. 213 * 214 * @return The bean name to use to distinguish beans of the same type for different purposes, or blank if bean type is unique. 215 */ 216 String value() default ""; 217 218 /** 219 * Optional ordering value used when exporting ordered bean collections. 220 * 221 * <p> 222 * Lower values are higher precedence. If both {@link Order} and this value are present on the same 223 * contribution source, {@link Order} wins. 224 * 225 * @return The priority value. 226 */ 227 int priority() default Integer.MAX_VALUE / 2; 228}