Preparing for Spring Professional Certification. Container, IoC, Beans

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.







Why am I doing this, because there are already a bunch of specialized materials?
  1. Often the information in them is not structured, not collected, or not relevant

  2. Young developers may not know English. This cycle can be used not only for certification, but also for self-training / repetition of materials.

  3. These materials can be used in preparation for the interview, as they are arranged in the form of questions and answers.

  4. An important and most important advantage is that this QA is made from questions from the official Pivotal Study Guide .



  • I deliberately missed some questions that seemed to me superfluous or which were not in the guide .


Table of contents
  1. Dependency injection, container, IoC, beans
  2. AOP (aspect-oriented programming)
  3. JDBC, Transactions, JPA, Spring Data
  4. Spring boot
  5. Spring mvc
  6. Spring security
  7. REST
  8. Testing




I’ll write a list of sources from which the author took materials
  • Spring 5 design patterns

  • Spring in Action 4th edition

  • Spring Security - Third Edition

  • Core Spring 5 Certification in Detail by Ivan Krizsan

  • Spring Documentation and Spring API javadocs



So, let's begin.







What is dependency injection (DI) and what are its benefits?

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.







DI Benefits
  • Reduced communication between parts of the application

  • Improved testing

  • Enhanced Application Architecture

  • Reduces boilerplate code

  • Standardizes application development



Why are interfaces recommended for creating Spring beans?
  • Improved testing. In tests, the bean can be replaced with a special object (mock or stub) that implements the bean interface.

  • Allows you to use the dynamic proxy mechanism from the JDK (for example, when creating a repository via Spring Data)

  • Allows you to hide the implementation



What is application context?

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.







What is a container and what is its life cycle?

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.







Container life cycle
  1. The container is created when the application starts.

  2. The container reads configuration data

  3. Description of bins is created from configuration data

  4. BeanFactoryPostProcessors handle bean description

  5. The container creates beans using their description

  6. Beans are initialized - property values ​​and dependencies are embedded in the bean

  7. BeanPostProcessor start callback methods

  8. The application is up and running

  9. Initialized application closure

  10. Container closes

  11. Callback methods are called



How to create an instance of ApplicationContext?

Spring provides several variations of context.







There are several basic implementations of the ApplicationContext interface:







  • FileSystemXmlApplicationContext

  • ClassPathXmlApplicationContext

  • AnnotationConfigApplicationContext

  • XmlWebApplicationContext

  • AnnotationConfigWebApplicationContext



Examples of creating a context:







 ApplicationContext ctx = new FileSystemXmlApplicationContext(                                     "c:/bean_properties.xml"); ApplicationContext ctx = new AnnotationConfigApplicationContext(                            "com.springdemoapp.JavaConfig.class");
      
      





Can you describe the life cycle of a bean in a container?
  1. Loading bin descriptions, creating a dependency graph (between beans)
  2. Creating and BeanFactoryPostProcessors



  3. Create Beans
  4. Spring injects values ​​and dependencies into bean properties
  5. If the bean implements the setBeanName()



    method from the NameBeanAware interface, then the bean ID is passed to the method
  6. If the bean implements BeanFactoryAware, then Spring establishes a reference to the bean factory via setBeanFactory()



    from this interface.
  7. If the bean implements the ApplicationContextAware interface, then Spring establishes a reference to the ApplicationContext through setApplicationContext()



    .
  8. BeanPostProcessor



    is a special interface (about it below), and Spring allows beans to implement this interface. By implementing the postProcessBeforeInitialization()



    method, you can change the instance of the bean before initializing it (the bean) (setting properties, etc.)
  9. If callback methods are defined, then Spring calls them. For example, this is a method annotated by @PostConstruct



    or the initMethod



    method from an @Bean



    annotation.
  10. The bean is now ready for use. It can be obtained using the ApplicationContext#getBean()



    method.
  11. After the context is closed ( close()



    method from ApplicationContext), the bean is destroyed.
  12. If the bean has a method annotated by @PreDestroy



    , then this method will be called before destruction. If the bean implements a DisposibleBean, then Spring will call the destroy()



    method to clear resources or kill processes in the application. If the @Bean



    method is defined in the destroyMethod



    , then it is also called.



How to get ApplicationContext in integration test?

If you are using JUnit 5, then you need to specify 2 annotations:







  • `` @ExtendWith (TestClass.class) `` `` - used to indicate a test class

  • `` `` @ContextConfoguration (classes = JavaConfig.class) `` `` - loads the java / xml configuration to create context in the test



You can use the @SpringJUnitConfig



annotation, which combines both of these annotations.

You can use the @SpringJUnitWebConfig



annotation to test the web layer.







How to shut down context in an application?

If this is not a web application, then there are 2 ways:







  • Register shutdown-hook using the registerShutdownHook()



    method call, it is also implemented in the AbstractApplicationContext class. This is the preferred method.
  • You can call the close()



    method from the AbstractApplicationContext class.


In the Spring Boot application:







  • Spring Boot will self-register the shutdown-hook for you.


What is Java configuration? How is it applied?

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.







DI using annotations, class scanning

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.







What are stereotypes (stereotypical annotations)?

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)


What are the bin scopes? What is their default visibility?

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



How are beans created: immediately or lazily? How to change this behavior?

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.







What is a BeanFactoryPostProcessor and when is it used?
  • BeanFactoryPostProcessor



    works on bin descriptions or configuration metadata before the bin is created.
  • Spring provides several useful BeanFactoryPostProcessor



    implementations, for example, reading property files and getting BeanFactoryPostProcessor



    properties from them.
  • You can write your own implementation of BFPP.


Why do you need the static @ Bean method?

In order to use custom BFPP. You can override the mechanism for obtaining data from metafiles.







 @Bean public static PropertySourcesPlaceholderConfigurer pspc() {    //,    pspc }
      
      





Describe @Bean annotation properties
  • destroyMethod



    - points to a callback method. The method is in the bin.
  • initMethod



    - points to a callback method. The method is in the bin.
  • name



    - the name of the bean. By default, the bean name is the method name.
  • value



    - alias for name ()


What is a BeanPostProcessor and how is it different from a BeanFactoryPostProcessor?

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.













What are callback methods and how to use them?

There are 3 options for creating such methods:







  • @PreDestroy



    and @PostConstruct



    annotations
  • The initMethod



    and destroyMethod



    in the destroyMethod



    annotation that point to methods in the bean class
  • InitializingBean#afterPropertiesSet()



    and DisposableBean#destroy()



    . To override these methods, you need to implement the corresponding interfaces.








How can I use @Autowire annotation and what is the difference between the ways?

The following are the types of DI that can be used in your application:







  • Constructor DI
  • Setter di
  • Field di


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.







Describe the behavior of @Autowired annotation
  1. The container determines the type of object to embed.
  2. A container searches for beans in a context (aka a container) that match the desired type
  3. If there are several candidates, and one of them is marked as @Primary



    , then it is implemented
  4. If @Autowire



    + Qualifier



    annotations are used, the container will use the information from @Qualifier



    to figure out which component to deploy
  5. Otherwise, the container will attempt to inject the component based on its name or ID.
  6. If none of the methods worked, an exception will be thrown


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)
      
      





How to make DI in a private field?

You can use different types of implementation:







  • Constructor
  • Setter
  • Field injection
  • Value


How does using @Qualifier complement @Autowired?

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.







What are proxy objects and what types of proxy objects can Spring create?

A proxy is a special object that has the same public methods as the bean, but which has additional functionality.

Two types of proxies:







  • JDK-proxy - dynamic proxy. APIs are built into the JDK. It needs an interface
  • CGLib proxy - not built into the JDK. Used when the interface of an object is unavailable.


Pros of proxy objects:







  • Allow to add extra. logic - transaction management, security, logging
  • Separates some code (logging, etc.) from the main logic


How is a singleton bean implemented?

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.







What are profiles? What are their reasons for using?

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() {...}
      
      





How to embed simple values ​​in properties in Spring?

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.



All Articles