At compile time, it is provided by your configured Maven repositories, just like any other dependency.
At run time, a
provided dependency is simply "expected to be there". What that means exactly depends on what the dependency is used for.
A very common use case for
provided dependencies are Jakarta EE APIs. An example is the Jakarta
Servlet API. If you've ever written a servlet-based web application, you probably had a dependency on either the Jakarta Servlet API, or the Jakarta EE Platform API. You need these dependencies to compile your application, but you don't need to include it with your application when you deploy it, because a web container such as
Tomcat is already expected to provide the Servlet API.
Another example is when you're building an add-in for another application. Your add-in might depend on some API that is provided by the application that your add-in hooks into, but it doesn't need to be released with that dependency because the application that hosts the add-in is already expected to provide the API.
There is a third use case, and this is the use case that applies to
maven-plugin-annotations. When the dependency contains solely annotations that are processed at compile-time only, it would be pointless to include the dependency at run time, because the dependency doesn't actually do anything at run time. At run time, the dependency isn't provided by anything at all, because it isn't needed. In this case, the scope name "
provided" is a bit of a misnomer.
You should instead interpret it as "needed at compile time only".