Java provides Keyword

The provides keyword in Java is part of the Java Platform Module System (JPMS) introduced in Java 9. It is used within a module declaration to specify that the module provides an implementation of a service interface. This keyword is paired with the with keyword to declare the specific implementation class.

Table of Contents

  1. Introduction
  2. provides Keyword Syntax
  3. Understanding provides
  4. Examples
    • Providing a Service Implementation
    • Using the Service
  5. Real-World Use Case
  6. Conclusion

Introduction

In Java’s module system, services and service providers are declared and consumed using the provides and uses keywords. The provides keyword is used to declare that a module provides an implementation for a specified service interface.

provides Keyword Syntax

The syntax for using the provides keyword in a module-info.java file is as follows:

module moduleName { provides fully.qualified.ServiceInterfaceName with fully.qualified.ImplementationClassName; } 

Example:

module com.example.provider { provides com.example.myapp.api.MyService with com.example.provider.MyServiceImpl; } 

Understanding provides

Key Points:

  • Service Provider: The provides keyword declares that the module provides an implementation of a service interface.
  • Implementation Class: The with keyword specifies the class that implements the service interface.
  • Service Discovery: The ServiceLoader class can be used to discover and load implementations of the service at runtime.

Examples

Providing a Service Implementation

A module that provides an implementation for a service interface.

Example

// File: src/com.example.provider/module-info.java module com.example.provider { requires com.example.myapp; provides com.example.myapp.api.MyService with com.example.provider.MyServiceImpl; } // File: src/com.example.myapp/api/MyService.java package com.example.myapp.api; public interface MyService { void performService(); } // File: src/com.example.provider/MyServiceImpl.java package com.example.provider; import com.example.myapp.api.MyService; public class MyServiceImpl implements MyService { @Override public void performService() { System.out.println("Service performed by MyServiceImpl"); } } 

Using the Service

Using the ServiceLoader to load and use the service implementation.

Example

// File: src/com.example.myapp/module-info.java module com.example.myapp { uses com.example.myapp.api.MyService; } // File: src/com.example.myapp/Main.java package com.example.myapp; import com.example.myapp.api.MyService; import java.util.ServiceLoader; public class Main { public static void main(String[] args) { ServiceLoader<MyService> serviceLoader = ServiceLoader.load(MyService.class); for (MyService service : serviceLoader) { service.performService(); } } } 

Output:

Service performed by MyServiceImpl 

Real-World Use Case

Plugin System

In real-world applications, the provides and uses keywords can be used to create a plugin system where the main application can discover and use plugins (service providers) at runtime without knowing the implementation details.

Example

// Main application module definition (src/com.example.app/module-info.java) module com.example.app { uses com.example.plugin.api.Plugin; } // Plugin API module definition (src/com.example.plugin/module-info.java) module com.example.plugin { exports com.example.plugin.api; } // Plugin provider module definition (src/com.example.plugin.impl/module-info.java) module com.example.plugin.impl { requires com.example.plugin; provides com.example.plugin.api.Plugin with com.example.plugin.impl.PluginImpl; } // Plugin interface (src/com.example.plugin/api/Plugin.java) package com.example.plugin.api; public interface Plugin { void execute(); } // Plugin implementation (src/com.example.plugin.impl/PluginImpl.java) package com.example.plugin.impl; import com.example.plugin.api.Plugin; public class PluginImpl implements Plugin { @Override public void execute() { System.out.println("Plugin executed by PluginImpl"); } } // Main application (src/com.example.app/Main.java) package com.example.app; import com.example.plugin.api.Plugin; import java.util.ServiceLoader; public class Main { public static void main(String[] args) { ServiceLoader<Plugin> serviceLoader = ServiceLoader.load(Plugin.class); for (Plugin plugin : serviceLoader) { plugin.execute(); } } } 

Output:

Plugin executed by PluginImpl 

Conclusion

The provides keyword in Java’s module system is used for declaring service implementations. By specifying which classes provide implementations for service interfaces, modules can discover and use these implementations at runtime through the ServiceLoader mechanism. Understanding and using the provides keyword effectively is essential for developing modular and maintainable Java applications that rely on dynamic service discovery and decoupled architecture.

Leave a Comment

Scroll to Top