1

This question might sound lame but I had a doubt so I wanted to clear it out. I am reading Getting Started with Spring Framework by Ashish Sarin and there is this simple code which fetches a spring bean of type FixedDepositService class

package sample.spring.chapter06.bankapp;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import sample.spring.chapter06.bankapp.domain.FixedDepositDetails;
import sample.spring.chapter06.bankapp.service.FixedDepositService;

public class BankApp {
    public static void main(String args[]) throws Exception {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "classpath:META-INF/spring/applicationContext.xml");

        FixedDepositService fixedDepositService = context
                .getBean(FixedDepositService.class);
        fixedDepositService.createFixedDeposit(new FixedDepositDetails(1, 0,
                12, "someemail@somedomain.com"));
        fixedDepositService.createFixedDeposit(new FixedDepositDetails(1, 1000,
                12, "someemail@somedomain.com"));
    }
}

Now FixedDepositService is an interface and not a concrete class. It is implemented by another class called FixedDepositServiceImpl like this

....
@Service(value = "fixedDepositService")
public class FixedDepositServiceImpl implements FixedDepositService {
....
}

My question is, how does this code work? Shouldn't the BankApp class fetch a bean of FixedDepositServiceImpl class instead of FixedDepositService class since FixedDepositService is just an interface and contains no method definitions and FixedDepositServiceImpl is the class that actually implements it and has all the logic defined in it?

user1232138
  • 5,451
  • 8
  • 37
  • 64

2 Answers2

1

In straight you can use getClass().getName() to see which class object is it

FixedDepositService service = (FixedDepositService) context.getBean("fixedDepositService");

System.out.println(service.getClass().getName());  //FixedDepositServiceImpl
Ryuzaki L
  • 37,302
  • 12
  • 68
  • 98
  • Thank you for the answer. But how does Spring pick what interface implentation to pick? – user1232138 Sep 26 '19 at 00:47
  • There is a concept called autowiring and dependency injection https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-dependencies @user1232138 or this link https://stackoverflow.com/questions/12899372/spring-why-do-we-autowire-the-interface-and-not-the-implemented-class – Ryuzaki L Sep 26 '19 at 00:58
1

In spring this is the concept behind decoupling your actual implementation/behaviour from the client and use it as a strategy depends on your requirement.

As you mentioned above

Shouldn't the BankApp class fetch a bean of FixedDepositServiceImpl class instead of FixedDepositService class since FixedDepositService is just an interface

This is the issue when you need to have multiple strategies defined from your requirement but in most cases this is used without any actual requirement behind.

If you do not need to decouple your implementation as you implement above it is totally fine to make your FixedDepositService a concrete class and use (using @Component).

But if you have multiple implementations based on your requirement you can use a @Qualifier to mention what implementation you are going to use based on a strategy.

List<? extends FixedDepositService> fixedDepositServices; //use based on a strategy

Or

//inject single implementation if you know what you want
@Qualifier("diffrentFixedDepositService") FixedDepositService diffrentFixedDepositService; 

And also it is not needed to name your service class like @Service(value = "fixedDepositService") because your not really using a (different name or you only have one implementation) for your service class.

MaxExplode
  • 1,977
  • 2
  • 17
  • 27