lundi 9 janvier 2023

Unable to autowire Spring Boot components while using factory pattern

I'm not able to inject Environment dependencies in the classes that extend the base interface in a factory pattern. My architect advised me to pass the dependency through method parameters, but now the requirement has changed to add more dependencies. I don't feel comfortable in adding more parameters to the same function anymore. The parameter change in one function has to be updated in base interface along with all the classes implementing it. Please suggest a better way of solving this issue.

I tried to add more parameters in the function to accommodate new dependencies, but this doesn't look like a scalable and clean approach.

Taking the example of this NotifierFactory:


public interface Notification {
    void notifyUser();
}

public class SMSNotification implements Notification {
 
    @Override
    public void notifyUser()
    {
        // TODO Auto-generated method stub
        System.out.println("Sending an SMS notification");
    }
}

public class EmailNotification implements Notification {
 
    @Override
    public void notifyUser()
    {
        // TODO Auto-generated method stub
        System.out.println("Sending an e-mail notification");
    }
}

public class PushNotification implements Notification {
 
    @Override
    public void notifyUser()
    {
        // TODO Auto-generated method stub
        System.out.println("Sending a push notification");
    }
}

public class NotificationFactory {
    public Notification createNotification(String channel)
    {
        if (channel == null || channel.isEmpty())
            return null;
        switch (channel) {
        case "SMS":
            return new SMSNotification();
        case "EMAIL":
            return new EmailNotification();
        case "PUSH":
            return new PushNotification();
        default:
            throw new IllegalArgumentException("Unknown channel "+channel);
        }
    }
}

public class NotificationService {
@Autowired
Environment env;
    public static void main(String[] args)
    {
        NotificationFactory notificationFactory = new NotificationFactory();
        Notification notification = notificationFactory.createNotification("SMS");
        notification.notifyUser();
    }
}

Now, say I need to use the Environment bean that is autowired in NotificationService inside notifyUser() method of EmailNotification class. If I try to do simple autowiring, the value of env is resolved to null. So the workaround I used was to pass env in notifiyUser() function like, notifyUser(env). The drawback of this approach is that now I need to change the definition of notifyUser() method in all classes implementing Notfication class, even though the env dependency is not used there. And in future, if I need to add more such dependencies, every time the function signature will change.

Aucun commentaire:

Enregistrer un commentaire