Spring Dependency Injection via Setter Example


In this article, we will learn how to use setter-based dependency injection in Spring applications.

In the below diagram, the highlighted part of the code shows a setter-based dependency injection example.



Let's see the complete example to demonstrate Setter-based dependency injection.
As we know, spring java and annotation based configurations are quite easy to use in spring based applications so I prefer to use a mix of java and annotation based spring configurations.
In this example, we have used spring Java-based container configuration.
Let's create spring configuration file using java class AppConfiguration and annotated with @Configuration annotation. This is equivalent to spring XML configuration file without beans definition.
package com.javadevsguide.springframework.di.config;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.javadevsguide.springframework.di")
public class AppConfiguration {

}
Now create MessageService interface and provide more than two implementations for it.

public interface MessageService {
    public void sendMsg(String message);
}
Let's implement the MessageService interface. There are many ways to send a message like through email, SMS, twitter etc.
@Service("EmailService")
public class EmailService implements MessageService{
    public void sendMsg(String message) {
        System.out.println(message);
    }
}
@Service("SMSService")
public class SMSService implements MessageService{
    public void sendMsg(String message) {
        System.out.println(message);
    }
}
@Service("TwitterService")
public class TwitterService implements MessageService{
    public void sendMsg(String message) {
        System.out.println(message);
    }
}
Note that there are multiple implementations for MessageService interface so to avoid ambiguity, let's use @Qualifier annotation.

It's time to demonstrate the usage of Setter-based dependency injection. To avoid decoupling always use interfaces or abstract base classes as an instance variable and setter method arguments. In this example, we have used the MessageService interface.
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Component;
    
    import com.javadevsguide.springframework.di.service.MessageService;
    
    @Component
    public class SetterBasedInjection {
        private MessageService messageService;
    
        @Autowired
        @Qualifier("TwitterService")
        public void setMessageService(MessageService messageService) {
            this.messageService = messageService;
        }
    
        public void processMsg(String message) {
            messageService.sendMsg(message);
        }
    }
    It's time to test the usage of Constructor-based dependency injection. Let's create IOC container object that is an ApplicationContext object and get the beans from it.
    import org.springframework.context.ApplicationContext;
    
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    import com.javadevsguide.springframework.di.config.AppConfiguration;
    import com.javadevsguide.springframework.di.field.FieldBasedInjection;
    
    public class TestApplication {
        public static void main(String[] args) {
            ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfiguration.class);
            FieldBasedInjection  fieldBasedInjection = applicationContext.getBean(FieldBasedInjection.class);
            fieldBasedInjection.processMsg("twitter message sending ");
        }
    }
    Note that we have used AppConfiguration class annotated with @Configuration for configurations.
    Output:
    twitter message sending 

    Comments