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.rest.server; 018 019import static java.lang.annotation.ElementType.*; 020import static java.lang.annotation.RetentionPolicy.*; 021 022import java.lang.annotation.*; 023 024import org.apache.juneau.commons.inject.*; 025 026import jakarta.servlet.*; 027 028/** 029 * Identifies a method that gets called during servlet initialization. 030 * 031 * <p> 032 * This method is called from within the {@link Servlet#init(ServletConfig)} method after the 033 * resource's annotation-driven configuration has been applied to the in-flight {@link RestContext}, but before 034 * any HTTP request is dispatched. It's the supported hook for one-time setup work such as loading data files 035 * or precomputing caches. 036 * 037 * <p> 038 * Method parameters are resolved from the 039 * {@link BeanStore bean store} the same way as any other Juneau-injected 040 * method. {@link jakarta.servlet.ServletConfig}, {@link jakarta.servlet.ServletContext}, the resource instance 041 * itself, and any bean registered via {@link Bean @Bean} or the 042 * configured bean-store hooks are all resolvable. Zero-argument variants are also supported. 043 * 044 * <p> 045 * <b>Note (10.0):</b> two related Builder-injection protocols have been removed in this release. They had zero 046 * real-world callers across the codebase before deletion: 047 * <ul> 048 * <li><b>Per-operation:</b> {@code @RestInit public void init(RestOpContext.Builder b)} (invoked once per 049 * <code>@RestOp</code>-annotated method) — replaced by declarative <code>@RestOp(...)</code> attributes, 050 * <code>@Bean(name=, methodScope=)</code>-named beans, or class-level <code>@RestInit</code> hooks. 051 * <li><b>Class-level Builder injection:</b> {@code @RestInit public void init(RestContext.Builder b)} (which 052 * injected the in-flight resource-level builder so the hook could imperatively mutate it) — replaced by the 053 * same declarative surfaces. Migrate by moving each <code>builder.xxx(...)</code> call to the equivalent 054 * <code>@Rest(xxx=...)</code> annotation attribute or {@code @Bean}-named bean. 055 * </ul> 056 * 057 * <p> 058 * The remaining supported {@code @RestInit} hook shape is one whose parameters are bean-store-resolvable 059 * (no {@code RestContext.Builder} or {@code RestOpContext.Builder}). The example below uses the resource 060 * instance itself, but {@code @Bean}-supplied beans, {@code ServletConfig}, etc. work the same way. 061 * 062 * <h5 class='figure'>Example:</h5> 063 * <p class='bjava'> 064 * <ja>@Rest</ja>(...) 065 * <jk>public class</jk> PetStoreResource <jk>extends</jk> BasicRestServlet <jk>implements</jk> BasicUniversalJenaConfig { 066 * 067 * <jc>// Our database.</jc> 068 * <jk>private</jk> Map<Integer,Pet> <jf>petDB</jf>; 069 * 070 * <ja>@RestInit</ja> 071 * <jk>public void</jk> onInit() <jk>throws</jk> Exception { 072 * <jc>// Load our database from a local JSON file.</jc> 073 * <jf>petDB</jf> = JsonParser.<jsf>DEFAULT</jsf>.read(getClass().getResourceAsStream(<js>"PetStore.json"</js>), LinkedHashMap.<jk>class</jk>, Integer.<jk>class</jk>, Pet.<jk>class</jk>); 074 * } 075 * } 076 * </p> 077 * 078 * <h5 class='section'>Notes:</h5><ul> 079 * <li class='note'> 080 * The method should return <jk>void</jk> although if it does return any value, the value will be ignored. 081 * <li class='note'> 082 * The method should be <jk>public</jk> although other visibilities are valid if the security manager allows it. 083 * <li class='note'> 084 * Static methods can be used. 085 * <li class='note'> 086 * Multiple init methods can be defined on a class. 087 * <br>Init methods on parent classes are invoked before init methods on child classes. 088 * <br>The order of init method invocations within a class is alphabetical, then by parameter count, then by parameter types. 089 * <li class='note'> 090 * The method can throw any exception causing initialization of the servlet to fail. 091 * <li class='note'> 092 * Note that if you override a parent method, you probably need to call <code><jk>super</jk>.parentMethod(...)</code>. 093 * <br>The method is still considered part of the parent class for ordering purposes even though it's 094 * overridden by the child class. 095 * </ul> 096 * 097 * <h5 class='section'>See Also:</h5><ul> 098 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/LifecycleHooks">Lifecycle Hooks</a> 099 * </ul> 100 */ 101@Target({ METHOD }) 102@Retention(RUNTIME) 103@Inherited 104public @interface RestInit { 105 106 /** 107 * Optional description for the exposed API. 108 * 109 * @return The annotation value. 110 * @since 9.2.0 111 */ 112 String[] description() default {}; 113}