1

In one of my classes, I have the following line of code. I don't know how these objects are registered as beans with spring's application context without any auto wiring and all.

    public class EmailAction<R, T> extends Action<R, T> {
    private EmailService emailService = SpringContextBridge.services().getEmailService();
    .
    .
    }

I want to know how this emailService object is created without any auto wiring

The SpringContextBridge class is as follows

@Component
@Getter
public class SpringContextBridge implements SpringContextBridgedServices, ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Autowired
    private CoffeeAuthorizationService authorizationService;

    @Autowired
    private CoffeeGroupParser coffeeGroupParser;

    @Autowired
    private CoffeeGroupService coffeeGroupService;

    @Autowired
    private AppProperties appProperties;

    @Autowired
    private EmailService emailService;

    @Autowired
    private CoffeeCloudProperties coffeeCloudProperties;

    @Autowired
    private CoffeeUtil coffeeUtil;

    @Autowired
    private CoffeeRuleService coffeeRuleService;

    @Autowired
    private CoffeeRuleRepository coffeeRuleRepository;
    
    @Override
    public void setApplicationContext(ApplicationContext ac) throws BeansException {
        applicationContext = ac;
    }

    /**
     * A static method to lookup the SpringContextBridgedServices Bean in the
     * applicationContext. It is basically an instance of itself, which was
     * registered by the @Component annotation.
     *
     * @return the SpringContextBridgedServices, which exposes all the Spring
     *         services that are bridged from the Spring context.
     */

    public static SpringContextBridgedServices services() {
        return applicationContext.getBean(SpringContextBridgedServices.class);
    }
}

You may wonder what is SpringContexxtBridgedServices. Yes That class is as follows

public interface SpringContextBridgedServices {
    
    CoffeeAuthorizationService getAuthorizationService();

    CoffeeGroupParser getCoffeeGroupParser();

    CoffeeGroupService getCoffeeGroupService();

    AppProperties getAppProperties();

    EmailService getEmailService();

    CoffeeCloudProperties getCoffeeCloudProperties();

    CoffeeUtil getCoffeeUtil();

}
Jithin M V
  • 175
  • 1
  • 1
  • 10
  • General rule of thumb, don't mix spring with `static`, this code should be refactored, as it's messy and unnecessary complicated... – Lino May 06 '21 at 14:02
  • Well, you _have_ autowiring in `SpringContextBridge`, e.g. `@Autowired private EmailService emailService;`. Then `applicationContext.getBean(SpringContextBridgedServices.class);` picks up `SpringContextBridge` as an implementation of that interface and returns an instance. That being said `ApplicationContextAware` makes Spring realize that you want an instance of `SpringContextBridge` to be fed an application context. Storing that in a static field doesn't look like the best idea but that's your connection. – Thomas May 06 '21 at 14:05
  • @Thomas Hey thanks for responding. One more doubt is why we need this much complication. The SpringContextBridge itself auto wires all the required beans. So I can simply call the getter from that right? Why we need this SpringContextBridgedServices at all? – Jithin M V May 07 '21 at 07:16
  • That depends. While you could do without the interface there might be a reason for it to exist. In general you'd want to [program to an interface](https://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface) if there are good reasons, e.g. if you might want to replace the implementation (e.g. `List> l = new ArrayList<>()` and later you'd want to use a `LinkedList` instead) but whether there are such reasons in your case I can't tell. You'd need to ask the devs. – Thomas May 10 '21 at 05:54

0 Answers0