[{"data":1,"prerenderedAt":828},["ShallowReactive",2],{"docs-navigation:\u002Fdocs\u002Fconventions\u002Fspring":3,"docs-page-estimated-read-time:\u002Fdocs\u002Fconventions\u002Fspring":399,"docs-page:\u002Fdocs\u002Fconventions\u002Fspring":400},[4,9,41,69,282],{"title":5,"path":6,"stem":7,"icon":8},"Welcome to the Vital docs","\u002Fdocs\u002Fabout","docs\u002F1.about","i-lucide-info",{"title":10,"path":11,"stem":12,"children":13,"icon":40},"Getting started","\u002Fdocs\u002Fgetting-started","docs\u002F2.getting-started\u002F1.index",[14,16,35],{"title":15,"path":11,"stem":12,"icon":8},"What is Vital?",{"title":17,"icon":18,"path":19,"stem":20,"children":21,"page":34},"Installation","i-lucide-download","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F2.getting-started\u002F1.installation",[22,26,30],{"title":23,"path":24,"stem":25},"Using a starter project (~5 minutes)","\u002Fdocs\u002Fgetting-started\u002Finstallation\u002Fstarter","docs\u002F2.getting-started\u002F1.installation\u002F2.starter",{"title":27,"path":28,"stem":29},"Manual configuration (~7-8 minutes)","\u002Fdocs\u002Fgetting-started\u002Finstallation\u002Fmanual","docs\u002F2.getting-started\u002F1.installation\u002F3.manual",{"title":31,"path":32,"stem":33},"Using the initializer (~2-3 minutes)","\u002Fdocs\u002Fgetting-started\u002Finstallation\u002Finitializer","docs\u002F2.getting-started\u002F1.installation\u002F4.initializer",false,{"title":36,"path":37,"stem":38,"icon":39},"Main class","\u002Fdocs\u002Fgetting-started\u002Fmain-plugin-class","docs\u002F2.getting-started\u002F2.main-plugin-class","i-lucide-play","i-lucide-circle-play",{"title":42,"path":43,"stem":44,"children":45,"icon":68},"Conventions","\u002Fdocs\u002Fconventions","docs\u002F3.conventions\u002F1.index",[46,48,52,56,60,64],{"title":47,"path":43,"stem":44,"icon":8},"About",{"title":49,"path":50,"stem":51},"Spring","\u002Fdocs\u002Fconventions\u002Fspring","docs\u002F3.conventions\u002F2.spring",{"title":53,"path":54,"stem":55},"Platforms","\u002Fdocs\u002Fconventions\u002Fplatform-implementations","docs\u002F3.conventions\u002F3.platform-implementations",{"title":57,"path":58,"stem":59},"Metadata","\u002Fdocs\u002Fconventions\u002Fmetadata","docs\u002F3.conventions\u002F4.metadata",{"title":61,"path":62,"stem":63},"Lifecycles","\u002Fdocs\u002Fconventions\u002Flifecycles","docs\u002F3.conventions\u002F5.lifecycles",{"title":65,"path":66,"stem":67},"(Optional) Advanced class loading","\u002Fdocs\u002Fconventions\u002Fadvanced-classloading","docs\u002F3.conventions\u002F6.advanced-classloading","i-lucide-cog",{"title":70,"path":71,"stem":72,"children":73,"icon":281},"Modules","\u002Fdocs\u002Fmodules","docs\u002F4.modules\u002F1.index",[74,76,100,106,112,126,136,150,164,178,188,224,234,248,257,275],{"title":75,"path":71,"stem":72,"icon":8},"What are modules?",{"title":77,"path":78,"stem":79,"children":80,"icon":99},"vital-core","\u002Fdocs\u002Fmodules\u002Fvital-core","docs\u002F4.modules\u002F2.vital-core\u002F1.index",[81,83,87,91,95],{"title":82,"path":78,"stem":79,"icon":8},"About this module",{"title":84,"path":85,"stem":86},"Configuration","\u002Fdocs\u002Fmodules\u002Fvital-core\u002Fconfiguration","docs\u002F4.modules\u002F2.vital-core\u002F2.configuration",{"title":88,"path":89,"stem":90},"Listeners","\u002Fdocs\u002Fmodules\u002Fvital-core\u002Flisteners","docs\u002F4.modules\u002F2.vital-core\u002F3.listeners",{"title":92,"path":93,"stem":94},"Conditional beans","\u002Fdocs\u002Fmodules\u002Fvital-core\u002Fconditional-beans","docs\u002F4.modules\u002F2.vital-core\u002F4.conditional-beans",{"title":96,"path":97,"stem":98},"Repositories","\u002Fdocs\u002Fmodules\u002Fvital-core\u002Frepositories","docs\u002F4.modules\u002F2.vital-core\u002F5.repositories","",{"title":101,"path":102,"stem":103,"children":104,"icon":99},"vital-cloudnet4-bridge","\u002Fdocs\u002Fmodules\u002Fvital-cloudnet4-bridge","docs\u002F4.modules\u002Fvital-cloudnet4-bridge\u002F1.index",[105],{"title":82,"path":102,"stem":103,"icon":8},{"title":107,"path":108,"stem":109,"children":110,"icon":99},"vital-cloudnet4-driver","\u002Fdocs\u002Fmodules\u002Fvital-cloudnet4-driver","docs\u002F4.modules\u002Fvital-cloudnet4-driver\u002F1.index",[111],{"title":82,"path":108,"stem":109,"icon":8},{"title":113,"path":114,"stem":115,"children":116,"icon":99},"vital-commands","\u002Fdocs\u002Fmodules\u002Fvital-commands","docs\u002F4.modules\u002Fvital-commands\u002F1.index",[117,118,122],{"title":82,"path":114,"stem":115,"icon":8},{"title":119,"path":120,"stem":121},"Commands","\u002Fdocs\u002Fmodules\u002Fvital-commands\u002Fcommands","docs\u002F4.modules\u002Fvital-commands\u002Fcommands",{"title":123,"path":124,"stem":125},"Exception handling","\u002Fdocs\u002Fmodules\u002Fvital-commands\u002Fexception-handling","docs\u002F4.modules\u002Fvital-commands\u002Fexception-handling",{"title":127,"path":128,"stem":129,"children":130,"icon":99},"vital-configs","\u002Fdocs\u002Fmodules\u002Fvital-configs","docs\u002F4.modules\u002Fvital-configs\u002F1.index",[131,132],{"title":82,"path":128,"stem":129,"icon":8},{"title":133,"path":134,"stem":135},"Configs","\u002Fdocs\u002Fmodules\u002Fvital-configs\u002Fconfigs","docs\u002F4.modules\u002Fvital-configs\u002F2.configs",{"title":137,"path":138,"stem":139,"children":140,"icon":99},"vital-holograms","\u002Fdocs\u002Fmodules\u002Fvital-holograms","docs\u002F4.modules\u002Fvital-holograms\u002F1.index",[141,142,146],{"title":82,"path":138,"stem":139,"icon":8},{"title":143,"path":144,"stem":145},"Global holograms","\u002Fdocs\u002Fmodules\u002Fvital-holograms\u002Fglobal-holograms","docs\u002F4.modules\u002Fvital-holograms\u002F2.global-holograms",{"title":147,"path":148,"stem":149},"Player holograms","\u002Fdocs\u002Fmodules\u002Fvital-holograms\u002Fplayer-holograms","docs\u002F4.modules\u002Fvital-holograms\u002F3.player-holograms",{"title":151,"path":152,"stem":153,"children":154,"icon":99},"vital-inventories","\u002Fdocs\u002Fmodules\u002Fvital-inventories","docs\u002F4.modules\u002Fvital-inventories\u002F1.index",[155,156,160],{"title":82,"path":152,"stem":153,"icon":8},{"title":157,"path":158,"stem":159},"Normal inventories","\u002Fdocs\u002Fmodules\u002Fvital-inventories\u002Fnormal-inventories","docs\u002F4.modules\u002Fvital-inventories\u002F2.normal-inventories",{"title":161,"path":162,"stem":163},"Paged inventories","\u002Fdocs\u002Fmodules\u002Fvital-inventories\u002Fpaged-inventories","docs\u002F4.modules\u002Fvital-inventories\u002F3.paged-inventories",{"title":165,"path":166,"stem":167,"children":168,"icon":99},"vital-items","\u002Fdocs\u002Fmodules\u002Fvital-items","docs\u002F4.modules\u002Fvital-items\u002F1.index",[169,170,174],{"title":82,"path":166,"stem":167,"icon":8},{"title":171,"path":172,"stem":173},"Items","\u002Fdocs\u002Fmodules\u002Fvital-items\u002Fitems","docs\u002F4.modules\u002Fvital-items\u002F2.items",{"title":175,"path":176,"stem":177},"Item builders","\u002Fdocs\u002Fmodules\u002Fvital-items\u002Fitem-builders","docs\u002F4.modules\u002Fvital-items\u002F3.item-builders",{"title":179,"path":180,"stem":181,"children":182,"icon":99},"vital-localization","\u002Fdocs\u002Fmodules\u002Fvital-localization","docs\u002F4.modules\u002Fvital-localization\u002F1.index",[183,184],{"title":82,"path":180,"stem":181,"icon":8},{"title":185,"path":186,"stem":187},"Localization","\u002Fdocs\u002Fmodules\u002Fvital-localization\u002Flocalization","docs\u002F4.modules\u002Fvital-localization\u002F2.localization",{"title":189,"path":190,"stem":191,"children":192,"icon":99},"vital-minigames","\u002Fdocs\u002Fmodules\u002Fvital-minigames","docs\u002F4.modules\u002Fvital-minigames\u002F1.index",[193,194,208],{"title":82,"path":190,"stem":191,"icon":8},{"title":195,"path":196,"stem":197,"children":198,"icon":99},"Global games","\u002Fdocs\u002Fmodules\u002Fvital-minigames\u002Fglobal-games","docs\u002F4.modules\u002Fvital-minigames\u002F2.global-games\u002F1.index",[199,200,204],{"title":47,"path":196,"stem":197,"icon":8},{"title":201,"path":202,"stem":203},"States","\u002Fdocs\u002Fmodules\u002Fvital-minigames\u002Fglobal-games\u002Fstates","docs\u002F4.modules\u002Fvital-minigames\u002F2.global-games\u002F2.states",{"title":205,"path":206,"stem":207},"Countdown states","\u002Fdocs\u002Fmodules\u002Fvital-minigames\u002Fglobal-games\u002Fcountdown-states","docs\u002F4.modules\u002Fvital-minigames\u002F2.global-games\u002F3.countdown-states",{"title":209,"path":210,"stem":211,"children":212,"icon":99},"Instanced games","\u002Fdocs\u002Fmodules\u002Fvital-minigames\u002Finstanced-games","docs\u002F4.modules\u002Fvital-minigames\u002F3.instanced-games\u002F1.index",[213,214,218,221],{"title":47,"path":210,"stem":211,"icon":8},{"title":215,"path":216,"stem":217},"Instances","\u002Fdocs\u002Fmodules\u002Fvital-minigames\u002Finstanced-games\u002Finstances","docs\u002F4.modules\u002Fvital-minigames\u002F3.instanced-games\u002F2.instances",{"title":201,"path":219,"stem":220},"\u002Fdocs\u002Fmodules\u002Fvital-minigames\u002Finstanced-games\u002Fstates","docs\u002F4.modules\u002Fvital-minigames\u002F3.instanced-games\u002F3.states",{"title":205,"path":222,"stem":223},"\u002Fdocs\u002Fmodules\u002Fvital-minigames\u002Finstanced-games\u002Fcountdown-states","docs\u002F4.modules\u002Fvital-minigames\u002F3.instanced-games\u002F4.countdown-states",{"title":225,"path":226,"stem":227,"children":228,"icon":99},"vital-players","\u002Fdocs\u002Fmodules\u002Fvital-players","docs\u002F4.modules\u002Fvital-players\u002F1.index",[229,230],{"title":82,"path":226,"stem":227,"icon":8},{"title":231,"path":232,"stem":233},"Players","\u002Fdocs\u002Fmodules\u002Fvital-players\u002Fplayers","docs\u002F4.modules\u002Fvital-players\u002F2.players",{"title":235,"path":236,"stem":237,"children":238,"icon":99},"vital-scoreboards","\u002Fdocs\u002Fmodules\u002Fvital-scoreboards","docs\u002F4.modules\u002Fvital-scoreboards\u002F1.index",[239,240,244],{"title":82,"path":236,"stem":237,"icon":8},{"title":241,"path":242,"stem":243},"Global scoreboards","\u002Fdocs\u002Fmodules\u002Fvital-scoreboards\u002Fglobal-scoreboards","docs\u002F4.modules\u002Fvital-scoreboards\u002Fglobal-scoreboards",{"title":245,"path":246,"stem":247},"Player scoreboards","\u002Fdocs\u002Fmodules\u002Fvital-scoreboards\u002Fplayer-scoreboards","docs\u002F4.modules\u002Fvital-scoreboards\u002Fplayer-scoreboards",{"title":249,"path":250,"stem":251,"children":252,"icon":99},"vital-statistics","\u002Fdocs\u002Fmodules\u002Fvital-statistics","docs\u002F4.modules\u002Fvital-statistics\u002F1.index",[253,254],{"title":82,"path":250,"stem":251,"icon":8},{"title":84,"path":255,"stem":256},"\u002Fdocs\u002Fmodules\u002Fvital-statistics\u002Fconfiguration","docs\u002F4.modules\u002Fvital-statistics\u002F2.configuration",{"title":258,"path":259,"stem":260,"children":261,"icon":99},"vital-tasks","\u002Fdocs\u002Fmodules\u002Fvital-tasks","docs\u002F4.modules\u002Fvital-tasks\u002F1.index",[262,263,267,271],{"title":82,"path":259,"stem":260,"icon":8},{"title":264,"path":265,"stem":266},"Repeatable tasks","\u002Fdocs\u002Fmodules\u002Fvital-tasks\u002Frepeatable-tasks","docs\u002F4.modules\u002Fvital-tasks\u002F2.repeatable-tasks",{"title":268,"path":269,"stem":270},"Countdown tasks","\u002Fdocs\u002Fmodules\u002Fvital-tasks\u002Fcountdown-tasks","docs\u002F4.modules\u002Fvital-tasks\u002F3.countdown-tasks",{"title":272,"path":273,"stem":274},"Scheduled tasks","\u002Fdocs\u002Fmodules\u002Fvital-tasks\u002Fscheduled-tasks","docs\u002F4.modules\u002Fvital-tasks\u002F4.scheduled-tasks",{"title":276,"path":277,"stem":278,"children":279,"icon":99},"vital-utils (Also for non Vital projects)","\u002Fdocs\u002Fmodules\u002Fvital-utils","docs\u002F4.modules\u002Fvital-utils\u002F1.index",[280],{"title":82,"path":277,"stem":278,"icon":8},"i-lucide-package",{"title":283,"path":284,"stem":285,"children":286,"icon":398},"Recipes","\u002Fdocs\u002Frecipes","docs\u002F5.recipes\u002F1.index",[287,289,301,305,317,330,341,344,368,371,384],{"title":288,"path":284,"stem":285,"icon":8},"What are recipes?",{"title":119,"path":290,"stem":291,"children":292,"page":34},"\u002Fdocs\u002Frecipes\u002Fcommands","docs\u002F5.recipes\u002Fcommands",[293,297],{"title":294,"path":295,"stem":296},"Command with arg exception handler","\u002Fdocs\u002Frecipes\u002Fcommands\u002Fcommands","docs\u002F5.recipes\u002Fcommands\u002Fcommands",{"title":298,"path":299,"stem":300},"Global command exception handler","\u002Fdocs\u002Frecipes\u002Fcommands\u002Fglobal-exception-handler","docs\u002F5.recipes\u002Fcommands\u002Fglobal-exception-handler",{"title":302,"path":303,"stem":304},"Config","\u002Fdocs\u002Frecipes\u002Fconfig","docs\u002F5.recipes\u002Fconfig",{"title":306,"path":307,"stem":308,"children":309,"page":34},"Holograms","\u002Fdocs\u002Frecipes\u002Fholograms","docs\u002F5.recipes\u002Fholograms",[310,314],{"title":311,"path":312,"stem":313},"Global hologram","\u002Fdocs\u002Frecipes\u002Fholograms\u002Fglobal-holograms","docs\u002F5.recipes\u002Fholograms\u002Fglobal-holograms",{"title":147,"path":315,"stem":316},"\u002Fdocs\u002Frecipes\u002Fholograms\u002Fplayer-holograms","docs\u002F5.recipes\u002Fholograms\u002Fplayer-holograms",{"title":318,"path":319,"stem":320,"children":321,"page":34},"Inventories","\u002Fdocs\u002Frecipes\u002Finventories","docs\u002F5.recipes\u002Finventories",[322,326],{"title":323,"path":324,"stem":325},"Normal inventory","\u002Fdocs\u002Frecipes\u002Finventories\u002Fnormal-inventory","docs\u002F5.recipes\u002Finventories\u002Fnormal-inventory",{"title":327,"path":328,"stem":329},"Paged inventory","\u002Fdocs\u002Frecipes\u002Finventories\u002Fpaged-inventory","docs\u002F5.recipes\u002Finventories\u002Fpaged-inventory",{"title":171,"path":331,"stem":332,"children":333,"page":34},"\u002Fdocs\u002Frecipes\u002Fitems","docs\u002F5.recipes\u002Fitems",[334,338],{"title":335,"path":336,"stem":337},"Interactable items","\u002Fdocs\u002Frecipes\u002Fitems\u002Finteractable-items","docs\u002F5.recipes\u002Fitems\u002Finteractable-items",{"title":175,"path":339,"stem":340},"\u002Fdocs\u002Frecipes\u002Fitems\u002Fitem-builders","docs\u002F5.recipes\u002Fitems\u002Fitem-builders",{"title":185,"path":342,"stem":343},"\u002Fdocs\u002Frecipes\u002Flocalization","docs\u002F5.recipes\u002Flocalization",{"title":345,"path":346,"stem":347,"children":348,"page":34},"Minigames","\u002Fdocs\u002Frecipes\u002Fminigames","docs\u002F5.recipes\u002Fminigames",[349,353,357,361,365],{"title":350,"path":351,"stem":352},"Global minigame countdown states","\u002Fdocs\u002Frecipes\u002Fminigames\u002Fglobal-countdown-states","docs\u002F5.recipes\u002Fminigames\u002Fglobal-countdown-states",{"title":354,"path":355,"stem":356},"Global minigame states","\u002Fdocs\u002Frecipes\u002Fminigames\u002Fglobal-states","docs\u002F5.recipes\u002Fminigames\u002Fglobal-states",{"title":358,"path":359,"stem":360},"Instance countdown states","\u002Fdocs\u002Frecipes\u002Fminigames\u002Finstance-countdown-states","docs\u002F5.recipes\u002Fminigames\u002Finstance-countdown-states",{"title":362,"path":363,"stem":364},"Instance states","\u002Fdocs\u002Frecipes\u002Fminigames\u002Finstance-states","docs\u002F5.recipes\u002Fminigames\u002Finstance-states",{"title":215,"path":366,"stem":367},"\u002Fdocs\u002Frecipes\u002Fminigames\u002Finstances","docs\u002F5.recipes\u002Fminigames\u002Finstances",{"title":231,"path":369,"stem":370},"\u002Fdocs\u002Frecipes\u002Fplayers","docs\u002F5.recipes\u002Fplayers",{"title":372,"path":373,"stem":374,"children":375,"page":34},"Scoreboards","\u002Fdocs\u002Frecipes\u002Fscoreboards","docs\u002F5.recipes\u002Fscoreboards",[376,380],{"title":377,"path":378,"stem":379},"Global scoreboard","\u002Fdocs\u002Frecipes\u002Fscoreboards\u002Fglobal-scoreboard","docs\u002F5.recipes\u002Fscoreboards\u002Fglobal-scoreboard",{"title":381,"path":382,"stem":383},"Player scoreboard","\u002Fdocs\u002Frecipes\u002Fscoreboards\u002Fplayer-scoreboard","docs\u002F5.recipes\u002Fscoreboards\u002Fplayer-scoreboard",{"title":385,"path":386,"stem":387,"children":388,"page":34},"Tasks","\u002Fdocs\u002Frecipes\u002Ftasks","docs\u002F5.recipes\u002Ftasks",[389,392,395],{"title":268,"path":390,"stem":391},"\u002Fdocs\u002Frecipes\u002Ftasks\u002Fcountdown-tasks","docs\u002F5.recipes\u002Ftasks\u002Fcountdown-tasks",{"title":264,"path":393,"stem":394},"\u002Fdocs\u002Frecipes\u002Ftasks\u002Frepeatable-tasks","docs\u002F5.recipes\u002Ftasks\u002Frepeatable-tasks",{"title":272,"path":396,"stem":397},"\u002Fdocs\u002Frecipes\u002Ftasks\u002Fscheduled-tasks","docs\u002F5.recipes\u002Ftasks\u002Fscheduled-tasks","i-lucide-cooking-pot",5,{"id":401,"title":49,"body":402,"description":821,"extension":822,"meta":823,"navigation":824,"path":50,"rawbody":825,"seo":826,"stem":51,"__hash__":827},"docs\u002Fdocs\u002F3.conventions\u002F2.spring.md",{"type":403,"value":404,"toc":818},"minimark",[405,409,413,416,423,426,431,437,443,589,592,601,604,606,625,628,634,747,769,789,802,814],[406,407,49],"h1",{"id":408},"spring",[410,411,412],"p",{},"Vital is developed with Spring (Boot) at its core, meaning that you can profit from all of its functionalities, mainly being dependency injection.",[410,414,415],{},"Dependency injection is a term used by a lot of plugin developers that is often misunderstood, especially in the Spring context.",[410,417,418,419,422],{},"It is important to know the basics of Spring dependency management and dependency injection before you start developing with Vital.",[420,421],"br",{},"\nDon't worry, it's not complicated, and you will soon know why this pattern is loved by many developers.",[424,425],"hr",{},[427,428,430],"h2",{"id":429},"the-basics","The basics",[410,432,433,434,436],{},"Your plugin will always contain multiple files \u002F classes; maybe you have a class for a single command, then a class for a listener which has all of your event handlers, etc.",[420,435],{},"\nEvery class by-default doesn't do anything yet, especially commands and listeners.",[410,438,439,440,442],{},"When you're not using Vital, you manually need to let your plugin (and the server) know what classes are responsible for commands, listeners, etc.",[420,441],{},"\nThis is what you would normally write in your main class.",[444,445,450],"pre",{"className":446,"code":447,"filename":448,"language":449,"meta":99,"style":99},"language-java shiki shiki-themes material-theme-lighter github-light github-dark","public class MyPlugin extends JavaPlugin {\n  @Override\n  public void onEnable() {\n    getCommand(\"mycommand\").setExecutor(new MyCommand());\n    Bukkit.getPluginManager().registerEvents(new MyListener());\n    \u002F\u002F ...\n  }\n}\n","MyPlugin.java","java",[451,452,453,479,488,506,543,570,577,583],"code",{"__ignoreMap":99},[454,455,458,462,465,469,472,475],"span",{"class":456,"line":457},"line",1,[454,459,461],{"class":460},"sbsja","public",[454,463,464],{"class":460}," class",[454,466,468],{"class":467},"sbgvK"," MyPlugin",[454,470,471],{"class":460}," extends",[454,473,474],{"class":467}," JavaPlugin",[454,476,478],{"class":477},"sP7_E"," {\n",[454,480,482,485],{"class":456,"line":481},2,[454,483,484],{"class":477},"  @",[454,486,487],{"class":460},"Override\n",[454,489,491,494,497,501,504],{"class":456,"line":490},3,[454,492,493],{"class":460},"  public",[454,495,496],{"class":460}," void",[454,498,500],{"class":499},"sGLFI"," onEnable",[454,502,503],{"class":477},"()",[454,505,478],{"class":477},[454,507,509,512,515,519,523,525,528,531,533,537,540],{"class":456,"line":508},4,[454,510,511],{"class":499},"    getCommand",[454,513,514],{"class":477},"(",[454,516,518],{"class":517},"sjJ54","\"",[454,520,522],{"class":521},"s_sjI","mycommand",[454,524,518],{"class":517},[454,526,527],{"class":477},").",[454,529,530],{"class":499},"setExecutor",[454,532,514],{"class":477},[454,534,536],{"class":535},"sVHd0","new",[454,538,539],{"class":499}," MyCommand",[454,541,542],{"class":477},"());\n",[454,544,545,549,552,555,558,561,563,565,568],{"class":456,"line":399},[454,546,548],{"class":547},"su5hD","    Bukkit",[454,550,551],{"class":477},".",[454,553,554],{"class":499},"getPluginManager",[454,556,557],{"class":477},"().",[454,559,560],{"class":499},"registerEvents",[454,562,514],{"class":477},[454,564,536],{"class":535},[454,566,567],{"class":499}," MyListener",[454,569,542],{"class":477},[454,571,573],{"class":456,"line":572},6,[454,574,576],{"class":575},"sutJx","    \u002F\u002F ...\n",[454,578,580],{"class":456,"line":579},7,[454,581,582],{"class":477},"  }\n",[454,584,586],{"class":456,"line":585},8,[454,587,588],{"class":477},"}\n",[410,590,591],{},"You would have to manually register every command and listener when your plugin starts up.",[410,593,594,595,597,598,600],{},"But sometimes you add a command, implement it fully, start your server and then realize, \"Wait; why doesn't my command show up?\"",[420,596],{},"\nYou look into your command class and don't find the problem right away, you take a look into your main class and \"Ahhh, I forgot to register the command...\".",[420,599],{},"\nThis can be very annoying when working on complex plugins.",[410,602,603],{},"Vital automatically detects all of your commands \u002F listeners \u002F other components and registers them when your plugin starts up.",[424,605],{},[410,607,608,609,612,613,616,617,619,620,624],{},"In Spring Boot, you can add the ",[451,610,611],{},"@Component"," annotation to any of your classes and Spring Boot will then automatically try to create a new instance of it using ",[451,614,615],{},"new ClassThatYouAnnotated()"," when it starts up.",[420,618],{},"\nThese automatically created instances of your classes are called \"",[621,622,623],"strong",{},"Spring Beans","\". A bean is an instance of a class that is automatically created and then managed by Spring.",[410,626,627],{},"Note that sometimes, you also need to access other classes to perform actions, like maybe your command needs to open an inventory, etc.",[410,629,630,631,633],{},"Since your inventory might be a class, you somehow have to get that class into your command class.",[420,632],{},"\nWith Vital, you can simply define the inventory class as a constructor parameter, and Spring Boot will automatically inject that inventory into your command without you having to do anything.",[444,635,638],{"className":446,"code":636,"filename":637,"language":449,"meta":99,"style":99},"\u002F\u002F This is the annotation that makes all of this dependency injection magic work; internally, it is annotated with @Component.\n@VitalCommand.Info(...)\npublic class MyCommand extends VitalCommand.Spigot {\n  private final MyInventory myInventory;\n  \n  public MyCommand(MyInventory myInventory) {\n    this.myInventory = myInventory;\n  }\n}\n","MyCommand.java",[451,639,640,645,656,677,695,700,719,738,742],{"__ignoreMap":99},[454,641,642],{"class":456,"line":457},[454,643,644],{"class":575},"\u002F\u002F This is the annotation that makes all of this dependency injection magic work; internally, it is annotated with @Component.\n",[454,646,647,650,653],{"class":456,"line":481},[454,648,649],{"class":477},"@",[454,651,652],{"class":460},"VitalCommand.Info",[454,654,655],{"class":477},"(...)\n",[454,657,658,660,662,664,666,669,672,675],{"class":456,"line":490},[454,659,461],{"class":460},[454,661,464],{"class":460},[454,663,539],{"class":467},[454,665,471],{"class":460},[454,667,668],{"class":467}," VitalCommand",[454,670,551],{"class":671},"stp6e",[454,673,674],{"class":467},"Spigot",[454,676,478],{"class":477},[454,678,679,682,685,689,692],{"class":456,"line":508},[454,680,681],{"class":460},"  private",[454,683,684],{"class":460}," final",[454,686,688],{"class":687},"s_bVq"," MyInventory",[454,690,691],{"class":547}," myInventory",[454,693,694],{"class":477},";\n",[454,696,697],{"class":456,"line":399},[454,698,699],{"class":547},"  \n",[454,701,702,704,706,708,711,714,717],{"class":456,"line":572},[454,703,493],{"class":460},[454,705,539],{"class":499},[454,707,514],{"class":477},[454,709,710],{"class":687},"MyInventory",[454,712,691],{"class":713},"s99_P",[454,715,716],{"class":477},")",[454,718,478],{"class":477},[454,720,721,725,727,730,734,736],{"class":456,"line":579},[454,722,724],{"class":723},"s39Yj","    this",[454,726,551],{"class":477},[454,728,729],{"class":547},"myInventory ",[454,731,733],{"class":732},"smGrS","=",[454,735,691],{"class":547},[454,737,694],{"class":477},[454,739,740],{"class":456,"line":585},[454,741,582],{"class":477},[454,743,745],{"class":456,"line":744},9,[454,746,588],{"class":477},[410,748,749,750,753,754,551,756,758,759,761,762,764,765,768],{},"Spring will try to create your command using ",[451,751,752],{},"new MyCommand()"," but then fails and sees that your constructor needs ",[451,755,710],{},[420,757],{},"\nIt will then check if the class ",[451,760,710],{}," is also annotated with ",[451,763,611],{},", and if so, first creates your inventory using ",[451,766,767],{},"new MyInventory()"," and then automatically uses that newly created inventory to create your command.",[770,771,772],"blockquote",{},[410,773,774,775,778,779,781,782,784,785,788],{},"Vital will internally grab all of your commands annotated with ",[451,776,777],{},"@VitalCommand.Info"," (",[451,780,611],{},") and register them for you.",[420,783],{},"\nSo internally the same ",[451,786,787],{},"getCommand(String).setExecutor(Command)"," is still happening, but for you, it is hidden.",[410,790,791,792,794,795,797,798,801],{},"And that's it...",[420,793],{},"\nAll you need to know is that all classes annotated with ",[451,796,611],{}," now live in Spring and are called \"",[621,799,800],{},"Spring beans","\" and can freely be injected into any other bean.",[770,803,804],{},[410,805,806,807,809,810,813],{},"One important note is that once you annotate your class with ",[451,808,611],{}," you should never manually create a new instance using ",[451,811,812],{},"new MyClass"," again, just inject it to whereever you need it.",[815,816,817],"style",{},"html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .stp6e, html code.shiki .stp6e{--shiki-light:#39ADB5;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_bVq, html code.shiki .s_bVq{--shiki-light:#9C3EDA;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}",{"title":99,"searchDepth":481,"depth":481,"links":819},[820],{"id":429,"depth":481,"text":430},"This page broadly explains how Vital incorporates Spring and how to use it in the Vital context.","md",{},{"title":49},"---\ntitle: Spring\ndescription: This page broadly explains how Vital incorporates Spring and how to use it in the Vital context.\nnavigation:\n  title: Spring\n---\n\n# Spring\n\nVital is developed with Spring (Boot) at its core, meaning that you can profit from all of its functionalities, mainly being dependency injection.  \n\nDependency injection is a term used by a lot of plugin developers that is often misunderstood, especially in the Spring context.  \n\nIt is important to know the basics of Spring dependency management and dependency injection before you start developing with Vital.  \nDon't worry, it's not complicated, and you will soon know why this pattern is loved by many developers.  \n\n---\n\n## The basics\n\nYour plugin will always contain multiple files \u002F classes; maybe you have a class for a single command, then a class for a listener which has all of your event handlers, etc.  \nEvery class by-default doesn't do anything yet, especially commands and listeners.  \n\nWhen you're not using Vital, you manually need to let your plugin (and the server) know what classes are responsible for commands, listeners, etc.  \nThis is what you would normally write in your main class.  \n```java [MyPlugin.java]\npublic class MyPlugin extends JavaPlugin {\n  @Override\n  public void onEnable() {\n    getCommand(\"mycommand\").setExecutor(new MyCommand());\n    Bukkit.getPluginManager().registerEvents(new MyListener());\n    \u002F\u002F ...\n  }\n}\n```\n\nYou would have to manually register every command and listener when your plugin starts up.  \n\nBut sometimes you add a command, implement it fully, start your server and then realize, \"Wait; why doesn't my command show up?\"  \nYou look into your command class and don't find the problem right away, you take a look into your main class and \"Ahhh, I forgot to register the command...\".  \nThis can be very annoying when working on complex plugins.  \n\nVital automatically detects all of your commands \u002F listeners \u002F other components and registers them when your plugin starts up.  \n\n---\n\nIn Spring Boot, you can add the `@Component` annotation to any of your classes and Spring Boot will then automatically try to create a new instance of it using `new ClassThatYouAnnotated()` when it starts up.  \nThese automatically created instances of your classes are called \"**Spring Beans**\". A bean is an instance of a class that is automatically created and then managed by Spring.  \n\nNote that sometimes, you also need to access other classes to perform actions, like maybe your command needs to open an inventory, etc.  \n\nSince your inventory might be a class, you somehow have to get that class into your command class.  \nWith Vital, you can simply define the inventory class as a constructor parameter, and Spring Boot will automatically inject that inventory into your command without you having to do anything.  \n\n```java [MyCommand.java]\n\u002F\u002F This is the annotation that makes all of this dependency injection magic work; internally, it is annotated with @Component.\n@VitalCommand.Info(...)\npublic class MyCommand extends VitalCommand.Spigot {\n  private final MyInventory myInventory;\n  \n  public MyCommand(MyInventory myInventory) {\n    this.myInventory = myInventory;\n  }\n}\n```\n\nSpring will try to create your command using `new MyCommand()` but then fails and sees that your constructor needs `MyInventory`.  \nIt will then check if the class `MyInventory` is also annotated with `@Component`, and if so, first creates your inventory using `new MyInventory()` and then automatically uses that newly created inventory to create your command.  \n\n> Vital will internally grab all of your commands annotated with `@VitalCommand.Info` (`@Component`) and register them for you.  \n> So internally the same `getCommand(String).setExecutor(Command)` is still happening, but for you, it is hidden.\n\nAnd that's it...  \nAll you need to know is that all classes annotated with `@Component` now live in Spring and are called \"**Spring beans**\" and can freely be injected into any other bean.  \n\n> One important note is that once you annotate your class with `@Component` you should never manually create a new instance using `new MyClass` again, just inject it to whereever you need it.\n",{"title":49,"description":821},"cusrB9i0ffr-8a_btN1wR0xW65Pc-7ZIlFEW51cD6y8",1789308658758]