Spring Fundamentals (A shallow dive)
Tags: Spring Boot, Software Development, Spring Framework, Spring, Java

Hello! This article is on spring fundamentals. If you have been hearing about the spring framework and you don’t know what it is, then this article is for you.

The Problem

To understand the solution which is spring in this case, we must look at the problem to know what was wrong and exactly what the solution fixes.

Developing Java enterprise apps was in a weird place once upon a time and it made code hard to test, maintain and scale. There was a lot of complexity and codes didn’t focus on the business logic but more on the configuration.

The Solution

Spring came out as a way to easily do things in Java Development. It enabled programmers to easily configure applications through the use of annotations or XML based configurations. It’s original concept was to provide an alternative to EJB but it has grown a lot more than that.

This enabled developers to focus on the important code or business logic which increased productivity.

How it works

Spring can be simply thought of as a registry where our POJO’s are stored. It can be visualized as storing our beans inside a container and then making these beans available for access in our apps easily

Ways to configure Spring beans

XML configuration

This approach is often seen as simpler to some. It separates concerns because the configuration is done in a separate xml file usually called applicationContext.xml ( optional naming convention) and usually looks like the xml below.



<beans xmlns="

xmlns:xsi="

xsi:schemaLocation="

http://www.springframework.org/schema/beans xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "> <bean name="userRepository"

class="com.robinson.repository.HibernateUserRepositoryImpl" /> <bean name="userService"

class="com.robinson.service.UserServiceImpl" autowire="byType" /> // Setter Injection by xml

<property="userRepository" ref ="userRepository" /> // Constructor Injection by xml

<constructor-arg index="0" ref="userRepository" /> </bean>

Above you can see that it contains an xml namespace and bean declarations, but what are beans?

Beans are just essentially POJOs in apps, using beans here replaces calling the new keyword. Using the xml file in our Application class should be done like this

ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");



UserService service = appContext.getBean("userService", UserService.class);

How do we use these beans?

We can use these beans we have defined here in other places by using constructor injection and setter injection.

Constructor injection and setter injection are as you must have guessed, it involves using the constructor and setter methods to get bean value. I am not going to talk much about them. I will talk about Autowiring later.

Annotation Configuration Using XML

This is another way similar to what we did earlier but here we use annotations and add a component scanner in our XML.

Here we can see we add the context namespace, annotation config and component scanner to look in the com.robinson package.

We use stereotype annotations to mark the classes we want and @Autowired to set it up. I will talk about the stereotype annotations later

Java Configuration

This is the last and by far the best way to configure spring applications. It is preferred because you do not have to use any xml for your configurations and everything is done in the Java file.

@Configuration

@ComponentScan({“com.robinson"})

public class AppConfig {

public UserService getUserService() {

UserServiceImpl userService = new UserServiceImpl();

userService.setUserRepository(getUserRepository());

return userService;

} @Bean (name="userService")public UserService getUserService() {UserServiceImpl userService = new UserServiceImpl();userService.setUserRepository(getUserRepository());return userService;

public UserRepository getUserRepository() {

return new HibernateUserRepositoryImpl();

}

} @Bean (name = "userRepository")public UserRepository getUserRepository() {return new HibernateUserRepositoryImpl();

applicationContext.xml is replaced by @Configuration as a class level annotation. We can choose to use constructor, setter or property injection. We can also optionally remove bean declarations here and use stereotypes to declare them like in the previous section.



public class HibernateUserRepositoryImpl implements UserRepository{} @Repository ("userRepository")public class HibernateUserRepositoryImpl implements UserRepository{}

Stereotype annotations

These are annotations that help define beans in applications. The main ones are @Component, @Service, @Repository. They are semantically the same

@Component is usually used with any POJO. @Service is used in business logic layer and not web service. @Repository is used in the data layer.

Using stereotype annotation in our repository would look something like this



public class HibernateUserRepositoryImpl implements UserRepository{} @Repository ("userRepository")public class HibernateUserRepositoryImpl implements UserRepository{}

Autowire

There are four options when it comes to auto wiring. Spring wires beans byType, byName, constructor or no.

ByName simply means that the bean will be gotten by it’s defined name , byType means that it would be gotten via it’s type or class, constructor is self explanatory and means that it will be autowired to the constructor. no is the last choice which asks spring not to autowire anything for us

Bean Scopes

Beans generally have 5 Scopes. Two which are valid in any configuration and includes Singleton and Prototype. The other 3 are valid only in web-aware Spring projects and include Request, Session and Global. Scopes here are somewhat similar to design patterns we already know.

Singleton is the default scope and is use when no scope is defined. Like the design pattern, it creates an instance of the bean if it has not been created before and caches it for reuse.

Prototype scope forces or guarantees a new unique instance of the bean to be created whenever the bean is needed from the container and is the total opposite of the singleton scope.

Request generates a new bean per HTTP request, Session generates and uses the same been throughout the users session and Global will return a single bean per application and will be shared throughout the application.

Adding a scope to the app should look like this



("singleton")

public class UserServiceImpl implements UserService {} @Service ("userService") @Scope ("singleton")public class UserServiceImpl implements UserService {}

Properties

This is a great way to abstract out important information that cannot be hard-coded in the app. Can be done with xml like this

<context:property-placeholder location="app.properties" /> <bean name="userRepository"

class="com. robinson .repository.HibernateUserRepositoryImpl">

<property name="dbUsername" value="${dbUsername}"/>

</bean>

can be configure in Java like this



@ComponentScan({"com.robinson"})

@PropertySource @Configuration ("app.properties")@ComponentScan({"com.robinson"}) @Bean

public static PropertySourcesPlaceholderConfigurer

getPropertySourcesPlaceholderConfigurer() { public static PropertySourcesPlaceholderConfigurergetPropertySourcesPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer();

}

value is used like this in code



private String dbUsername; @Value ("${dbUsername}")private String dbUsername;

Note: To do certain things with spring you need to add it’s dependencies to your code and I recommend spring boot because of it’s ease. Thanks for reading and as usual, leave alike only if it was helpful 😃