Εμφάνιση αναρτήσεων με ετικέτα @PropertySource. Εμφάνιση όλων των αναρτήσεων
Εμφάνιση αναρτήσεων με ετικέτα @PropertySource. Εμφάνιση όλων των αναρτήσεων

Πέμπτη 4 Νοεμβρίου 2021

Spring Certification: Container, Dependency and IOC

What is dependency injection and what are the advantages of using it?
  • Dependency injection is a technique where application components don't create their dependencies on their own, but instead declare the dependencies' interfaces, and then the application context finds and applies real implementations of them
  • Advantages:
    • Reduced coupling
    • Increased cohesion
    • Reduced boilerplate code
    • Facilitates testing (use of mocks in place of dependencies)
    • Increased code maintainability, re-usability and readability

What is an interface and what are the advantages of making use of them in Java?
  • Interface is a Java reference type that holds a blueprint of the functionalities that should be implemented from a class. It provides a contract for an object's functionalities. It enforces the implementation of an API.
  • Advantages:
    • Decoupling of contract and implementation
    • Enables implementations' interchangeability
    • Allows implementation hiding, so that only the interface is public, and all implementations are protected, and thus one can only use e.g. @Qualifier("bean1") in caller class
    • In Spring, allows the use of JDK Dynamic Proxy

What is an ApplicationContext?
  • ApplicationContext is the representation of the Spring IoC container, and holds registered and initialized beans and components, ready for use in runtime. Also:
  • Provides access to the Environment abstraction and its properties
  • Pushes events to registered listeners
  • Manages beans lifecycle 
  • Resolves internationalization messages

How are you going to create a new instance of an ApplicationContext?
  • Web applications:
    • Inside a class implementing ServletContainerInitializer, use AnnotationConfigWebApplicationContext to include a Java Configuration file
    • Use a WebXmlApplicationContext, to include xml(s) holding all configuration
  • Standalone application:
    • Use AnnotationConfigApplicationContext to include a Java Configuration file
    • Use ClassXmlApplicationContext to load the xml configuration from classpath/jar
    • Use FileSystemXmlApplicationContext to load the xml configuration from the file system

What is the concept of a Container, what its lifecycle?
  • Container is an execution environment that plays a central role in assembling user-defined components, managing their lifecycle and also providing basic functionalities, like HTTP and REST.
    It usually supports the inversion-of-control (IOC) principle, so that the programmer only creates beans and declares dependencies, and finally the Container does the underlying work of linking all together.
  • Lifecycle:
    • App starts
    • Container is created and load all configuration to
    • create Bean Definitions
    • Any BeanFactoryPostProcessors now run to alter the definitions
    • Bean instances are created
    • Any bean dependencies and property injections are resolved
    • Any BeanPostProcessors run to alter bean instances
    • App now is up and ready 
    • App shutdown is initiated
    • Context is closing
    • Any destruction callbacks take place to release resources, etc


Can you describe the lifecycle of a Spring Bean in an ApplicationContext?

  • Context is created
  • Bean Definitions created (Spring Bean Configuration)
  • BeanFactoryPostProcessors 
  • Bean Instance created (constructor runs)
  • Properties and dependencies are resolved
  • BeanPostProcessor: postprocessBeforeInitialization method 
  • @PostConstruct annotated method 
  • InitializingBean::afterPropertiesSet 
  • @Bean(initMethod) 
  • BeanPostProcessor: postprocessAfterInitialization method 
  • Bean ready to use.
  • Bean destroyed:
  • @PreDestroy
  • DisposableBean::destroy
  • Bean(@DestroyMethod)


How are you going to create an ApplicationContext in an integration test?
  • Import maven dependencies of spring-test and JUnit
  • Before JUnit 5: Annotate test class with @RunWith(SpringRunner.class) and @ContextConfiguration(classes = MyAppConf.class)
  • After JUnit 5: Annotate test class with @ExtendWith(SpringExtension.class) @ContextConfiguration(classes=MyAppConf.class)
  • If @ContextConfiguration has no "classes" attribute, then xml <TestClass>-context.xml will be loaded
  • @ContextConfiguration can also accept XML config:
    • Example: @ContextConfiguration("file:src/main/webapp/WEB-INF/spring-config.xml")
  • To above, add annotation @WebAppConfiguration to load a web related test context. However on Spring Boot, @SpringBootTest already provides a WebApplicationContext.
  • Use @DirtiesContext to clean/restart context between tests


What is the preferred way to close an application context? Does Spring Boot do this for you?
  • Non-web / Standalone app: Call registerShutDownHook immediately on a AnnotationConfigApplicationContext. This will trigger a JVM shutdown informing all beans, etc
  • Don't use close() on the context, since some exception may occur before that
  • Web app: Servlet will send closing event to ContextLoaderListener, which in turn will close the application context 
  • Spring Boot: Automatically registers the shutdown hook which closes the application context. For web apps, the same logic with above ContextLoaderListener applies


Are beans lazily or eagerly instantiated by default? How do you alter this behavior?
  • By default, Beans (Singletons by default) are eagerly instantiated on startup.
  • Note that each singleton bean is used for multiple threads.
  • Beans with prototype scope are lazily instantiated (on demand)
  • To alter, below ways exist:
    • @ComponentScan(lazyInit = true) to make scanned beans lazy
    • @Lazy on Bean to change default eagerness to lazy 
    • @Lazy(false) to force eagerness 
    • @Lazy on @Component class
    • @Lazy on @Configuration class (makes all @Bean-s lazy)

What is a property source? How would you use @PropertySource?
  • Property sources are key-value pairs in yaml/xml files, and accessed using a Spring abstraction on Environment key-value pairs (JVM, JNDI, system ..)

  • @PropertySource is used on top of a component class, like:

    • @PropertySources({
      @PropertySource("file:${app-home}/app-db.properties"),
      @PropertySource("classpath:/app-defaults.properties")
      })
    • If using non-default properties file name (other than application.properties/yml), define a PropertySourcePlaceholderConfigurer bean with the @Bean annotation to activate the placeholder resolving mechanism
    • Set @Value("${propertyKey:defaultValue}") on a field, to retrieve and initialize it


Can you describe: 
Dependency injection using Java configuration?
Dependency injection using Annotations (@Component, @Autowired)?
Component Scanning, stereotypes?
Scopes for Spring beans? What is the default scope?

  • Dependency injection using Java configuration
    • SpringBean1,2,3 are plain POJO classes
    • In our central configuration class, we appoint them as @Bean-s
    • Use of @Autowired to inject SpringBean1's dependencies (SpringBean2,3)

  • Dependency injection using Annotations (@Component, @Autowired)
    • Each bean will be annotated with @Component in its own class file
    • If any bean has dependencies on other beans, we create fields of these beans annotated with @Autowired
    • The Configuration file is annotated with @ComponentScan, and placed on a directory level higher than all our @Component beans




  • Component Scanning, Stereotypes?
    •  Spring will scan project classpath for classes annotated with stereotype annotations like @Component, @Repository, @Service, @Controller and more, in order to create Bean Definitions. 
    • @ComponentScan is used for this, applied in project root usually
    • Attributes "basePackages", "includeFilters", "excludeFilters" can be added for named adjustments.
    • Stereotypes refer to annotations that define some specific role in the project, thus: 
      • @Component  (Spring component, scanning candidate)
      • @Controller   (Component to handle the web layer)
      •  @Service   (Component to handle the Service layer)
      • @Repository  (Component to create beans in DAO layer)

  • Scopes for Spring beans? What is the default scope?
    • Scopes: Singleton, Prototype, Request, Session, Application, WebSocket

    • Default scope for @Components is the Singleton scope (also eager)

    • Singleton: Never hold state in these, in a multithreaded environment. All threads access the unique shared instance, and there may be concurrency issues. More:
      https://dzone.com/articles/how-does-singleton-bean-serve-multiple-requests-at

    • PrototypeA typical use case to create a bean in request scope is for information that should only be valid on one page. For example, the confirmation of an order. The bean will be valid until the page is reloaded.

    • Prototype case: A Singleton bean might contain a prototype bean. The issue is that since the Singleton will be instatiated only once, the prototype bean instance will be also unique. To solve this issue use the Lookup Method Injection: https://docs.spring.io/spring-framework/docs/3.0.0.M4/reference/html/ch03s04.html#beans-factory-lookup-method-injection





What is a BeanFactoryPostProcessor and what is it used for? When is it invoked?

  • BeanFactoryPostProcessor is an interface holding one postProcessBeanFactory method 
  • It is used to modify(not create) Spring Bean metadata, that will be used later to create the actual Beans
  • It is invoked before Spring Bean is created and after Spring discovers all Bean Definitions


What is a BeanPostProcessor and how is it different to a BeanFactoryPostProcessor? What do they do? When are they called?
  • BeanPostProcessor holds two methods: postProcessBeforeInitialization and postProcessAfterInitialization 
  • The difference with BeanFactoryPostProcessor, is that it acts after the Spring Bean is created from the Bean definition, and its dependencies and property injections are done
  • Thus BeanFactoryPostProcessor acts on Bean Definition, while BeanPostProcessor acts on actual Spring Bean object


Why would you define a static @Bean method when creating your own?

  • The reason would be to have it run before any object instance creation is done
  • Example:





What is a PropertySourcesPlaceholderConfigurer used for?
  • Ιt is a BeanFactoryPostProcessor bean used to resolve properties' placeholders in Spring Beans, and specifically on fields with @Value("${propertyName}") annotation


What is an initialization method and how is it declared on a Spring bean?
  • Initialization method purpose is to perform alterations on Spring Bean after all properties and dependencies are resolved. Otherwise, having initialization functionality inside constructor is a bad practice, since properties and dependencies may not have been resolved yet
  • Three ways to set init method:
    • @Bean(initMethod = "initMyBean")
    • @PostConstruct
    • Implement InitializingBean and override afterPropertiesSet (not recommended)


What is a destroy method, how is it declared and when is it called?
  • Destroy method is called to release resources a Bean uses, before it reaches end of life
  • It is declared in three ways:
    • @PreDestroy annotated methods inside Beans
    • Implementing a DisposableBean in our Bean class, and overriding its destroy() method
    • Use @Bean(destroyMethod = "someDestroyMethod")
  • Singleton beans (as default @Component-s) destroy method is called when application and Spring container starts to shut down. A session-scoped bean's destroy will be invoked after session ends. Same for request-scope. But, prototype-scoped beans aren't tracked from Spring after being created, so destroy method won't be called automatically.

Consider how you enable JSR-250 annotations like @PostConstruct and @PreDestroy?
  • When using AnnotationConfigApplicationContext, support for @PostConstruct and @PreDestroy is added automatically. Specifically, these are handled by CommonAnnotationBeanPostProcessor.



What does component-scanning do?
  • Spring framework scans project classpath in search for classes annotated with Stereotype annotations (@Component, @Controller, @Service, @Repository), and creates Bean Definitions in Spring container.


What is the behavior of the annotation @Autowired with regards to field injection, constructor injection and method injection?
  • Autowired annotation is processed by AutowiredAnnotationBeanPostProcessor and enables automatic Spring Dependency Resolution based on types. If there are multiple implementations for a type, we need to specify the unique candidate, usually with @Qualifier or @Primary or Spring will automatically match bean name

  • Autowired injection takes place after Bean constructor is run, to resolve the wanted dependencies. Autowired injections finishes before any initialization method (@PostConstruct, InitializingBean, @Bean(initMethod))

  • Constructor injection: @Autowired is applied above constructor method. All dependencies must not be null. If we expect some dependency to be null, use Optional, @Nullable, or @Autowired(required=false) for that parameter. If we have many constructors, we must apply @Autowire in one only.

    Tip:
     Use constructor injection to ensure with IoC container that all required dependencies are successfully initialized, and prevent NPEs. Additionally, all dependencies are visible in one place, and any refactoring need is facilitated.

  • Method/Setter injection: Same as above, and also if some parameter(s) are expected to be null, use @Autowired(required=false) above method. Preferable for optional dependencies.

  • Method injection - Map/Collection:
    @Autowired
    public void setRecordsReaders(List<RecordsReader> recordsReaders) {}

    Spring autowires all implementations of interface RecordsReader, by @Order or @Priority annotations, or Ordered interface 

  • Field injection: Same as above

  • More: https://reflectoring.io/constructor-injection/



What do you have to do, if you would like to inject something into a private field? How does this impact testing?
  • Use @MockBean to inject a mock in a private field (Here, ReportWriter is a private field of ReportService). Spring Test framework will create an application context, where the ReportWriter Bean will be replaced with a mock.
  • Use Mockito mock. No Spring application context is loaded here, only plain mocks. @InjectMocks will recognize and inject @Mocks that are dependencies of ReportService


  • Use ReflectionTestUtils to alter a private field using Reflection. Not recommended since a name refactoring will break this


  • Use @TestPropertySource to introduce a test properties file, to be utilized by @Value annotations in the code.


    Here, the targeted private field is a String. The @Value annotation will read property from the test property file of @TestPropertySource








How does the @Qualifier annotation complement the use of @Autowired?

  • "dbRecordsProcessor" will be matched with available Bean name







  • Or define explicitly in @Component attribute the Bean name to match


  • Or define explicitly using @Qualifier


  • Include @Qualifier inside a custom meta-annotation






  • Use @Qualifier inside method parameters :

    @Autowired

    public void doStuff(@Qualifier("book") Book book)



What is a proxy object and what are the two different types of proxies Spring can create?

  • Proxies are used to add additional functionality on top of a class by intercepting caller access to this class, without altering class code. Proxies help on applying separation of concerns, e.g. logging, security, etc. Proxies hold same public method as the proxied class, to provide known access points
  • Example in Spring: There is a CGLIB proxy for each @Component singleton bean, to ensure all callers use the same and unique instance.  
  • Disadvantages:
    • Code hard to debug
    • Proxies not serializable
  • JDK Dynamic proxy
    • Proxied must implement an interface
    • Only interface methods can be proxied
    • No support for self invocation
  • CGLIB proxy
    • Proxied does not have to implement an interface
    • Proxied must not be final (CGLIB needs to extend this)


What are the advantages of Java Config? Limitations?
  • Advantages of Java Config versus XML configuration:
    • Compile-time checking vs XML's runtime checking
    • Most IDEs support refactoring adjustments for Java Config, while not for XML config
  • Advantages of Java Config versus Annotation-based configuration:
    • Beans are organized in single @Configuration file (better project organization)
    • Separation of concerns (Beans implementation resides outside the @Configuration + @Beans file)
    • Tech-agnosticism (Beans' implementations is a POJO class, not glued to Spring framework, while e.g. @Component class is Spring-specific)
    • Ability to integrate with 3rd-party libraries (Just have a @Bean method returning some modified library instance)
  • Disadvantages of Java Config:
    • @Configuration file and @Beans must not be Final, because these annotations utilize a CGLIB proxy which demands proxied object to be inheritable. 
      Note: CGLIB proxying is used to ensure that all callers access a single instance of the Bean (@Bean is by default a Singleton) 



What does the @Bean annotation do?
What is the default bean id if you only use @Bean? How can you override this?
  • @Bean is used in @Configuration files to tell Spring container to manage it as a Spring Bean. It also can define a Bean name identifier.
  • Cases of usage:
    • By default, the method name ("springBean3A") is set as bean's name. If @Bean name attribute exists, then "springBean3rd" is set as name.


    • Bean attributes "initMethod" and "destroyMethod"


    • Bean attribute "autowireCandidate" to tell if this bean should be used as dependency to other beans








Why are you not allowed to annotate a final class with @Configuration?
  • @Configuration file and @Beans must not be Final, because these annotations utilize a CGLIB proxy which demands proxied object to be inheritable.
  • Note: CGLIB proxying is used to ensure that all callers access a single instance of the Bean (@Bean is by default a Singleton)  


How do you configure profiles? What are possible use cases where they might be useful?
Can you use @Bean together with @Profile? Can you use @Component together with @Profile?
  • @Profile with @Component



  • @Profile with @Configuration
    (Also, we can have multiple configuration files per profile.
    Then, import all / some config files in main Configuration file : @Configuration @Import({Config1.class, Config2.class , ...}))









  • @Profile with @Bean (in @Configuration file)







  • @Profile included in custom annotation











To activate profiles, there are many ways:

  • Use ConfigurableEnvironment to set active profiles in Runner class










  • VM options: Dspring.profiles.active="profile1,profile2,profile3"

  • Use @ActiveProfiles in test class, to define profile(s) for Test Context to load










  • In Spring Boot, use SpringApplicationBuilder to set profiles:














  • In application.properties, define spring.profiles.active 



How many profiles can you have?
  • setActiveProfiles() accepts varargs, and that being a String array, can hold the maximum value of Integer (Integer.MAX_VALUE)


How do you inject scalar/literal values into Spring beans?
What is @Value used for?
  • Using @Value on field to inject value from properties file, in conjunction with @PropertySource

















  • Using plain primitive types




  • Using spEL language (Below example also uses property reference)



  • Can inject values from other Bean:






  • Can inject values from VM options or environment properties with "$"

  • Can inject whole Map, Sets in field





What is Spring Expression Language (SpEL for short)?
  •  SpEL is an expression language that evaluates the given expression at runtime and the results are injected in a field ready to use

  • It can be used with:

    • ExpressionParser and EvaluationContext
    • On top of constructors, fields, method parameters using @Value
  • SpEL expressions by default are interpreted dynamically at runtime, but we can choose to evaluate them in compile-time for performance reasons:
    • SpelCompilerMode has values Off (no compiler-time evaluation), Immediate (compiler enabled after first interpretation) and Mixed (in case of evaluation exception switches back to runtime, and again to compiler later)

What is the Environment abstraction in Spring?
  • Part of Spring Container that handles Profiles and Properties
  • Can use directly Environment to fetch properties
  • Decided default-activated profile, and active profile set by developer
  • Provides standard ways to resolve properties from configured property sources (property files, JVM, system environment variables, JNDI, servlet config, context params)
  • Standalone application: StandardEnvironment
  • Web application: StandardServletEnvironment (has also servlet configs and context params)


Where can properties in the environment come from – there are many sources for properties – check the documentation if not sure. Spring Boot adds even more.

  • Common sources for Spring Standalone, Spring Web, and Spring Boot apps
    • JVM properties
    • Properties files
    • Enviroment variables
  • Sources for Spring Web app:
    • JNDI
    • ServletConfig init params
    • ServletContext init params

  • Sources for Spring Boot app:
    • @TestPropertySource, @PropertySource
    • @SpringBootTest's property attribute 
    • Command line arguments
    • application.properties file (inside or outside or JAR)

What can you reference using SpEL?







What is the difference between $ and # in @Value expressions?

  • $  => reference a property in Spring Environment Abstraction
  • # => spEL expressions parsed and evalueated by SpEL




Τετάρτη 20 Οκτωβρίου 2021

Spring Certification: Spring Boot Basics

What is Spring Boot?
  • Extension of Spring Framework
  • Build fast production-ready applications, by:
  • providing auto-configurated dependencies
  • starter POMs (easy dependency management)
  • devTools (live code reload)
  • Fit for building apps in microservice architecture


What are the advantages of using Spring Boot?

  • Starter POMs: provide commonly used dependencies with correct versions and transitive dependencies
  • Embedded servlet containers (tomcat, jetty..), no need for WAR, packaging and deploying manually
  • Automatic Configuration: out of the box dependencies, but also configurable
  • Facilitates testing - provides default setup for unit IT tests
  • Solves boilerplate code in Spring projects (no XML)
  • Easily set  development and production profiles
  • Non-functional requirements: Security, Metrics, Externalized configuration and more


Why is it opinionated?
  • Convention over configuration principle is followed, meaning that framework tries to understand what to load, depending on what dependencies the developer has entered
  • Above approach can be edited


What things affect what Spring Boot sets up?
  1. Dependencies are set via starter POMs and/or additional by hand
  2. Spring Boot's autoconfigure module scans what there is on the classpath, and then employs Spring beans to integrate all dependencies (e.g. Spring MVC, Spring Data JPA, etc). This is done with use of @ConditionalOn.. inside AutoConfiguration classes.
  3. Furthermore, developer can set @ConditionalOn.. in his beans


    @ConditionalOn.. classes:

  • ConditionalOnBean - Spring Bean must exist
  • ConditionalOnMissingBean - Spring Bean must not exist
  • ConditionalOnClass - Class must exist
  • ConditionalOnMissingClass - Class must not exist
  • ConditionalOnExpression - spEL expression must result to true
  • ConditionalOnJava - Java JDK in certain version must exist
  • ConditionalOnJndi - JNDI location should exist
  • ConditionalOnProperty - property must exist
  • ConditionalOnResource - resource must exist


What is a Spring Boot starter? Why is it useful?

  • Spring Boot starters are sets of dependency descriptors that define all correct transitive dependencies and versions needed to provide a specific technology to include and use in applications. All official starters follow this pattern: spring-boot-starter-*
  • Developers can focus on business logic, not worrying much about dependency management.
  • Ensures no dependencies are missing and that all have versions that are compatible together.


Spring Boot supports both properties and YML files. Would you recognize and understand them if you saw them?
  • Spring provides option for externalization of configuration by Properties file or YML
  • YML is derived from JSON and is enabled when snakeYAML dependency is present
    • Recognizable from its hierarchical data structure


Can you control logging with Spring Boot? How?
  • Logging library:
    • If spring-boot-starter-web is used, by default Spring uses Commons Logging API, and Apache Logback as reference implementation. To change that, we need to exclude Logback in pom, and include another compatible e.g. Log4J
  • Logging levels:
    • In application properties use logging.level.root=<level> (application-wise).  Use debug=true to enable DEBUG mode globally
    • or com.app.package1=<level> (package-wise)
    • Alternatively, above can apply in a logback-spring.xml file
    • From VM options like: -Dlogging.level.org.springframework=DEBUG

  • Logging output: Use logging.file or logging.path in application properties


Where does Spring Boot look for application.properties file by default?
  1. In /config directory (outside of classpath/jar)
  2. In application directory (outside of classpath/jar)
  3. In /config directory of classpath (in jar)
  4. In classpath root directory (in jar)



How do you define profile specific property files?
  • application-{profile}.yml or application-{profile}.properties
  • If a property is not found in profile-specific file, it loads from the application.properties or application-default.properties (same for yml)



How do you access the properties defined in the property files?
  • In @Configuration class, annotate itself with @PropertySource("app.properties") and then annotate fields with @Value("app.some.property")
  • Alternatively, in Class1 add annotation @ConfigurationProperties(prefix = "app.some"), and then refer to field as "property". Finally, access property value in a second @Configuration class with @EnableConfigurationProperties(Class1.class)
  • @Autowire Spring's Environment, and access property with environment.getProperty("app.some.property")



What properties do you have to define in order to configure external MySQL?
  • spring.datasource.url=jdbc:mysql://<host>:<port>/<databaseName>
  • spring.datasource.username=<username>
  • spring.datasource.password=<password>
  • spring.datasource.driver-class-name=com.mysql.jdbc.Driver


How do you configure default schema and initial data?
  • Configure data.sql and schema.sql in /resources 
  • In properties: spring.datasource.initialization-mode=always
  • If using hibernate, spring.jpa.hibernate.ddl-auto=none
  • Spring loads according to platform set and loads data-{platform}.sql and schema-{platform}.sql. Platform is defined in property spring.datasource.platform=<vendor-platform>, e.g. mysql


What is a fat jar? How is it different from the original jar?
  • An executable jar containing all compiled classes and resources, along with dependencies as nested jars
  • project-1.2.3-SNAPSHOT.jar is the Fat jar, while inside it project-1.2.3-SNAPSHOT.jar.original is the original jar. 
  • To create a Fat jar, spring-boot-maven-plugin is needed to insert original jar in Fat jar. 
  • Fat jar is executable by default with java -jar project-1.2.3-SNAPSHOT.jar, while original is not.


What is the difference between an embedded container and a WAR?
  • Embedded container is used to run a single application's executable jar, and resides in jar itself as a dependency
    • To set up, use maven dependencies spring-boot-starter-web (provides embedded tomcat) and spring-boot-maven-plugin with repackaging goal (to integrate original jar in executable/fat jar)
  • WAR needs to be deployed in an Application Server, where many other war files (applications) can co-exist
    • To set up, use <packaging>war</packaging>, spring-boot-starter-web dependency and spring-boot-starter-tomcat with provided scope

What embedded containers does Spring Boot support?
  • Tomcat 
    • Default with spring-boot-starter-web
  • Jetty
    • First must exclude default Tomcat with <exclusion> tag
    • Set spring-boot-starter-jetty dependency
  • Undetow
    • Same setup logic as Jetty