Home Inversion of Control ve Dependency Injection
Post
Cancel

Inversion of Control ve Dependency Injection

Inversion of Control Nedir?

Kabaca, kodumuz çalışacağı zaman framework’ün kodumuzu çağırması, çalıştırması ve kontrolü tekrar ele alması sürecine Inversion of Control denir. Biraz daha teknik ifadeleri verecek olursak; bir uygulamanın bir kısmının ya da objelerinin kontrolünün bir framework’e verilmesi olarak tanımlayabiliriz. Bu yapının tanımı genellikle OOP context’i içerisinde kullanılır. Kod içerisinde bir çağrım yaptığımızda framework’ün program akışını ele alması ve kodumuz üzerinde çağırımlar yapmasına imkan tanır. Bunu sağlamak için de framework’ler ek bazı davranışlara sahip abstractionları kullanır. Eğer kendi davranışımızı da eklemek istersek framework’ün ilgili yapısını kendi sınıflarımıza extend etmemiz gerekir.

Bu mimarinin faydalarını listeleyecek olursak:

  • Bir task’ın execute edilmesini kendi implementasyonundan ayırır
  • Farklı implementasyonlar arası geçişi oldukça kolaylaştırır
  • Kodun modüleritesini artırır
  • Component’leri izole ederek test etmeyi kolaylaştırır.

Spring IoC Container

Aslında IoC container ifadesi IoC konseptini implement etmiş framework’ler için genel bir ifadedir. Spring Framework’de ise bu yapının ismi ApplicationContext ile tanımlanmıştır. Spring IoC container ise Bean ismini verdiğimiz objelerin örneklenmesi, konfigüre edilmesi ve lifecycle’larının yönetilmesi gibi işlemleri yapar. En basit şekilde SpringBoot kullandığımızı düşünürsek şu şekilde IoC container’a erişmemiz mümkün:

1
ApplicationContext ctx = SpringApplication.run(SpringApplication.class, args);

Dependency Injection Nedir?

Dependency Injection aslında IoC’nin implement edilmesini sağlayan bir pattern’dır ve programımızın ihtiyacı olan bağımlılıkları sağlaması amaçlanır. Kısacası kod içerisinde inject ettiğimiz bağımlılıklarımız için bizim buna ihtiyacımız var git bunu getir ve bu sınıf içerisinde inject et diyeceğimiz bir konsepti ifade ediyor.

Spring Framework kullanarak Dependency Injection sağlamanın 3 farklı yolu var.

Constructor ile Dependency Injection

Örneğin bir servis sınıfımız olsun ve bu servis sınıfımızın bağımlı olduğu bazı repository’leri ya da farklı servisleri olsun. Eğer constructor ile Dependency Injection yapmayı planlıyorsak bunu değişkenlerimizin access modifier’larını private final olarak tanımlayarak yapabiliriz. Ek olarak şunu da belirteyim; eğer sınıfımızda tek bir constructor bulunuyorsa Spring 4.3 ve üzeri versiyona sahipseniz, Spring bu constructor’ı siz belirtmezseniz otomatik olarak @Autowired ile işaretliyor. Yani aslında bu örnekte @Autowired yazmasak bile bu yapı çalışacaktı. Örnek verecek olursak:

1
2
3
4
5
6
7
8
9
10
11
public class UserService {

    private final UserRepository userRepository;
    private final RabbitTemplate rabbitTemplate;

    @Autowired
    public UserService(UserRepository userRepository, RabbitTemplate rabbitTemplate) {
        this.userRepository = userRepository;
        this.rabbitTemplate = rabbitTemplate;
    }
}

Lombok kullanarak constructor’ı elle oluşturmaya gerek kalmadan da aynı işi yapabiliyoruz. Buraya tıklayarak @RequiredArgsConstructor notasyonunu incelemenizi öneririm.

Setter ile Dependency Injection

1
2
3
4
5
6
7
8
public class ChannelServiceImpl implements ChannelService {
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}

Field ile Dependency Injection

Field ile inject etme örneği de bu şekilde ancak bu yöntem önerilmemekte. Çünkü debug yapmak istediğiniz zaman burada ne değişken set edilirken ne döndüğünü görebileceğiniz bir debug point atma şansınızı kaybediyorsunuz. Bu nedenle constructor kullanımı öneriliyor.

1
2
3
4
5
6
7
8
9
10
11
public class AuthController {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private JwtUserDetailsService userDetailsService;
}
This post is licensed under CC BY 4.0 by the author.