3

I recently stumbled upon a code like the one below.

@Component    
public class Instance {

    private static Instance instance;
    private final Template template;

    public Instance(Template template) {
        this.template = template;
        Instance.instance = this;
    }

    static void someMethod() {
        instance.template.doSomething();
    }
}

From my understanding this is done so that you could use template in a static method but then again you could just inject the Instance class to where you need it and avoid static method altogether.

@Component    
public class Instance {

    private final Template template;

    public Instance(Template template) {
        this.template = template;
    }

    void someMethod() {
        template.doSomething();
    }
}

I am curious as to what is the use case of such pattern and if there are any alternatives to that, thanks!

Rauno
  • 616
  • 8
  • 22

1 Answers1

3

[edit] Just realised that the static field is private and therefore not exposable to the outer non-Spring world as I've interpreted below.

In that case I don't see any reason whatsoever to do this. The Instance bean is singleton by virtue of the Spring 'singleton' scope. So introducing this static private field doesn't make any sense therefore what you are suggesting is obviously the correct approach.


[before edit]

I guess this is done to expose Instance Spring bean to other code that is not Spring-related i.e. some non-Spring code can invoke Instance.someMethod()

But still this is a bad idea in my opinion as it adds the non-intuitive responsibility within the Spring bean: "How can I be accessible from outside Spring?". And what do we do then for another Spring bean? Add this Spring-anti-pattern to all Spring beans?

If this is needed in one or just few places I would suggest using @Configurable to Spring-ify a class where you can inject the dependency as needed.

Otherwise, I would suggest the application to take care of this "Spring to non-Spring" interop centrally and agnostic to beans: Maybe hide upon startup the ApplicationContext and retrieve beans internally exponsing a Spring-agnostic API.

dimitrisli
  • 20,895
  • 12
  • 59
  • 63
  • `instance` being `private` doesn't prevent you from calling `Instance.someMethod()`, thus I don't see the reason edit. The prior answer is still correct. – Tom Jan 04 '18 at 11:10
  • @Tom thanks for that. I primarily meant to be accessed from some other non-Spring code as Instance.someMethod() – dimitrisli Jan 04 '18 at 11:12
  • And that is still possible (every class can call `Instance.someMethod()` as long as it is placed in the same package) and I also agree that this was surely the main reason why the code was implemented like this. I guess I'm missing something here, because the code looks like one wanted to expose `someMethod` to either a non-Spring class or to something static and used that way and your answer explains that correctly. I still don't see how the `private` modify on `instance` changes something. – Tom Jan 04 '18 at 11:19
  • Thanks for clearing it up. This is exactly the kind of explanation I was hoping for! – Rauno Jan 04 '18 at 11:22