Dependency Injection

Dependency injection

Dependency injection (DI) είναι μια διαδικασία, στην οποία τα αντικείμενα ορίζουν τις εξαρτήσεις τους (τα άλλα αντικείμενα με τα οποία δουλεύουν), μόνο μέσω παραμέτρων κατασκευαστή, παραμέτρων σε μια μέθοδο- εργοστάσιου ή μέσω properties, τα οποία ορίζονται στο στιγμιότυπο αντικειμένου, αφού αυτό κατασκευαστεί ή επιστραφεί από μέθοδο-εργοστάσιο. Το container ύστερα κάνει inject τις εξαρτήσεις, όταν δημιουργεί το bean. Η διαδικασία είναι ουσιαστικά η αντίστροφη, από το να ελέγχει το αντικείμενο-bean την αρχικοποίηση ή την τοποθεσία των εξαρτήσεων του , χρησιμοποιώντας απευθείας κατασκευή των κλάσεων.

Ο κώδικας είναι πιο "καθαρός" εφαρμόζοντας DI και πετυχαίνουμε χαμηλή σύζευξη, όταν στα αντικείμενα παρέχονται οι εξαρτήσεις τους. Τα αντικείμενα δεν ψάχνουν τις εξαρτήσεις τους και δεν γνωρίζουν την τοποθεσία ή την κλάση των εξαρτήσεων. Έτσι, είναι πιο εύκολο να πραγματοποιηθούν test στις κλάσεις, ειδικά όταν οι εξαρτήσεις είναι διεπαφές ή αφηρημένες κλάσεις, οι οποίες επιτρέπουν, να χρησιμοποιηθούν mock implementations στα unit tests.

Υπάρχουν δύο είδη dependency injection : Constructor-based dependency injection και Setter-based dependency injection.

Χωρίς dependency injection

                     
                         public class SimpleMovieLister {
 
                             // Η κλάση SimpleMovieLister εξαρτάται από τη MovieFinder
                             private MovieFinder movieFinder;
 
                             public SimpleMovieLister() {
                                    this.movieFinder = new MovieFinder();
                            }

                         }
                     
                 

Η κλάση SimpleMovieLister χρησιμοποιεί ένα στιγμιότυπο της κλάσης MovieFinder και παρέχει η ίδια ένα στιγμιότυπο στο κώδικα, χρησιμοποιώντας το keyword new και τον κατασκευαστή MovieFinder().

Constructor-based Dependency Injection

Το Constructor-based DI πραγματοποιείται από το Container, καλώντας έναν κατασκευαστή με έναν αριθμό παραμέτρων, όπου το καθένα αναπαριστά μια εξάρτηση.

                    
                        public class SimpleMovieLister {

                                // Η κλάση SimpleMovieLister εξαρτάται από τη MovieFinder
                                private MovieFinder movieFinder;

                                // Χρησιμοποιείται κατασκευαστής, ώστε το Spring Container να κάνει inject ένα στιγμιότυπο Moviefinder.
                                public SimpleMovieLister(MovieFinder movieFinder) {
                                      this.movieFinder = movieFinder;
                            }

                        }
                    
                

Setter-based Dependency Injection

Το Setter-based DI πραγματοποιείται από το Container, καλώντας μεθόδους setters στα αντικείμενα, αφού καλέσουν πρώτα έναν κατασκευαστή χωρίς παραμέτρους ή μια μέθοδο-εργοστάσιο χωρίς παραμέτρους, για την αρχικοποίηση του αντικειμένου.

                     
                         public class SimpleMovieLister {
 
                                // Η κλάση SimpleMovieLister εξαρτάται από τη MovieFinder
                                private MovieFinder movieFinder;
 
                                // Χρησιμοποιείται η μέθοδος setter, ώστε το Spring Container να κάνει inject ένα στιγμιότυπο Moviefinder.
                                public void setMovieFinder(MovieFinder movieFinder) {
                                      this.movieFinder = movieFinder;
                                    }
 
                         }
                     
                 

Dependency Injection με το annotation @Autowired

Ξεκινώντας από την έκδοση 2.5, το Spring εισήγαγε ένα νέο τρόπο, να πραγματοποιήσουμε Dependency Injection με το annotation @Autowired. Αυτό το annotation επιτρέπει στο Spring να αποφασίζει και να κάνει inject τα συνεργαζόμενα beans σε ένα bean. Μπορεί να χρησιμοποιηθεί είτε σε πεδίο, είτε στον κατασκευαστή.

                     
                         public class SimpleMovieLister {
 
                                // Το Spring κάνει inject ενα στιγμιότυπο movieFinder.
                                @Autowired
                                private MovieFinder movieFinder;
 
                         }
                     
                 

Πηγές