Core Spring

 

What is dependency injection?

IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies (that is, the other objects they work with) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes or a mechanism such as the Service Locator pattern.

Dependency Injection is a form of Inversion of Control used by containers like Spring to customize beans (the bean – as objects managed by Spring IoC container are called beans) or apply some given implementations on objects whose customizations are defined using interfaces. Techniques used for customizing the beans are constructor and setter injection – in that case, you have to define a constructor that will accept certain implementation for the object field as a parameter.

 

what are the advantages of Dependency Injection?

  • Code is more reusable – DI code becomes more generic and suitable for more implementation.
  • Code is cleaner.
  • Decoupling is more effective – less/or no direct dependencies are used the bean is less prone to be affected by changes in its dependencies.
  • Classes become easier to test – interfaces or abstract classes are used for fields, one can use stubs or mocks implementations to be used while unit testing.

What is pattern?

Design patterns represent the best practices used by experienced software developers. Imagine them as solutions to general problems that software developers face during software development. They are well established and it is very vital for you to learn about them. Why would you reinvent the wheel, when you can just use it?

There is a lot of different design patterns out there.

  • Creational patterns – Singleton, Prototype, Builder…
  • Structural patterns – Proxy, Facade, Decorator…
  • Behavioral patterns – Command, Observer, Template method…

What is an anti-pattern?

An anti-pattern is a common response to a recurring problem that is usually ineffective and risks being highly counterproductive. Imagine it is the opposite of what the pattern means.

Is dependency injection a design pattern?

Yes. Dependency injection is a pattern.

What is an interface and what are the advantages of making use of them in Java?

Interface is very powerful to run time injection of various concrete implementations of an interface in the application. By using references to interfaces instead of their concrete implementation classes help to minimize ripple effects, as the user of interface reference doesn’t have to worry about the changes in the underlying concrete implementation. Interface is an abstract representation of a class. In Spring using an interface for some field in a class allows for automatic substituting with required specific implementation – this will be done by DI.

Why are they recommended for Spring beans?

When Spring beans are implementing interfaces, it is very easy to change the interface implementations. You can simply exchange entire beans by changing the Spring configuration, but you don’t have to make any changes to the code.

What is meant by “application-context?

The ApplicationContext is the central interface of the Spring framework. It provides you with access to your Spring configuration.

How are you going to create a new instance of an ApplicationContext?

ApplicationContext context = new ClassPathXmlApplicationContext("config_file.xml");

What is the concept of a “container” and what is its lifecycle?

Spring container is an “environment” for the beans to live. The container creates, configures and wires beans together. Spring has many container implementations but actually you can divide them in 2 types

  1. BeanFactory – a simple container with basic support for DI
  2. ApplicationContext – a more advanced container that has support for getting values from property files or sending events to different listeners.

When an ApplicationContext is created several things happen:

  1. BeanDefinition creation
  2. Customizing BeanDefinitions by BeanFactoryPostProcessor
  3. Custom FactoryBeans creation
  4. BeanFactory instantiates beans instances
  5. Beans customization by BeanPostProcessor

The ApplicationContext lets you read bean definitions and access them, as the following example shows:

// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);

// use configured instance
List<String> userList = service.getUsernameList();

Scopes for Spring Beans. What is the default?

Configuration metadata allows for defining 7 types of bean scopes. 5 of these scopes are available only if the ApplicaitonContext chosen implementation is web-aware, for example XmlWebApplicationContext or you’ll get an IllegalStateException meaning the selected scope is “unknown”. 

  1. singleton – the default scope for the beans. Will ensure that only one instance of the bean will be created per current IoC container (Spring container). Used for stateless beans.
  2. prototype – any number of bean instances may be created. Used for stateful beans. For this type of beans configured destruction lifecycle callbacks are not called. User must clean up this type of objects and release the resources that they are holding; usually using custom bean post-processor for that.
  3. request – a bean instance will be created per each HTTP request. @RequestScope may be used with @Component to assign this scope.
  4. session – one instance per HTTP Session lifecycle. @SessionScope may be used with @Component to assign this scope.
  5. globalSession – one instance per HTTP global Session. Usually only valid when used in a Portlet context
  6. application – one instance per ServletContext. @ApplicationScope may be used with @Component to assign this scope.
  7. websocket – one instance per WebSocket

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

Spring Bean Life Cycle

Spring bean factory is responsible for managing the life cycle of beans created through spring container. The life cycle of beans consist of call back methods which can be categorized broadly in two groups: Post initialization call back methods and Pre destruction call back methods

Destroy method is the method that is called when the container containing it is destroyed (closed)

Initialization method is a method that does some initialization work after all the properties of the bean were set by the container.

Image result for bean lifecycle in spring

How are you going to create an ApplicationContext in an integration test?

It is possible to create ApplicationContext with @ContextConfiguration or @WebApplicationContext annotation.

@RunWith(SpringRunner.class)
// ApplicationContext will be loaded from AppConfig and TestConfig
@ContextConfiguration(classes = {AppConfig.class, TestConfig.class}) 
public class MyTest {
    // class body...
}

 

What is the preferred way to close an application context? Does Spring Boot do this for you?

There is no need to register a shutdown hook in a web application. Spring web-based ApplicationContext implementations already have shutdown code in place.

In a non-web application, you should register a shutdown hook with the JVM. This hook will ensure, that ApplicationContext will be closed gracefully and it calls the relevant destroy methods on singleton beans (remember, that destroy callbacks are not called on prototype-scoped beans). You can register shutdown hook via ConfigurableApplicationContext. If you are using Spring Boot, then it will register this hook automatically for you.

public class Application {
 
    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = 
            new ClassPathXmlApplicationContext("beans.xml");
 
        // add a shutdown hook for the above context...
        context.registerShutdownHook();
 
        // app runs here...
 
        // main method exits, hook is called prior to the app shutting down...
    }
}

What is an initialization method and how is it used in Spring?

Initialization method is a method that does some initialization work after all the properties of the bean were set by the container. It can be done in different ways:

  • using XML init-method attribute for <bean>
  • using initMethod attribute of @Bean
  • using @PostConstruct annotation
  • implementing InitializingBean and overriding afterPropertiesSet method
  • in case there is a default-init-method attribute set for <beans> and the bean has a method whose name matches that attribute – it will be the initialization method, although this can be overridden using init-method in a specific <bean>  

can you describe dependency injection using Java configuration?

Spring IoC container manages objects or beans. To configure and manage beans you need configuration metadata. One of the ways to create configuration metadata is by using java code. You can use @Configuration to annotate a class whose purpose is to create beans.

The @Bean annotation informs Spring container, that the method will instantiate and configure a new object to be managed by the container.

@Configuration
public class AppConfig {
 
    @Bean
    public UserService userService() {
        return new UserService();
    }

    @Bean
    public UserService userService(UserRepository userRepository) {
        // userRepository will be automatically resolved by the Spring container
        // it can be used for constructing UserService bean
        return new UserService(userRepository);
    }
}

Note here that the bean’s name will be the same as the method name.

@Autowired
private UserService userService;

If you want a different name you can change the name of the bean like this.

@Bean(name="userBean")
public UserService userService() {
    return new UserService();
}

...
@Autowired
private UserService userBean;

or you can do this.

@Bean
public UserService userService() {
    return new UserService();
}

...
@Autowired
@Qualifier("userService")// the name of the bean
private UserService userBean;

or 

@Resource(name="userService")// the name of the bean
private UserService userBean;

can you describe dependency injection using annotations (@Component, @Autowired)?

@Component annotation is used to mark a class as a Bean. You use @Component together with @ComponentScan which scans classes within a package and provides metadata for the IoC container to create beans. @Component will set the bean name derived from the class name, but if you need to set the name explicitly you just need to supply it in the brackets like @Component(“beanName”).

@Configuration
@ComponentScan(basePackages= {"bean.package"})
class AppConfig {

}

or 

@Configuration
@ComponentScan(basePackageClasses={UserService.class}) 
class AppConfig {

}

@Autowired is used to provide a reference of a bean to be used. Instead of an explicit definition of a bean dependency, it is possible to ask Spring to provide dependencies automatically. This is called auto wiring. @Autowired can be used at constructors, methods, and fields.

For auto wiring Spring does this:

  • Spring tries to resolve candidates by the type first.
  • If multiple candidates exist, Spring tries to resolve the dependency by its name
  • If multiple candidates are found, and Spring cannot decide which should be used, an exception is thrown
  • If no candidates are found, an exception is thrown
  • It is possible to auto-wire beans collection of the given type
  • If ambiguity exists, we can specify autowire candidate by the @Qualifier or @Primary annotation
  • It is possible to use Java 8 Optional for optional dependencies
@RestController
public class UserController {
	@Autowired
	private UserService userService;

        
}

Spring allows for using @Named and @ManagedBean instead of @Component. Spring also allows you to use @Inject and @Resource instead of @Autowired.

can you describe component scanning, Stereotypes, and Meta-Annotations?

Spring allows marking your class as a bean ready for component-scanning using the following annotations:

  1. @Component – most generic stereotype annotation. Other annotations are specializations of the @Component annotation. Use it, when more specific annotation does not fit for your purpose.
  2. @Service – marks a class as a member of the service layer.
  3. @Repository – for beans that represent a DAO. It marks a class as a member of the repository layer. All exception thrown from this class will be wrapped and translated to the Springs
  4. @Controller – marks a class as an annotated controller. Methods of such class will be used for handling of the incoming http requests.

You can use in all the above cases the @Component annotation but using a specific annotation may be a better idea due to automatic translation of exceptions (in @Repository case) and future possible meanings in Spring.

Spring can automatically detect your stereotype classes and instantiate beans defined inside those classes. To allow autodetection, it is needed to add the @ComponentScan annotation on your @Configuration class.

By default, components will be searched from the package, where @ComponentScan annotation is defined. If you want to scan for the components from other packages, you can define base package with @ComponentScan(“com.springcertified”)

It is possible to create composed annotations by joining several annotations together. Such meta-annotations can simplify your code and make it more readable. As an example, here is definition of the @RequestScope annotation. As you can see, it is based on the more generic @Scope annotation:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Scope(WebApplicationContext.SCOPE_REQUEST)
public @interface RequestScope {
 
	/**
	 * Alias for {@link Scope#proxyMode}.
	 * <p>Defaults to {@link ScopedProxyMode#TARGET_CLASS}.
	 */
	@AliasFor(annotation = Scope.class)
	ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
 
}

can you describe scopes for Spring beans? What is the default scope?

The scope is like a prescript, which defines the way how the bean instances are created from the bean definitions. With the Java-based configuration, it’s possible to set the bean scope with the following annotation on the bean method:

@Scope("prototype")
@Bean
public UserService userService() {
    return new UserService();
}

Basic Scopes

  1. singleton – the default scope for the beans. Will ensure that only one instance of the bean will be created per current IoC container (Spring container). Used for stateless beans.
  2. prototype – any number of bean instances may be created. Used for stateful beans. For this type of beans configured destruction lifecycle callbacks are not called. User must clean up this type of objects and release the resources that they are holding; usually using custom bean post-processor for that.

Additional beans for web application

  1. request – a bean instance will be created per each HTTP request. @RequestScope may be used with @Component to assign this scope.
  2. session – one instance per HTTP Session lifecycle. @SessionScope may be used with @Component to assign this scope.
  3. globalSession – one instance per HTTP global Session. Usually only valid when used in a Portlet context
  4. application – one instance per ServletContext. @ApplicationScope may be used with @Component to assign this scope.
  5. websocket – one instance per WebSocket

Are beans lazily or eagerly instantiated by default? How do you alter this behavior?

Beans are eagerly instantiated by default. This way, Spring is able to recognize issues in the configuration very early – usually during application startup. If you want to instantiate bean lazily, you can change it with the proper configuration.

@Bean
@Lazy
public UserService userService() { 
    return new UserService();
}

If you want to have all beans initialized in lazy fashion, you don’t have to specify lazy initialization for the every bean. You can alter the behavior by the configuration of the lazy initialization for all beans.

@Configuration
@ComponentScan(lazyInit = true) 
class AppConfig {
    @Bean
    public UserService userService() { 
        return new UserService();
    }
}

If you have a lazy bean instantiated within a non-lazy bean than that lazy bean will be an eager instantiated bean.

What is a property source? How would you use @PropertySource?

Property source is a set of properties. Properties are usually added to the application in the form of the standard Java property files. Spring application usually has multiple property sources registered. Some of them are registered by default, but usually every application adds own property source.

server.port=9090

# devtools
spring.devtools.livereload.enabled=true
spring.devtools.restart.enabled=true

To access a property value you need to use the property key. For example to get the server.port. Spring will search property sources hierarchically and returns the desired property value for server.port.

@Value("${server.port}")
private int portNumber;

Property sources are searched in the following order:

  1. ServletConfig parameters (if applicable — for example, in case of a DispatcherServlet context)
  2. ServletContext parameters (web.xml context-param entries)
  3. JNDI environment variables (java:comp/env/ entries)
  4. JVM system properties (-D command-line arguments)
  5. JVM system environment (operating system environment variables)
  6. You can also add your own property file using @PropertySource.
@Configuration
@PropertySource("classpath:app.properties")
public class AppConfig {
 
    @Autowired
    Environment env;
 
    @Bean
    public UserService userService() {
        UserService userService = new UserService();
        userService.setPort(env.getProperty("server.port"));
        return userService;
    }
}

 

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

BeanFactoryPostProcessor is an interface that allows for defining customizing BeanDefinitions for future beans before those beans are created. The BeanFactoryPostProcessor is a special kind of object registered in ApplicationContext . Its main purpose is to alter BeanFactory before the beans are instantiated. That means, that BeanFactoryPostProcessor operates on raw bean definitions, not on the bean instances.

Why would you define a static @Bean method?

To ensure, that it will be ready in such an early stage, you should register it via static bean method. The static method declaration will avoid the requirement to have the declaring class to be instantiated. When defining a method that returns a bean of BeanFactoryPostProcessor type it is best to declare it as static because of the fact that this type of beans requires very early initialization and thus the must not be affected by @Autowire, @PostConstruct and @Value annotations from a @Configuration annotated class.

What is a ProperySourcesPlaceholderConfigurer used for?

The PropertySourcesPlaceholderConfigurer is Springs internal implementation of the BeanFactoryPostProcessor . Its main purpose is to resolve ${…} placeholders within bean definition property values and @Value annotations with appropriate values loaded from the property sources.

public class UserService {
    private int concurentUsers;
 
    @Value("${app.configuration.concurent.users}")
    public void setConcurentUsers(int concurentUsers) {
	    this.concurentUsers = concurentUsers;
    }
}

The PropertySourcesPlaceholderConfigurer iterates over all bean definitions before they are created. When property defined via ${…} is found, it is replaced by the appropriate value from the property sources. When no such property is found, an exception is thrown. This bean is used for defining the location of the properties file to be used in assigning values to bean properties. But it also allows for searching the required value in the system and/or environment variables.

 

What is a BeanPostProcessor and how is it different to a BeanFactoryPostProcessor? What do they do? When are they called?

 

What is an initialization method and how is it declared on a Spring bean?

Initialization method is a special method, which is called by the ApplicationContext during the bean initialization phase. Consider the following class. It contains a method named doInitialization , which performs custom steps we want to execute when the bean is initialized

@Bean(initMethod = "doInitialization")
public void userService() {
    return new UserService();
}


...

public UserService {
 
	public UserService() {
        // normal constructor
	}
 
    public void doInitialization() { 
        //... perform some init steps 
    }
}

What is a destroy method, how is it declared and when is it called?

If you want to execute some cleanup code when the bean is destroyed, you can configure the so-called destroy method. Consider following class containing doCleanup method.

@Bean(destroyMethod = "doCleanup")
public void userService() {
    return new UserService();
}


...

public UserService {
 
    public UserService() {
        // normal constructor
    }
        
    public void doCleanup() { 
        //... perform some cleanup steps 
    }
}

Note that destroy callbacks are never called on Prototype scoped beans.

Consider how you enable JSR-250 annotations like @PostConstruct and @PreDestroy? When/how will they get called?

It is possible to define initialization and destroy callbacks by using @PostConstruct and @PreDestroy annotations. Those annotations are not part of the Spring framework, but they are defined directly in Java language as part of JSR-250 specification request.

Spring recognizes those annotations with the help of the CommonAnnotationBeanPostProcessor . The purpose of this bean post processor is to find bean methods annotated with @PostConstruct and @PreDestroy annotations, and register desired callbacks within ApplicationContext.

The CommonAnnotationBeanPostProcessor will be registered automatically when component scan is turned on, or it can be added to the bean configuration manually if component scan is not used. Usage of the annotations is then pretty straightforward.

public class UserService {
 
    public UserService() {}
 
    @PostConstruct
    protected void initialize() {
        // initialization code
    }
 
    @PreDestroy
    protected void destroy() {
        // destroy code
    }
}

How else can you define an initialization or destruction method for a Spring bean?

Register initialization and destroy callbacks is to implement InitializingBean and DisposableBean interfaces.

The InitializingBean interface contains a single method named afterPropertiesSet() .

public class UserService implements InitializingBean {
 
    public UserService() {
 
    @Override
    public void afterPropertiesSet() throws Exception {
        // initialization code
    }
}

The DisposableBean interface contains a single method named destroy(). Remember, that destroy callbacks are not triggered on the prototype-scoped beans.

public class UserService implements DisposableBean {
 
    public UserService() { }
 
    @Override
    public void destroy() throws Exception {
        // destroy code        
    }
}

What does component scanning do?

Component scanning scans a package or a set of packages for classes that are annotated with @Component, @Controller, @Service and @Repository and configure those classes as beans. These beans will be added automatically to the ApplicationContext without you, the developer, having to declare them explicitly using @Bean in a @Configuration or in an XML configuration metadata file. By using @ComponentScan you are scanning the package that corresponds to the package of the current @Configuration. In case you need to specify a custom package or more packages you have to use:

// scan package where this class is in
@Configuration
@ComponentScan
public class AppConfig {
}

// scan com.foo and com.boo packages
@Configuration
@ComponentScan(basePackages={"com.foo","com.boo"})
public class AppConfig {
}

// scan UserServiceImp.class and PaymentMethodServiceImp.class classes
@ComponentScan(basePackageClasses={UserServiceImp.class, PaymentMethodServiceImp.class})
public class AppConfig {
}

What is the behavior of the annotation @Autowired with regards to field injection, constructor injection and method injection?

@Autowired tries to find a matching bean by type and inject it at the place on annotation – that may be a constructor, a method (not only setter, but usually setter) and field.

In case no bean is found an exception will be thrown; to skip this you can set the required attribute of @Autowired to false, and in that case you have to pay attention to possible null values related exceptions.

In case of ambiguity there are 2 approaches:

  1. @Primary annotation to identify a “preferable” bean among different implementations of an interface
  2. @Qualifier annotation to indicate directly the preferred bean.

What do you have to do, if you would like to inject something into a private field? How does this impact testing?

It does not matter because Spring uses reflection or setter methods to assign values to beans. So it does not matter whether you use private or public fields.

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

@Autowiring + @Qualifier combination is used to identify or inject a bean by name. This combination can be used but it is better to use @Resource when trying to inject by name.

@Component("staff") 
public Staff implements Person {}

@Component("employee") 
public Manager implements Person {}


@Component
public PayrollService {

   @Autowired
   @Qualifier("employee") 
   private final Person person;
}

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

Proxy objects are objects that replace beans that should be injected in a singleton bean but are themselves lazily instantiable. For example in a singleton bean, you have a dependency on a session scoped bean. In this case at the container startup, Spring will instantiate the singleton bean and during this process, it will already need the bean that is session scoped. So here we have a problem. So we can benefit from a proxy object that will mimic the bean that we actually need. But here comes another problem. Our dependency may be defined as an interface or as a class. So for each case one of the two types of proxies will be created:

  1. Interface proxy(created by Spring itself)
  2. Class proxy(generated by CGLib)

Interface proxy is created by Spring itself while class proxy is generated by CGLib. 

@Component
@Scope(proxyMode = ScopedProxyMode.INTERFACES, scopeName = "session")
public class UserServiceImp implements UserService{
}

 


○ What are the limitations of these proxies (per type)?

Limitation of Interface type
– Proxied class must implement interfaces

Limitation of Class type
– Proxied class must provide a default constructor
– Final methods won’t allow for using CGLib proxying
– Resulting proxy is final (you cannot proxy a proxy)

○ What is the power of a proxy object and where are the disadvantages?

 

What are the advantages of Java Config? What are the limitations?

Biggest advantage of JavaConfig is type safety or compile-time check. Another advantage is the possibility to use someone other’s classes. The limitation is that you cannot change the configuration dynamically – you have to rebuild the project.

Search is much simpler, refactoring will be bliss. Finding a bean definition will be far easier.

XML based on configuration can quickly grow big. Yes, we can split and import but still.

What does the @Bean annotation do?

@Bean annotation is used on methods that will return beans as return types. It is used to indicate that a method produces a bean to be managed by the Spring container. Typically @Bean is used in configuration classes. Bean methods may reference other @Bean methods in the same class by calling them directly.

 @Configuration
 public class AppConfig {

     @Bean
     public FooService fooService() {
         return new FooService(fooRepository());
     }

     @Bean
     public FooRepository fooRepository() {
         return new JdbcFooRepository();
     }
 }

 

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

In a configuration class, the name of the bean in case you use @Bean on a method will instantiate a bean with the name matching the method name.

You can override this by using the name attribute of the @Bean annotation to name your bean to a name.

@Bean(name="memberService")
public UserService userService() {
   return new UserServiceImp();
}

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

Spring requires for subclassing classes(Spring creates dynamic proxies) annotated with @Configuration (for example to check if a bean exists before calling for its creation). But a final class cannot be extended so you cannot make a proxy of a final class.

○ How do @Configuration annotated classes support singleton beans?

 

○ Why can’t @Bean methods be final either?

because bean methods must be proxied and final methods can be extended.

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

You use @Profile to configure beans to behave according to a particular environment. Like for example you might want to use certain endpoints in dev to short cut testing but in prod you cannot have those endpoints.

Can you use @Bean together with @Profile?

Yes you can. @Profile can be used on a configuration class or bean method.

@Configuration
@Profile("dev")
public class AppConfig {

}
....

@Profile("dev")
@Bean
public FooService fooService() {
    return new FooService(fooRepository());
}

Can you use @Component together with @Profile?

Yes you can.

@Profile("dev")
@Component
public class UserServiceImp implements UserService {

}

How many profiles can you have?

Multiple profiles can be activated at once.

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

Depending on the beans wiring style you can use different methods to inject scalar/literal values:

  • for Java-based configurations: use @Value annotation at constructor arguments, over properties and at setter methods
  • for XML-based configurations: c-namespace for constructors and p-namespace for properties
@Component
public class SomeBean{

    @Value("Some title") //at property 
    private String title;

    private String author;
    @Value("Hemingway")
    public setAuthor(String authorName){
        this.author = authorName;
    }

    private int price;
    public SomeBean(@Value("14")int newprice){ // ! int value is set 
     with quotes ! 
         this.price = newPrice;}
    }
}

What is @Value used for?

This annotation is used for assigning some value to a bean field. It can be used at different levels

  • constructor
  • setter
  • field

It is not accessible in a BeanFactoryPostProcessor and BeanPostProcessor by the time it is applied using a BeanPostProcessor.

What is Spring Expression Language (SpEL for short)?

SpEL is an expression language that allows you to query and manipulate an object graph at runtime.

@Component
public class UserService{

    @Value("#{account.name}")
    private String name;

}

... 

@Bean
public Account account() {
    return new Account("John","john@gmail.com");
}

What is the Environment abstraction in Spring?

Environment interface represents Spring abstraction for the environment. It deals with 2 aspects of a Spring application:

  1. profiles and
  2. properties from different sources (properties files, system and JVM properties etc.)

For a bean to interact with environment you can either make it EnvironmentAware or autowire the Environment.

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.

 

What can you reference using SpEL?

SpEL can reference beans, system variables, system properties.

@Bean
public PaymentMethod paymentMethod() {
	PaymentMethod paymentMethod = new PaymentMethod();
	paymentMethod.setName("Visa");
	return paymentMethod;
}

...

@Value("#{paymentMethod.name}")
private String name;// Visa

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

$ is used for placeholders from property files or system property files

# is used for SpEL

@Value("${springboot.profile}") //will populate field with value from properties file
private String profile;

@Value("#{userService.name}") // will populate field with value from otherBean bean someBeanField field
private String name;

 




Subscribe To Our Newsletter
You will receive our latest post and tutorial.
Thank you for subscribing!

required
required


Leave a Reply

Your email address will not be published. Required fields are marked *