What Is Spring Framework
What Is Spring Framework
More
than Dependency Injection
Last updated on May 14, 2020 - 29 comments
What is a dependency?
Imagine you are writing a Java class that lets you
access a users table in your database. You would call
these classes DAOs (data access object) or
Repositories. So, you are going to write a UserDAO
class.
import com.mysql.cj.jdbc.MysqlDataSource;
dataSource.setURL("jdbc:mysql://localhost:3306/myData
dataSource.setUser("root");
dataSource.setPassword("s3cr3t");
import com.mysql.cj.jdbc.MysqlDataSource;
dataSource.setURL("jdbc:mysql://localhost:3306/myData
return dataSource;
}
}
INSTANCE;
dataSource.setURL("jdbc:mysql://localhost:3306/myData
this.dataSource = dataSource;
}
return dataSource;
}
}
import com.yourpackage.Application;
Learning Spring
Spring’s Dependency
Injection
As already mentioned at the very beginning, Spring
Framework, at its core, is a dependency injection
container that manages the classes you wrote and
their dependencies for you (see the previous
section). Let’s nd out how it does that.
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.annotation.AnnotationConf
import javax.sql.DataSource;
UserDao userDao =
ctx.getBean(UserDao.class); // (2)
User user1 = userDao.findById(1);
User user2 = userDao.findById(2);
DataSource dataSource =
ctx.getBean(DataSource.class); // (3)
// etc ...
}
}
What is a
ApplicationContextCon guration? How
to construct ApplicationContexts from
Con gurations.
In the code above, we put a variable called
"someCon gClass" in the
AnnotationCon gApplicationContext constructor.
Here’s a quick reminder:
import
org.springframework.context.annotation.AnnotationConf
import
org.springframework.context.annotation.Bean;
import
org.springframework.context.annotation.Configuration;
@Configuration
public class MyApplicationContextConfiguration {
// (1)
@Bean
public DataSource dataSource() { // (2)
MysqlDataSource dataSource = new
MysqlDataSource();
dataSource.setUser("root");
dataSource.setPassword("s3cr3t");
dataSource.setURL("jdbc:mysql://localhost:3306/myData
return dataSource;
}
@Bean
public UserDao userDao() { // (3)
return new UserDao(dataSource());
}
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.annotation.AnnotationConf
UserDao userDao =
ctx.getBean(UserDao.class);
// User user1 = userDao.findById(1);
// User user2 = userDao.findById(1);
DataSource dataSource =
ctx.getBean(DataSource.class);
}
}
@Configuration
public class MyApplicationContextConfiguration {
@Bean
@Scope("singleton")
// @Scope("prototype") etc.
public DataSource dataSource() {
MysqlDataSource dataSource = new
MysqlDataSource();
dataSource.setUser("root");
dataSource.setPassword("s3cr3t");
dataSource.setURL("jdbc:mysql://localhost:3306/myData
return dataSource;
}
}
etc.
import
org.springframework.context.annotation.Bean;
import
org.springframework.context.annotation.Configuration;
@Configuration
public class MyApplicationContextConfiguration {
@Bean
public DataSource dataSource() {
MysqlDataSource dataSource = new
MysqlDataSource();
dataSource.setUser("root");
dataSource.setPassword("s3cr3t");
dataSource.setURL("jdbc:mysql://localhost:3306/myData
return dataSource;
}
@Bean
public UserDao userDao() { // (1)
return new UserDao(dataSource());
}
import
org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan // (1)
public class MyApplicationContextConfiguration {
@Bean
public DataSource dataSource() {
MysqlDataSource dataSource = new
MysqlDataSource();
dataSource.setUser("root");
dataSource.setPassword("s3cr3t");
dataSource.setURL("jdbc:mysql://localhost:3306/myData
return dataSource;
}
// (2)
@Component
public class UserDao {
import javax.sql.DataSource;
import org.springframework.stereotype.Component;
import
org.springframework.beans.factory.annotation.Autowire
@Component
public class UserDao {
@Component
public class UserDao {
@Component
public class UserDao {
@Autowired
private DataSource dataSource;
import javax.sql.DataSource;
import org.springframework.stereotype.Component;
import
org.springframework.beans.factory.annotation.Autowire
@Component
public class UserDao {
@Autowired
public void setDataSource(DataSource
dataSource) {
this.dataSource = dataSource;
}
Learning Spring
Spring’s Aspect-Oriented
Programming (AOP)
Dependency injection might lead to better structured
programs, but injecting a dependency here and there
is not what Spring’s ecosystem is all about. Let’s
have a look at a simple
ApplicationContextCon guration again:
import
org.springframework.context.annotation.Bean;
import
org.springframework.context.annotation.Configuration;
@Configuration
public class MyApplicationContextConfiguration {
@Bean
public UserService userService() { // (1)
return new UserService();
}
}
Spring’s @Transactional
Your UserService implementation above could look a
bit like this:
import org.springframework.stereotype.Component;
import
org.springframework.transaction.annotation.Transactio
@Component
public class UserService {
@Transactional // (2)
public User activateUser(Integer id) { // (1)
// execute some sql
// send an event
// send an email
}
}
@Configuration
@EnableTransactionManagement // (1)
public class MyApplicationContextConfiguration {
@Bean
public UserService userService() { // (2)
return new UserService();
}
}
Spring’s Resources
We’ve been talking about dependency injection &
proxies for a while. Let’s now have a rst look at
what I would call important convenience utilities in
Spring framework. One of these utilities is Spring’s
resources support.
Resource aClasspathTemplate =
ctx.getResource("classpath:somePackage/application.pr
// (2)
Resource aFileTemplate =
ctx.getResource("file:///someDirectory/application.pr
// (3)
Resource anHttpTemplate =
ctx.getResource("https://marcobehler.com/application.
// (4)
Resource depends =
ctx.getResource("myhost.com/resource/path/myTemplate.
// (5)
Resource s3Resources =
ctx.getResource("s3://myBucket/myFile.txt"); //
(6)
}
}
boolean exists();
String getFilename();
Does it exist?
import org.springframework.core.env.Environment;
public class MyApplication {
/mydir/application.properties
classpath:/application-default.properties
import
org.springframework.context.annotation.PropertySource
@Configuration
@PropertySources(
{@PropertySource("classpath:/com/${my.placeholder:def
@PropertySource("file://myFolder/app-
production.properties")})
public class MyApplicationContextConfiguration {
// your beans
}
@Component
public class PaymentService {
@Value("${paypal.password}") // (1)
private String paypalPassword;
public PaymentService(@Value("${paypal.url}")
String paypalUrl) { // (2)
this.paypalUrl = paypalUrl;
}
}
2. Or on constructor arguments.
Learning Spring
Additional Modules
There’s even more modules that Spring Framework
consists of. Let’s have a look at them now.
@Autowired
private JavaMailSender mailSender; // (1)
helper.setTo("john@rambo.com");
helper.setText("Check out your new
invoice!");
FileSystemResource file = new
FileSystemResource(pdf);
helper.addAttachment("invoice.pdf", file);
mailSender.send(mimeMessage);
}
}
Module Overview
I’d like to give you a quick overview of the most
common utilities, features and modules you might
encounter in a Spring framework project. Note,
however, that detailed coverage of all these tools is
impossible in the scope of this guide. Instead, have a
look at the o cial documentation for a full list.
Spring’s Data Access: Not to be confused with
Spring Data (JPA/JDBC) libraries. It is the basis
for Springs @Transactional support, as well as
pure JDBC and ORM (like Hibernate) integration.
Learning Spring
FAQ
You can see that the initial Spring release was ~17
years ago, with major framework versions being
released every 3-4 year. This does not account for
maintenance branches, however.
// Gradle
compile group: 'org.springframework', name:
'spring-context', version: '5.2.6.RELEASE'
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
The issue is, you have to write and con gure all
these individual pieces yourself. Spring Boot, on the
other hand, takes these single pieces and bundles
them up together. Example:
AspectJ Homepage
Google’s Guice.
Fin
If you have read this far, you should now have a
pretty thorough understanding of what Spring
framework is about.
You’ll nd out how this connects to other Spring
ecosystem libraries (like Spring Boot, or Spring Data)
in the follow-up guides, but for now I want you to
keep this metaphor in mind when trying to answer
the question What is Spring Framework?
Acknowledgments
Big thanks go out to:
e.g. martin@fowler.com
I want more!
Share:
Comments
Login
Add a comment
Anonymous
? 1 point · 4 months ago
Anonymous
? 0 points · 56 days ago
Excellent article! Thank you very much for putting the time and effort into
it
Anbu Sampath
A 0 points · 4 months ago
Anonymous
? 0 points · 53 days ago
Hey Marco,
Marco Behler
0 points · 53 days ago
Mishap on my part! Thanks for bringing it up, will be fixed soon.
Anonymous
? 0 points · 4 months ago
Anonymous
? 0 points · 4 months ago
Anonymous
? 0 points · 4 months ago
Anonymous
? 0 points · 4 months ago
Anonymous
? 0 points · 4 months ago
Anonymous
? 0 points · 3 months ago
Thank you very much for this very insightful article. I am a Spring
developer since one year, but always had some issues understanding how
the internals of Spring work and what is actually doing. Thanks to your
article I now have a better understanding of all things that are happening
intrinsically. Kudos!
Anonymous
? 0 points · 4 months ago
Anonymous
? 0 points · 4 months ago
Marco Behler
0 points · 4 months ago
Anonymous
? 0 points · 3 months ago
Anonymous
? 0 points · 3 months ago
Thanks for this article! I loved the one on Microservices and this one as
well. Keep em coming :)
goyalshub
G 0 points · 3 months ago
"Spending ~15 minutes reading this guide" are you kidding me?
Marco Behler
0 points · 3 months ago
Anonymous
? 0 points · 3 months ago
Anonymous
? 0 points · 3 months ago
Great article and summary. I would just add that the @Scope("singleton")
is the default setting for a new creation of a bean. Your text suggest it but
doesn't mention it explicitly. Another idea: The @Scope("prototype")
could be used if one connection should have 'UTF-8' encoding while the
other not or different timezones. Than one could easily get the same
basic settings but different flavors of the same settings. Beside this -
wonderful to read this article especially a er working some time already
with Spring. Now getting a little bit more detailed idea. THX
Anonymous
? 0 points · 3 months ago
Well written; with a good deal of links to follow up for more details.
Sterling job!
Anonymous
? 0 points · 3 months ago
thanks so much
Anonymous
? 0 points · 3 months ago
I read other tutorials to explore Spring, and they were winding and had
unnecessary details. Yours was crisp, clear and much useful. Explained
clearly why the framework is so popular. Thanks!!
Anonymous
? 0 points · 42 days ago
ricksonmenezes
R 0 points · 3 months ago
Marco, what made you write this? The fact that you found this need to fill
the gap with an in-depth write-up requires many shout-outs. Thanks you.
Anonymous
? 0 points · 7 days ago
ricksonmenezes
R 0 points · 3 months ago
Hi Marco,
In the code here there is a main method. In my spring mvc project, there
is no main. We have web.xml, our main servlet mapped there, other bean
objects declared in dispatcher-servlet.xml but no main().
Why is it that your demo code has it? Does it not use a servlet? If the
answer is too long, do you think you can point me to a resource?
Marco Behler
1 point · 3 months ago
Now, you seem to be using Spring "WebMVC" (!), with the old-school
web.xml & dispatcher-servlet.xml configuration. That means you will
have a Tomcat (or similar servlet container), package up your
application into a .war file and put it into your Tomcat. Your Tomcat will
be able to read he web.xml and - in the end - instantiate a
DispatcherServlet which internally needs (to instantiate) an
ApplicationContext. So what we do here in the main method is
basically hidden for you that way.
There are other, more modern ways, though. First, you could use an
embedded Tomcat and ,second, then use the servlet 3+ servlet
initialization mechanisms without having a web.xml, and at the end
with a Spring Java Config instead of the dispatcher-servlet.xml.
As for further reading, I actually explain and make you practice pretty
much all of these concepts in my new Spring Framework course
https://www.marcobehler.com/academy/learning-spring , which will
be published this week. You will be able to try out the first part for free,
which explains most of these concepts.
Cheers
Anonymous
? 0 points · 2 months ago
Nice overview! The only thing I'd complain about is that it uses annotated
controllers with field injection, which was the standard pattern about 10
years ago. These days, most people agree that @Configuration classes
with constructor injection are the way to go, mostly because that
combination leads to better testability. Don't want to create a login here.
Disagree with me at https://twitter.com/oldJavaGuy
Powered by Commento
Privacy & Terms | Imprint | Contact