Sunday, December 5, 2021

Spring Professional Certificate Study Guide Section 1-1, Question 16-28

16. What does the @Bean annotation do?

17. What is the default bean id if you only use @Bean? How can you override this?

18. Why are you not allowed to annotate a final class with @Configuration

19. How do you configure profiles? What are possible use cases where they might be useful?

20. Can you use @Bean together with @Profile?

21. Can you use @Component together with @Profile?

22. How many profiles can you have?

23. How do you inject scalar/literal values into Spring beans?

24. What is Spring Expression Language (SpEL for short)?

25. What is the Environment abstraction in Spring?

26. 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.

27. What can you reference using SpEL?

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


  • 16. What does the @Bean annotation do?
      @Bean  
      public List<Student> studentList(){  
           return Arrays.asList(new Student("Jack", new Baseball()), new Student("Joe", new Baseball()), new Student("Jason", new Baseball()));  
      }  
        Read also Question 5 and 8 from Section 1-1.
       @Bean is used inside the @Configuration or @Component class. The method annotated by @Bean would return a Bean that will be managed by Spring container.
We can specify name, initMethod, destroyMethod, autowiring, name...

  • 17. What is the default bean id if you only use @Bean? How can you override this?
The class AnnotationBeanNameGenerator is in charge of creating the bean id. By default, Bean id will be the short name of the class/method (With first letter lowercased). We can override this behavior by specifying a Bean name: Bean name must be unique within the container that hosts the bean.
 
 @Bean(name={"name", "alias1", "alias2"}, initMethod= "init")  
 @Scope("prototype")
 @Description("Provides a basic example of a bean")
 public MyBean getABean(){  
...
 }  

 @Bean
 public MyBean2 getAnotherBean(){
    return new MyBean2(getABean());    //Injecting Inter-bean Dependencies
 }

  • 18. Why are you not allowed to annotate a final class with @Configuration
Please also read Section 1.1 Question 15.
Spring creates dynamic proxies for classes annotated with @Configuration classes. Spring uses CGLIB to extend your class to create proxy. Therefore, configuration classes cannot be final. Keep in mind that CGLIB proxying works with inheritance, so final/private methods/classes won't work with AOP.
If a @Configuration class is final, Spring will throw BeanDefinitionParsingException.

§ Proxying enables singleton Beans. Method calls would be intercepted by the proxy, and if the requested Bean is already instantiated, then it would be returned. (singleton)

  • 19. How do you configure profiles? What are possible use cases where they might be useful?
Spring Profile: A feature that enables us to map beans to different profiles (example, dev, test, prod...), so we can activate only part of the bean set that we need. Read also Section 1.1 Question 9.
 @Component  
 @Profile("dev", "database")  //multiple profiles possible
 public class DevelopmentConfig 
 
 @Configuration  
 @Profile("!production")  //can be combined with "!" (not)
 public class NotForProductionConfig  {
   @Bean
   @Profile
   public MyBean getBean(){...}
 }


then to active a specific profile, you just write: (in xml)
 spring.profiles.active=dev, production, <profilesToActive>, ...
alternatively (java-only configuration)
context.getEnvironment().setActiveProfiles("dev");

  • 20. Can you use @Bean together with @Profile?
Yes. Read Question 19. @Profile on @Bean annotated methods in @Configuration.
If no profiles specified, then the bean is active in all profiles.

  • 21. Can you use @Component together with @Profile?
Yes. 

  • 22. How many profiles can you have?
This is not explicitly defined in Spring official documents. However, some relevant classes, such as ActiveProfilesUtils use arrays to iterate over profiles, so the upper limit of profiles should equal to number of elements you can have in an array. (Integer.MAX_VALUE = 2^31-1) Note that this MAX_VALUE is regardless of the JVM bits (32 or 64-bit machine) we are using. 
 
  • 23. How do you inject scalar/literal values into Spring beans?
 @Value(<value>). It can be used on 
 1. fields
 2. constructor parameter
 3. method 
 4. method parameter
 5. annotation type

<value> can be:
 1. simple values: "Hello", "true", 
 2. Property reference: "${myProperty.property1}"
 3. inject into array, list, map, set
 4. SpEL inline computation
 
public class UmsMemberController {  
   @Value("${jwt.tokenHeader}")  
   private String tokenHeader;  

For example, specify in our property file:
valuesMap={key1: '1', key2: '2', key3: '3'}
Then we can inject this property using @Value
@Value("#{${valuesMap}}") 
private Map<String, Integer> valuesMap; 
  • 24. What is Spring Expression Language (SpEL for short)?
 Read also Question 23:
 An example combined with @Value annotation would be:
@Value("#{'helloworld'.toUpperCase()}")


  • 25. What is the Environment abstraction in Spring?
Read also Section 1.1 Question 9. 

Default PropertySources for standalone applications are configured in class StandardEnvironment. For Spring running under Servlet Environment, class StandardServletEnvironment is used.

§ StandardEnvironment configures two additional property sources in following order:
1. system properties -> system environment variables (This means if a property named "abc" is present in both property files, then the value defined in system properties is preferred.)

§ StandardServletEnvironment : includes additionally servlet config and servlet context parameters

  • 26. 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.
Read also Section 1.1 Question 9.

Properties can be specified inside:

a. @PropertySource or @PropertySources
@Configuration
@PropertySources({
   @PropertySource("classpath:foo.properties"),
   @PropertySource("classpath:bar.properties")
})

b. @Value injection 
@Value("${host.mall.admin}")
c. src/main/resources/application.properties file (Spring Boot)

d. @TestPropertySource (Spring Boot)

e. JVM System Properties

f. System Environment Variables

It depends on type of applications you are using:
  1. Standalone Application: 
  2. Servlet Application:
  3. Spring Boot Application:

Common Application Properties: 
https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html

  • 27. What can you reference using SpEL?
Read also Section 1.1 Question 24
Following can be used as SpEL:
  • public static fields/methods from class: 
public class App { 
  public static String MY_NAME = " XXXX";
  public static getMyname(){...}
  
MY_NAME can be referenced using SpEL :
  #{T(xxx.yyy.App).MY_NAME}
  #{T(xxx.yyy.App).getMyname()}
  • Spring Bean Property/method
#{@beanName.propertyName}
#{@beanName.getProperty()}
  • SpEL Variables:
#{#spelVariableName}
    • Spring Environment Properties:
    #{environment['app.file.property']}
        • System Properties:
        #{systemProperties['app.vm.property']}
              • System Environment Properties
              #{systemEnvironment['JAVA_HOME']}

                      • 28. What is the difference between $ and # in @Value expressions?
                      @Value supports two syntaxes:
                      $: referencing a property in Spring Environment Abstraction
                      #: SpEL expressions (Read Section1.1 Question 27)

                      No comments:

                      Post a Comment