Good day, Habr.
Today I decided to present you a translation of a series of articles in preparation for Spring Professional Certification .
This translation is only the first article, if it goes to the audience, I will continue to issue translations.
 
      So, let's begin.
  Dependency injection is a special pattern that reduces communication between Spring components.  Thus, when applying DI, your code becomes cleaner, simpler, it becomes easier to understand and test. 
      
        
        
        
      
      According to the DI pattern, creating objects for dependencies is transferred to the factory or given to a third party.  This means that we can focus on using these objects instead of creating them. 
 In the Spring Framework, the org.springframework.factory.BeanFactory
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     interface provides a org.springframework.factory.BeanFactory
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     factory, which at the same time is an IoC container for the application.  Bean management is configuration based (java or xml). 
  The org.springframework.context.ApplicationContext
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     interface is a wrapper over a bean factory that provides some additional features, such as AOP, transactions, security, i18n, etc. 
  The basis of the Spring Framework is a container, and our objects "live" in this container. 
      
        
        
        
      
      A container typically creates many objects based on their configurations and manages their life cycle from creating an object to destruction. 
A container is an object that implements the ApplicationContext interface.
Spring provides several variations of context.
There are several basic implementations of the ApplicationContext interface:
Examples of creating a context:
 ApplicationContext ctx = new FileSystemXmlApplicationContext(                                     "c:/bean_properties.xml"); ApplicationContext ctx = new AnnotationConfigApplicationContext(                            "com.springdemoapp.JavaConfig.class");
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      BeanFactoryPostProcessors
      
      setBeanName()
      
      setBeanFactory()
      
      setApplicationContext()
      
      BeanPostProcessor
      
      postProcessBeforeInitialization()
      
      @PostConstruct
      
      initMethod
      
      @Bean
      
      ApplicationContext#getBean()
      
      close()
      
      @PreDestroy
      
      destroy()
      
      @Bean
      
      destroyMethod
      
      
If you are using JUnit 5, then you need to specify 2 annotations:
  You can use the @SpringJUnitConfig
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     annotation, which combines both of these annotations. 
      
        
        
        
      
      You can use the @SpringJUnitWebConfig
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     annotation to test the web layer. 
If this is not a web application, then there are 2 ways:
registerShutdownHook()
      
      close()
      
      In the Spring Boot application:
  To create a class with configuration based on Java code, you need to annotate it with 
      
        
        
        
      
      @Configuration
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     . 
      
        
        
        
      
      This class will contain factory methods for creating beans in the container. 
      
        
        
        
      
      These methods should be annotated with the @Bean
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     annotation. 
Example:
 @Configuration public class DSConfig {  @Bean  public DataSource dataSource() {      return DataSourceBuilder          .create()          .username("")          .password("")          .url("")          .driverClassName("")          .build();  } }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      This class will place an instance of the DataSource class in the container. Later it can be used when accessing the database.
Component scanning - Spring automatically detects the beans that will be in the container. These are bins with annotations-stereotypes.
  However, component scanning is not enabled by default. 
      
        
        
        
      
      To enable scanning, annotate the @ Configuration class with the annotation @ComponentScanning
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     .  Spring will automatically scan the package that contains this class and all its subpackages. 
      
        
        
        
      
      You can specify other packages for scanning, and even classes: 
 // 2  @Configuration(<i>basePackages</i> = {"soundsystem", "video"})
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
       //  @Configuration(<i>basePackageClasses</i> = "MyClass.class")
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
        Autowiring - Spring will automatically inject dependencies when scanning or placing a bin in a container. 
      
        
        
        
      
      Dependency injection uses the @Autowire
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     annotation. 
  Stereotypes are annotations denoting special functionality. 
      
        
        
        
      
      All stereotypes include @Component
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     annotation. 
| Component | The root annotation that marks a class as a candidate for auto-implementation | 
| Controller | Indicates that the class is the controller for sending data to the front. | 
| @RestController | Indicates that the class is the controller for REST. Contains Controller and @ResponseBody annotations | 
| Service | Indicates that the class is a service for executing business logic. | 
| Repository | Indicates that the class is a repository for working with the database. | 
| @Configuration | Indicates that the class contains a Java configuration (@ Bean methods) | 
Scope - scope. There are 2 default scopes.
| Singleton | The default scope.  There is only 1 bean instance in the container | 
| Prototype | Any number of bin instances can be in the container | 
And 4 scopes in a web application.
| Request | Scope - 1 HTTP request.  A new bean is created for each request. | 
| Session | Scope - 1 session.  A new bean is created for each session. | 
| Application | Scope - ServletContext Life Cycle | 
| Web socket | Scope - WebSocket Life Cycle | 
  Singleton beans are usually created immediately upon scanning. 
      
        
        
        
      
      Prototype beans are usually created only upon request. 
  You can use the @Lazy
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     annotation to indicate how to initialize. 
      
        
        
        
      
      It is placed on @ Bean methods, on @ Configuration classes, or on @ Component classes. 
      
        
        
        
      
      Depending on the parameter (true or false) that the annotation accepts, initialization will either be lazy or will happen immediately.  By default (i.e., without specifying a parameter), true is used. 
BeanFactoryPostProcessor
      
      BeanFactoryPostProcessor
      
      BeanFactoryPostProcessor
      
      In order to use custom BFPP. You can override the mechanism for obtaining data from metafiles.
 @Bean public static PropertySourcesPlaceholderConfigurer pspc() {    //,    pspc }
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      destroyMethod
      
      initMethod
      
      name
      
      value
      
        Spring uses several BeanPostProcessors. 
      
        
        
        
      
      For example, CommonAnnotationPostProcessor
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     or AutowiredAnnotationBeanPostProcessor
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     . 
      
        
        
        
      
      BPP works with bean instances, i.e.  the container creates the bin, and then BPP starts. 

There are 3 options for creating such methods:
@PreDestroy
      
      @PostConstruct
      
      initMethod
      
      destroyMethod
      
      destroyMethod
      
      InitializingBean#afterPropertiesSet()
      
      DisposableBean#destroy()
      
      
The following are the types of DI that can be used in your application:
  DI through the constructor is considered the best way, because  for him there is no need to use reflection, and also he does not have the disadvantages of DI through the setter. 
      
        
        
        
      
      DI through the field is not recommended, because  For this, reflection is used that reduces productivity. 
      
        
        
        
      
      DI through the constructor can lead to circular dependencies .  To avoid this, you can use lazy initialization of beans or DI through the setter. 
@Primary
      
      @Autowire
      
      Qualifier
      
      @Qualifier
      
      The container handles the DI using the AutowiredAnnotationBeanPostProcessor . In this regard, the annotation cannot be used in any BeanFactoryPP or BeanPP.
If the injected object is an array, collection, or map with a generic, then Spring will embed all the beans that are of type in this array (or another data structure). In the case of map, the key will be the bin name.
 // ,   DI @Authowired(required = true/false)
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      Spring provides Qualifier annotation to overcome the DI ambiguity problem.
 @Bean @Qualifier("SomeClass1") public SomeClass getField() {...} //… @Autowire @Qualifier("SomeField1") public SomeClass someField;
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
        If there are several bins of the same type in the container (SomeClass), then the container will implement the bean with the corresponding qualifier above the @ Bean method.  You can also not put a qualifier on a method, but use the bean name as a qualifier parameter. 
      
        
        
        
      
      The bean name can be specified through the Bean annotation parameter, and by default this is the name of the factory method. 
  A proxy is a special object that has the same public methods as the bean, but which has additional functionality. 
      
        
        
        
      
      Two types of proxies: 
Pros of proxy objects:
If there is no bean instance in the container, the @ Bean method is called. If there is a bean instance, then the already created bean is returned.
  When using the Java configuration, you can use the @Profile
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     annotation. 
      
        
        
        
      
      It allows you to use different settings for Spring, depending on the specified profile. 
      
        
        
        
      
      It can be placed on the @Configuration and Component classes, as well as on Bean methods. 
 Profile("!test") //   ,  
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
       @Bean("dataSource") @Profile("production") public DataSource jndiDataSource() {...} @Bean("dataSource") @Profile("development") public DataSource standaloneDataSource() {...}
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
        You can use the @Value
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     annotation for @Value
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
     . 
      
        
        
        
      
      Such values can be obtained from property files, from bins, etc. 
 @Value("$some.key") public String stringWithDefaultValue;
      
      
        
        
        
      
    
        
        
        
      
      
        
        
        
      
    
      
      A string will be embedded in this variable, for example, from property or from view.
As usual, please send corrections or errors found in PM.