diff --git a/AUTHORS.rst b/AUTHORS.rst
index 1ad3e9a..84c119e 100644
--- a/AUTHORS.rst
+++ b/AUTHORS.rst
@@ -62,3 +62,4 @@ Contributors (chronological)
 - Bastien Gerard `@bagerard <https://github.com/bagerard>`_
 - Ashutosh Chaudhary `@codeasashu <https://github.com/codeasashu>`_
 - Fedor Fominykh `@fedorfo <https://github.com/fedorfo>`_
+- Colin Bounouar `@Colin-b <https://github.com/colin-b>`_
diff --git a/src/apispec/core.py b/src/apispec/core.py
index 77b876c..e878321 100644
--- a/src/apispec/core.py
+++ b/src/apispec/core.py
@@ -190,19 +190,19 @@ class APISpec:
         self.version = version
         self.openapi_version = OpenAPIVersion(openapi_version)
         self.options = options
+        self.plugins = plugins
 
         # Metadata
         self._tags = []
         self._paths = OrderedDict()
 
+        # Components
+        self.components = Components(self.plugins, self.openapi_version)
+
         # Plugins
-        self.plugins = plugins
         for plugin in self.plugins:
             plugin.init_spec(self)
 
-        # Components
-        self.components = Components(self.plugins, self.openapi_version)
-
     def to_dict(self):
         ret = {
             "paths": self._paths,

diff --git a/tests/test_core.py b/tests/test_core.py
index 3978632..ce9348f 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -276,6 +276,21 @@ class TestComponents:
         spec.components.schema("Pet", properties=self.properties, enum=enum)
         assert spec.to_dict() == yaml.safe_load(spec.to_yaml())
 
+    def test_components_can_be_accessed_by_plugin_in_init_spec(self):
+        class TestPlugin(BasePlugin):
+            def init_spec(self, spec):
+                spec.components.schema(
+                    "TestSchema",
+                    {"properties": {"key": {"type": "string"}}, "type": "object"},
+                )
+
+        spec = APISpec(
+            "Test API", version="0.0.1", openapi_version="2.0", plugins=[TestPlugin()]
+        )
+        assert get_schemas(spec) == {
+            "TestSchema": {"properties": {"key": {"type": "string"}}, "type": "object"}
+        }
+
 
 class TestPath:
     paths = {

Ability to access APISpec.components in plugin init_spec method
Is there a specific reason why components is initialized after plugins init_spec methods are called?

If not, then I am willing to open a PR to solve this issue.
tests/test_core.py::TestComponents::test_components_can_be_accessed_by_plugin_in_init_spec
tests/test_core.py::TestAPISpecInit::test_raises_wrong_apispec_version tests/test_core.py::TestMetadata::test_openapi_metadata[2.0] tests/test_core.py::TestMetadata::test_openapi_metadata[3.0.0] tests/test_core.py::TestMetadata::test_openapi_metadata_merge_v3[3.0.0] tests/test_core.py::TestTags::test_tag[2.0] tests/test_core.py::TestTags::test_tag[3.0.0] tests/test_core.py::TestTags::test_tag_is_chainable[2.0] tests/test_core.py::TestTags::test_tag_is_chainable[3.0.0] tests/test_core.py::TestComponents::test_schema[2.0] tests/test_core.py::TestComponents::test_schema[3.0.0] tests/test_core.py::TestComponents::test_schema_is_chainable[2.0] tests/test_core.py::TestComponents::test_schema_is_chainable[3.0.0] tests/test_core.py::TestComponents::test_schema_description[2.0] tests/test_core.py::TestComponents::test_schema_description[3.0.0] tests/test_core.py::TestComponents::test_schema_stores_enum[2.0] tests/test_core.py::TestComponents::test_schema_stores_enum[3.0.0] tests/test_core.py::TestComponents::test_schema_discriminator[2.0] tests/test_core.py::TestComponents::test_schema_discriminator[3.0.0] tests/test_core.py::TestComponents::test_schema_duplicate_name[2.0] tests/test_core.py::TestComponents::test_schema_duplicate_name[3.0.0] tests/test_core.py::TestComponents::test_response[2.0] tests/test_core.py::TestComponents::test_response[3.0.0] tests/test_core.py::TestComponents::test_response_is_chainable[2.0] tests/test_core.py::TestComponents::test_response_is_chainable[3.0.0] tests/test_core.py::TestComponents::test_response_duplicate_name[2.0] tests/test_core.py::TestComponents::test_response_duplicate_name[3.0.0] tests/test_core.py::TestComponents::test_parameter[2.0] tests/test_core.py::TestComponents::test_parameter[3.0.0] tests/test_core.py::TestComponents::test_parameter_is_chainable[2.0] tests/test_core.py::TestComponents::test_parameter_is_chainable[3.0.0] tests/test_core.py::TestComponents::test_parameter_duplicate_name[2.0] tests/test_core.py::TestComponents::test_parameter_duplicate_name[3.0.0] tests/test_core.py::TestComponents::test_example[3.0.0] tests/test_core.py::TestComponents::test_example_is_chainable[3.0.0] tests/test_core.py::TestComponents::test_example_duplicate_name[3.0.0] tests/test_core.py::TestComponents::test_security_scheme[2.0] tests/test_core.py::TestComponents::test_security_scheme[3.0.0] tests/test_core.py::TestComponents::test_security_scheme_is_chainable[2.0] tests/test_core.py::TestComponents::test_security_scheme_is_chainable[3.0.0] tests/test_core.py::TestComponents::test_security_scheme_duplicate_name[2.0] tests/test_core.py::TestComponents::test_security_scheme_duplicate_name[3.0.0] tests/test_core.py::TestComponents::test_to_yaml[2.0] tests/test_core.py::TestComponents::test_to_yaml[3.0.0] tests/test_core.py::TestPath::test_path[2.0] tests/test_core.py::TestPath::test_path[3.0.0] tests/test_core.py::TestPath::test_paths_maintain_order[2.0] tests/test_core.py::TestPath::test_paths_maintain_order[3.0.0] tests/test_core.py::TestPath::test_paths_is_chainable[2.0] tests/test_core.py::TestPath::test_paths_is_chainable[3.0.0] tests/test_core.py::TestPath::test_methods_maintain_order[2.0] tests/test_core.py::TestPath::test_methods_maintain_order[3.0.0] tests/test_core.py::TestPath::test_path_merges_paths[2.0] tests/test_core.py::TestPath::test_path_merges_paths[3.0.0] tests/test_core.py::TestPath::test_path_called_twice_with_same_operations_parameters[2.0] tests/test_core.py::TestPath::test_path_called_twice_with_same_operations_parameters[3.0.0] tests/test_core.py::TestPath::test_path_ensures_path_parameters_required[2.0] tests/test_core.py::TestPath::test_path_ensures_path_parameters_required[3.0.0] tests/test_core.py::TestPath::test_path_with_no_path_raises_error[2.0] tests/test_core.py::TestPath::test_path_with_no_path_raises_error[3.0.0] tests/test_core.py::TestPath::test_path_summary_description[2.0] tests/test_core.py::TestPath::test_path_summary_description[3.0.0] tests/test_core.py::TestPath::test_parameter[2.0] tests/test_core.py::TestPath::test_parameter[3.0.0] tests/test_core.py::TestPath::test_invalid_parameter[2.0-parameters0] tests/test_core.py::TestPath::test_invalid_parameter[2.0-parameters1] tests/test_core.py::TestPath::test_invalid_parameter[3.0.0-parameters0] tests/test_core.py::TestPath::test_invalid_parameter[3.0.0-parameters1] tests/test_core.py::TestPath::test_parameter_duplicate[2.0] tests/test_core.py::TestPath::test_parameter_duplicate[3.0.0] tests/test_core.py::TestPath::test_global_parameters[2.0] tests/test_core.py::TestPath::test_global_parameters[3.0.0] tests/test_core.py::TestPath::test_global_parameter_duplicate[2.0] tests/test_core.py::TestPath::test_global_parameter_duplicate[3.0.0] tests/test_core.py::TestPath::test_response[2.0] tests/test_core.py::TestPath::test_response[3.0.0] tests/test_core.py::TestPath::test_response_with_HTTPStatus_code[2.0] tests/test_core.py::TestPath::test_response_with_HTTPStatus_code[3.0.0] tests/test_core.py::TestPath::test_response_with_status_code_range[2.0] tests/test_core.py::TestPath::test_response_with_status_code_range[3.0.0] tests/test_core.py::TestPath::test_path_check_invalid_http_method[2.0] tests/test_core.py::TestPath::test_path_check_invalid_http_method[3.0.0] tests/test_core.py::TestPlugins::test_plugin_factory tests/test_core.py::TestPlugins::test_plugin_schema_helper_is_used[True-2.0] tests/test_core.py::TestPlugins::test_plugin_schema_helper_is_used[True-3.0.0] tests/test_core.py::TestPlugins::test_plugin_schema_helper_is_used[False-2.0] tests/test_core.py::TestPlugins::test_plugin_schema_helper_is_used[False-3.0.0] tests/test_core.py::TestPlugins::test_plugin_parameter_helper_is_used[True-2.0] tests/test_core.py::TestPlugins::test_plugin_parameter_helper_is_used[True-3.0.0] tests/test_core.py::TestPlugins::test_plugin_parameter_helper_is_used[False-2.0] tests/test_core.py::TestPlugins::test_plugin_parameter_helper_is_used[False-3.0.0] tests/test_core.py::TestPlugins::test_plugin_response_helper_is_used[True-2.0] tests/test_core.py::TestPlugins::test_plugin_response_helper_is_used[True-3.0.0] tests/test_core.py::TestPlugins::test_plugin_response_helper_is_used[False-2.0] tests/test_core.py::TestPlugins::test_plugin_response_helper_is_used[False-3.0.0] tests/test_core.py::TestPlugins::test_plugin_path_helper_is_used[True-2.0] tests/test_core.py::TestPlugins::test_plugin_path_helper_is_used[True-3.0.0] tests/test_core.py::TestPlugins::test_plugin_path_helper_is_used[False-2.0] tests/test_core.py::TestPlugins::test_plugin_path_helper_is_used[False-3.0.0] tests/test_core.py::TestPlugins::test_plugin_operation_helper_is_used[2.0] tests/test_core.py::TestPlugins::test_plugin_operation_helper_is_used[3.0.0] tests/test_core.py::TestPluginsOrder::test_plugins_order