I am trying to implement the strategic pattern,the problem is that I could not access any dependency injected inside the strategy implmentation classes, so here is my code
Payment strategy interface
public interface PaymentStrategy {
public void processPayment(double amount);
}
Payment strategy interface implementation
@ApplicationScoped
public class CreditCardStrategy implements PaymentStrategy {
@Inject
@RestClient
ApiExample apiExample
public void processPayment(double amount) {
apiExample.doSomething() **//NULL POINTER EXCEPTION**
// Process credit card payment
}
}
@ApplicationScoped
public class PayPalStrategy implements PaymentStrategy {
@Inject
Service service
public void processPayment(double amount) {
service.doSomething() **//NULL POINTER EXCEPTION**
// Process PayPal payment
}
}
Payment strategy factory
public class PaymentStrategyFactory {
public PaymentStrategy getPaymentStrategy(String paymentMethod) {
if (paymentMethod.equals("creditcard")) {
return new CreditCardStrategy();
} else if (paymentMethod.equals("paypal")) {
return new PayPalStrategy();
} else {
throw new IllegalArgumentException("Invalid payment method: " + paymentMethod);
}
}
}
Main program method
String paymentMethod = "creditcard"; // Or "paypal"
PaymentStrategyFactory factory = new PaymentStrategyFactory();
PaymentStrategy paymentStrategy = factory.getPaymentStrategy(paymentMethod);
PaymentProcessor paymentProcessor = new PaymentProcessor(paymentStrategy);
paymentProcessor.processPayment(100.0); //NULL POINTER EXCEPTION CAUSED BY apiExample.doSomething()
To expand on the answer given in the comments, here's how you might get the bean from the context in spring. Here's a quarkus example of how you might do this.
it prints:
2023-03-18 10:08:57,311 INFO [org.so.q75.Example] (Quarkus Main Thread) ApiExample processed!
2023-03-18 10:08:57,316 INFO [org.so.q75.Example] (Quarkus Main Thread) CreditCardStrategy processed!
2023-03-18 10:08:57,317 INFO [org.so.q75.Example] (Quarkus Main Thread) PaymentProcessor processed!
// src/main/org/so/q75775998/Example.java
package org.so.q75775998;
import io.quarkus.runtime.Quarkus;
import io.quarkus.runtime.QuarkusApplication;
import io.quarkus.runtime.annotations.QuarkusMain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
@QuarkusMain
public class Example implements QuarkusApplication {
private static final Logger log = LoggerFactory.getLogger(Example.class);
@Inject
PaymentProcessor paymentProcessor;
public static void main(String[] args) {
Quarkus.run(Example.class, args);
}
@Override
public int run(String... args) throws Exception {
paymentProcessor.processPayment(100.0);
return 0;
}
@ApplicationScoped
public static class PaymentProcessor {
@Inject
Instance<PaymentStrategy> paymentStrategies;
void processPayment(double amount) {
paymentStrategies.iterator().next().processPayment(amount);
log.info("PaymentProcessor processed!");
}
}
public interface PaymentStrategy {
void processPayment(double amount);
}
@ApplicationScoped
public static class CreditCardStrategy implements PaymentStrategy {
@Inject
ApiExample apiExample;
public void processPayment(double amount) {
apiExample.doSomething();
log.info("CreditCardStrategy processed!");
}
}
@ApplicationScoped
public static class ApiExample {
public void doSomething() {
log.info("ApiExample processed!");
}
}
@ApplicationScoped
public static class PayPalStrategy implements PaymentStrategy {
@Inject
Service service;
public void processPayment(double amount) {
service.doSomething();
log.info("PayPalStrategy processed!");
}
}
@ApplicationScoped
public static class Service {
public void doSomething() {
log.info("did something!");
}
}
}
// pom.xml (initialized from https://quarkus.io/guides/lifecycle)
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.acme</groupId>
<artifactId>lifecycle-quickstart</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<compiler-plugin.version>3.10.1</compiler-plugin.version>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>2.16.4.Final</quarkus.platform.version>
<skipITs>true</skipITs>
<surefire-plugin.version>3.0.0-M7</surefire-plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<properties>
<skipITs>false</skipITs>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project>