Spring is a Java framework that facilitates for many needs and links to Spring are already posted in other answers, so I will not repost them here. Good tutorial here. Among other things it removes the need for you to take care and create dependencies for everything in your classes, It does this using using IoC (Inversion of Control). You create the rules and the container will then facilitate your needs by taking care of dependencies and creating objects when needed. These container managed objects are called Beans. This removes the need for using 'new' and figuring our where to get the instance of an object in you own class. So DataSource db = new DataSource("all the parameters you need. What if this is production env?!?") becomes essentially DataSource db = context.getBean(MySpecializedDataSource.class); and Spring decides according to your configuration and properties what instance to get for you.
Lets say you are creating a servlet that responds to HTTP requests and gets data from a database. Normally you would do everything by hand and extend HttpServlet and implement your logic in doGet()
and doPost()
. Then you would create a jdbc connection and get the data you need. Then you print out HTML maybe with something like response.getWriter().println("<html>Hello "+user.toString()+"</html>");
In Spring (and Spring Boot) you can get all this by using Annotations and Beans, without writing it all by yourself. This makes creating software and features a lot faster and without errors and implementation differences in every servlet.
I will continue the example with Spring Boot, because it makes things even more simple but we are still talking about Spring essentially.
In Spring Boot you would declare your servlet with Annotation to add functionality to it and also to tell Spring the rules you want to use for configuration. I would use
@Controller //This means it is also a Bean and I want Spring container to create, manage and destroy these objects. Just create one when I need like when a HTTP request arrives to mysite.com/
public class NameController
{
@Autowired //This is a Bean. It's configuration rules are somewhere in ApplicationContext. Spring go find them and get me an/the instance
private UserService userService;
@Autowired // I need access to the HTTP request. Go get it for me.
private HttpServletRequest request;
String fullName = userService.findUserById(reguest.getParameter("id")); //fullName is not a Bean
@Value("${myStrings.const1}") //not a Bean by itself, but a PropertyPlaceHolder bean will go and get this value from somewhere for me
private String someString;
@GetMapping("/") //No need to define HTTP handlers by hand or write doGet().
public String index() {
return "<html>Greetings from Spring Boot! "+fullName+" "+someString+" </html>";
}
}
//UserService would then define a Datasource and what to query
@Component // This is also a bean. Create and manage when needed
public class UserService {
private DataSource dataSource; //no need for initialization like 'new'
public UserService(@Autowired DataSource dataSource) { // Use the DataSource I defined in my Bean configuration in MyApplicationContextConfiguration (or where ever you find a configuration in the ApplicationContext)
this.dataSource = dataSource;
}
public String findById(Integer id) {
try (Connection connection = dataSource.getConnection()) {
PreparedStatement selectStatement = connection.prepareStatement("select * from users where id = ?");
// TODO execute query. Maybe wrap inside @Transactional to get DB commits if it is an update etc
}
}
}
/*
Then you would define the rules that the container follows when it creates and manages these Beans. You have to declare it somewhere right?
You would then create the Bean definitions somewhere like in ApplicationContextConfiguration that you would use to create your ApplicationContext (the container).
You could add configurations with XML or by any means that Spring provides.
/*
package com.my.examples;
@Configuration //This defines the Beans as a ApplicationContextConfiguration
@ComponentScan // please Spring go through all packages under com.my.examples and find anything that looks like a bean and create them if needed
public class MyApplicationContextConfiguration {
@Bean //this is a Bean and it is used inside my Components, Controllers etc. Create and manage it when needed
@Scope("singleton") //I want to be absolutely sure, that there is only one instance present in the container. Just an example. You might want several of these on a busy server
public DataSource dataSource() {
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setUser("root"); //you can move this outside your project to properties files later on, so it stays out of Git and can easily be change per environment
dataSource.setPassword("s3cr3t");
dataSource.setURL("jdbc:mysql://localhost:3306/myDatabase");
return dataSource;
}
/* no need for this anymore! It is being created by the @Component annotation
@Bean
public UserService userService() {
return new UserService(dataSource());
}
*/
}
/*
Then later on you can change this @Bean configuration so, that it does not contain hard coded values. You could use something like @Resource to define that these values are in someProps.properties file and then you can easily use different properties depending if you are in test or production.
You can also access any type of resource you need even outside the project folders. You could even use REST API to ask some other service for the configuration.
You add a package in pom.xml and then use the proper Annotation to get the feature you want inside your code.
JUnit for testing, RabbitMQ for messaging between beans or what ever the need is. You can add REST API support for your application in minutes with @RestController and the Spring Web package. Persistance of Java objects to Hibernate by adding JPA and H2
*/
The Back Story
I'll give some backround first and how I explained these Beans to myself. I have done J2EE programming back in the day for banks and such, so I got something like 7 years of Java experience in my pocket. When I was doing stuff there were Annotations in Java, but nobody was using them. There was no enum yet. So now ~20 years later I needed some software to automate a company's business. "I can do it myself with Java!" I thought and Googling around a bit I found out that Spring and Spring Boot is the way to go. Now after a week I finally got the Spring Boot Maven project to compile. I think I understand some of the methodology now. I don't know if the code actually runs, I wrote it as I undertand the Spring concept