Hacker News new | past | comments | ask | show | jobs | submit login
History of Spring Framework and Spring Boot (quickprogrammingtips.com)
159 points by based2 on April 2, 2018 | hide | past | favorite | 128 comments



Spring as a framework has come a long way since the year 2006 when it required multiple XML files for configuration to the now Spring Boot which requires virtually zero configuration. Now it is easier to develop MVP web app using Spring Boot than Rails. With the framework such as Angular 2, people withe server side programming experience are finding it easier to develop client side app with much ease. I have found Angular 2 and Spring Boot a great combination for client server app development.


I guess I'm alone in 2018 year, but I implemented new project with Spring 5 and XML configuration which works just fine and I think that it's easier to understand and support than Java configuration (or autowiring which I never use, because explicit is better than implicit even at the cost of boilerplate).


> explicit is better than implicit

You may be interested in programmatic / functional bean registration[0], which was introduced in Spring Framework 5. It has a particular focus on Kotlin support[1][2].

[0] https://springoneplatform.io/sessions/programmatic-bean-regi...

[1] https://spring.io/blog/2017/08/01/spring-framework-5-kotlin-...

[2] http://ilities.co/2017/09/10/annotation-free-spring/


No. I completly agree with, it's far easier than debugging what configuration has been applied due to specfic annotations used.


You can use Java explicit configurations without Spring boot magic. Using XML to configure an app is so backward to me and prone to error, not to mention debugging. When I see xml config file in 2018 I want to poke my eye out.


I don't like XML either but I can clearly see the point in being explicit.

Unless you're working alone or unless everybody knows exactly how the whole system works, being explicit will save you a lot of time.

If you're still insisting, I suggest you to clone random mid-size spring project from github and do some non-trivial change (like implement automatic tracking of all changes or soft-deletes)


> Now it is easier to develop MVP web app using Spring Boot than Rails.

This caught my eye. I have never used a Java framework, but use Rails daily. Does Spring Boot do Rails things such as migrations? Is there a healthy plugin ecosystems? (whatever the Gem equivalent in Java is).


I used rails professionally since version 0.14. 4 years ago I joined a new company and started developing Java server-side with a few years experience with java from University.

After 3 years of building and maintaining a mission-critical Java backend, I would never do it again... We were using a similar framework, called dropwizard, great product, super lean and reliable.

If you think Rails is magic, then you haven't seen the Java world, all the magic with annotations, dependency injection, glueing libraries together by placing some files in a folder.

If you think Rails 2.3 to 3.0 upgrade was dramatic, then what we went through with a minor update from dropwizard (i think 0.7 to 0.8) was a nightmareish 1-2 months of rewriting half of the code and dependency injection handling.

Java is still super verbose, not just the language itself, but also all the libraries that are often over-engineered.

Hibernate is quiet easy to get started and you don't understand what all the fuss is about. But once you go start adding features it quickly becomes unmaintainable and any change to the models comes with FUD whether that'll make the queries explode in an unpredictable manner.

There's a lot of libraries, but on UI/UX level you don't have anything close to what Rails offers out of the box. Things you take for granted don't exist, like devise.

The good parts were: Rails deployments are from the stone-age compared to dropwizards simple approach of installing java and copying the self-running jar (fat binary) to server and start. Very good instrumentation/metrics out of the box with joda-metrics.

After 3 years, a pivot required us to rewrite large parts of the logic. We took that as a chance to rewrite/migrate all our services to Elixir/Phoenix. And never looked back.

So far Elixir/Phoenix/Ecto to me is the perfect middle ground between a solid Java environment and the speed of development of Rails.


I tend not to agree with most of your points, but it may be a matter of taste. I actually like Java (but I also see quite some overengineering in some places).

> all the magic with annotations

... which are basically just decorators

> dependency injection

... which is quite useful for loose-coupling and injecting different implementations (and you don't have to use it)

> glueing libraries together by placing some files in a folder

.... what? Never done that ;-)

> Java is still super verbose, not just the language itself

I don't see that. It's actually quite nice for my taste. I guess you don't like generics, but then you have to live without them, which also sucks.

> There's a lot of libraries, but on UI/UX level you don't have anything close to what Rails offers out of the box.

What do you mean exactly? There are things like thymeleaf if you want SSR, otherwise you can put whatever SPA in front of it.

> things you take for granted don't exist, like devise.

.. it's not hard to use Spring Security though

>Elixir/Phoenix/Ecto" - is there some devise like auth by now? I also like Elixir/Phoenix quite a lot, but it's nowhere near Rails/Springs level.


> Elixir/Phoenix/Ecto" - is there some devise like auth by now?

Coherence https://github.com/smpallen99/coherence


You can't compare java to rails like this. Java is a server side language - rails is a web-dev library written in Ruby.

All the things you are complaining about have been abstracted away by many recent java and groovy libraries.

You are literally comparing some random company using a random java framework 4 years ago to modern ruby on rails. The comparison just doesn't work.

You can make java as simple as you want or as complex as you want. Modern tools like spring boot and groovy make it VERY easy to make java simple.


I use dropwizard but I would never consider it (or any java framework) for UI related work.

Kinda curious why there was such a big migration conisdering dw is mostly just a combination of packages.


What do you mean by UI related work?


Anything involving frontend. Dropwizard seems to fill the niche of API server very well but not beyond that imo


I still don't get it. How do other frameworks help on the frontend side? On Rails you're on your own, frontend-wise.


Spring Boot is an integration framework, which means that it does not implement various things itself, but provides an easy way to take a 3rd party implementation and plug it into your application. In Java there are multiple migration frameworks, including the ones that do migrations in a way similar to Rails. However, this approach is not very popular for exactly the same reasons people writing comments here distrust annotation-based configurations - it's not always obvious what an ORM will do for you. The recommended approach in Spring Boot is to use Flyway library which combines plain SQL migrations with custom Java code for complex data transformations and seeding the db.

Regarding ecosystem, the Java one is the biggest and has much more to offer than any other technology. Spring Boot can work with all libraries and there exist Spring Boot plugins for the configuration of the most popular solutions (data storages, clouds, templates, MQs etc).

The package management in Java is mature and one of the best and is now replicated/reused on other platforms. E.g. Java-based Nexus repository can be used for hosting libraries for JS and Docker and tools like Apache Maven can build and manage not only Java projects (I think it's even possible to wrap Rails project in Maven).


Gem is not a „plugin framework“ for rails. It’s a (dependency and) package manager for ruby libraries. That can contain rails plugins too, but i doubt that’s it‘s main use.

Most popular languages today have such a thing - cpan gor perl, pip for python, etc. In java there‘s at least maven for that with it’s huge library repositories.

There might be more nowadays, i‘ve not been using Java since a good while.


I haven’t used rails but I did use java’s play framework extensively and found it very easy to use and fast to develop for (coming from a PHP background). It has a migrations system baked into its ORM layer.


True and true. Even better is that you have native Kotlin support for it and with the advent of Kotlin multiplatform projects now I can write apps using Kotlin only. I finally reached a point that I don't have to use Javascript anymore!


Have you tried kotlin.js? It's still very fiddly to get up and running, think we'll have to waiting on tooling for it to be a good alternative


There are example projects which work out of the box. I am actually using it in production.


> Now it is easier to develop MVP web app using Spring Boot than Rails.

Really? Does it do a lot of code generation across the db / server / front end?

That plus convention over configuration makes most of my rails development pretty fast.


Why Angular 2 and not 5?


Because how else do you differentiate between Angular 2+ and Angular 1? They really should have changed the name since they are two completely different frameworks.


They did for 1.x, retroactively. That line of versions is now referred to as AngularJS by the Angular team, while the name Angular is reserved for 2.x and up.


True, but that doesn't help you google resources. I usually resort to just restricting to stuff in the last year.


> Now it is easier to develop MVP web app using Spring Boot than Rails.

BWAHAHAHAHAHA! Good one.

Seriously, though, I'm really, really glad to see this come up this morning.

I've done a lot of .NET lately, but Rails has been my main tool for 10 years. However, because it's (apparently) a strange, new, unproven-and-potentially-exceedingly-insecure framework, and because I'm the ONLY PERSON in a company of SIXTY THOUSAND employees who could possibly write a program with it, I've been forced to stop using it. I took FOUR MONTHS of arguing about it with the powers-that-be to conclude that I should use Java instead. I have 3 web applications to write, right now, with some flavor of Java EE.

For a couple of weeks, I've been trying to bootstrap an environment to read an existing database I had already created with Rails, and filled with production data. I thought it would have been straightforward. I'm trying to use current versions:

* Netbeans 8.2 * Java 1.8 * Gradle 4.6 * SpringMVC 5.0.4 * Hibernate 5.2.15

I can't find a single, working example that demonstrates this stack. Not a single one, on the entirety of the internet! Every example I can find switches out some part of that stack, and makes the flow different. Netbeans and Eclipse do things differently, and both have about 3 different ways to generate a Java web application.

Then there's the whole Maven thing. I guess most of the world hasn't really switched to Gradle, despite their site's glowing description of the advantages?

And what is "Spring Framework?" There's really several different pieces of that puzzle, and that's fine, but, at the end of the day, show me the code, AND TELL ME WHERE TO PUT IT IN THE FILE STRUCTURE TO MAKE IT WORK.

Most of the examples I can find about how to write a Java web application never even get to the point of pulling data from a database, and so finding an example that uses either Hibernate OR JPA is almost non-existent. This just makes me shake my head.

My current direction, which I was all set to get serious with today, was to use Groovy on Grails, under IntelliJ IDEA. After a couple of weeks of experimentation, it's the only stack I've been able to bootstrap, and actually get a listing of objects from the database. I feel it probably takes too many liberties to simplify the workflow, and will quickly lead to a bottleneck I don't know how to get out of, but, dammit, it's the only thing I can find some reasonable examples for.

(But even IDEA wants to generate a stack based on the non-current Spring 4.3.14, and Hibernate 5.1.5. Spring 5 is released. Why doesn't IDEA "support" it yet? What little examples I can find show that a lot of things are changing from Spring 4 to 5.)

Through this learning process, I've realized just how much tribal knowledge I've absorbed about Rails. I "grew up" with Rails. I was playing with it in the 0.x days, got serious with it in the early 2.x era, and have stayed with it ever since. I understood that learning how to use another web stack would be a challenge. While the actual language is hardly a concern to me, I had no idea that the chaos of choices and versions would complicate the process of just trying to get started. At the very least, when you say "Rails X.0", you've described all the major pieces of the stack, and the IDE is immaterial. That is simply not the case in the Java world.

So I've said all of this to set the context in order to ask you this: What is the "right" framework stack to use to create a Java web application TODAY? And by "right," I mean "most popular," in order to make finding answers as easy as possible. For the sake of argument, the 3 apps I need to write are essentially simple CRUD applications, so there are no esoteric requirements to consider. What's the most straightforward and maintainable approach, and where's the definitive documentation on how to configure it? I'm ready to go all-in on SOMETHING, but I'm overwhelmed with choices and a lack of examples.


> At the very least, when you say "Rails X.0", you've described all the major pieces of the stack, and the IDE is immaterial. That is simply not the case in the Java world.

Of course the IDE is immaterial. I understand that developing in a stack that you are familiar with is much simpler for anyone but people could make similar claims in support of Java+Spring.

That being said, if you are forced into this by your company, I think that stepping back from this would help you a lot.

The IDE is absolutely irrelevant to java stack (of course, there are some little nuances when you do something like develop an eclipse plugin, but in your case where you list several general technologies, there should be zero dependency on an editor) - whether you use netbeans, eclipse, vim, vscode or intellij should change exactly nothing about your project setup, maybe except for extra .gitignore line or two for the editor specific files.

I suspect that majority of the problems you're describing stems from this misconception.


If you want an example of a project using all the latest technologies together, a good place to look is jhipster. It’s code generation of a spring boot and angular or (coming soon) react app. When you use it, it will ask a series of questions about what you want your app to look like, and then generate that app. It as if you paid some expert to come in for a week and set everything up, including migrations, auth, documentation using swagger, and so on.


Excellent! Thank you!

And, to be fair, I've also since discovered https://start.spring.io.

It's worth pointing out that both of these sites exist specifically to address my frustration in just getting started with a Java web stack, but it's taken me a couple of weeks to discover them.


we somehow missed having a link to start.spring.io from the website front page. We'll get that addressed, thanks for this comment.


Why exactly did you choose Netbeans and Gradle, and why didn't you use Spring Boot for your first setup?

And how exactly did you search for examples, considering that there are pretty good guides and lots of examples right on the Github? Here's the one from Spring: https://spring.io/guides/gs/accessing-data-jpa/


How do I generate a stubbed structure to start with Spring Boot, without downloading an example? Is there a generator of some kind? I'm still looking for this answer.

That example is for JPA. I thought the "better" answer for a Java ORM was still Hibernate, and I can't find a Spring-based example for that. If you tell me that Hibernate has been usurped by JPA in Java developer mindshare, or if you tell me that JPA just works better with Spring, I can change course. I have no experience with either to make the call.


JPA is just the API; Hibernate implements JPA. :)


Thank you. These are exactly the sorts of comments I need to establish CONTEXT for all of these pieces.


https://start.spring.io/

Here you can generate a project and you can select what options you want in your starter.


I can sympathize with your rant. I remember the first time I started using the spring framework! It’s not bad once you get used to it, though. There are whole swarms of Java programmers who are really Spring programmers because that’s the only way they know how to do anything.

Anyways, I would highly recommend using IntelliJ and Dropwizard, both of which “just work”. Don’t worry about anything else, just use the DW docs.


Just mentioning your IDE as an essential part of the "stack" shows how little core understanding you have. You should read up on the documentation of the basics of java, gradle and spring first. Not sure maybe rails developers expect everything to be spoon fed to them in pieces of 5 minute screencasts or something?


> shows how little core understanding you have

Really? You dismiss my clearly-not-ignorant comments by belittling me? OK. I should have known.

Part of the frustration here is this: given a clean sheet of paper, and a desire to write a Java-based web application, where do I start? What files do I download? I don't know! How do I start developing with Spring? The site says "add this line to your build file." WTF does that even mean, to a Java noob? What's the file I'm supposed to be putting that configuration into? Unless you have a file structure bootstrapped, and know that they're talking about pom.xml, in the case of Maven, or build.gradle, in the case of Gradle, it doesn't mean anything!

How did I figure that out? By using an IDE and generating example file structures for a "web application" based on those 2 options in the stack. So getting started with Spring requires an existing bootstrapped structure that I STILL don't know how to generate by hand. (Feel free to enlighten me. How do YOU start a new Spring project?) Hence, my frustration with the various IDE's, and their multiple ways of generating what should be a pretty standard stack of files to get started.

As I tried to indicate, I "get it" that I have a lot of this stuff internalized with respect to Rails, and that's what I'm trying to get across. I don't think that the Spring folks understand what they need to do to "onboard" someone to their system. At least Grails seems to do a better job with this.


You might not like it, but I think that you need to start from scratch. Learn Java language, learn how javac compiler could be called, compile simple application from console. Then learn about Maven or Gradle, how to use them to build things. Then learn a bit about IDE. I suggest Idea, but Eclipse or NetBeans should work fine. Learn about Java Servlets, it's the underlying library for almost every Java web application. Deploy simple servlet to tomcat, learn how to handle GET/POST requests. Learn about JDBC, combine servlets and JDBC. Actually here you can stop and write production code for some simple REST service, for example. Only after you have some understanding about every underlying part, you should start with Spring framework, JPA, etc. And still it'll take a lot of time to learn those things.

I'd suggest not to search for various "stacks". They might be written poorly and incomplete. Learn each part and learn how to combine them.

I guess Rails is a complete solution, with Java there are many libraries which you should choose and glue together. Every non-trivial application probably will use somewhat unique combination of libraries.


re: tribal knowledge, what I've found in the Rails world is that much of the "getting started" process stuff was forged around one tech stack early on, and often one editor that everyone used (based on having watched a video).

When Spring started, there was already a myriad ways of doing stuff, and multiple IDEs, and multiple use cases for Java itself, and Spring was trying to answer a lot more up front.

If you're doing 'web' in Java (something I still think much of the java world still doesn't really 'get'), there are dozens of choices/options/etc. If, in 2006, you were planning to do 'web' and wanted to use Ruby... the primary choice was Rails. If you were doing 'web' and wanted to use Python... you similarly have often only had one or two major choices (I'd argue 'Zope' early on, then Django as a default go-to for the last 10 years or so). In the Java world... way too many choices up front, all answering similar problems, but slightly differently.

While Ruby was out before Rails, their popularity generally rose in tandem, and much of the tooling for the ecosystem seemed to develop in tandem during the progression of Rails itself.

Had Spring started in 1997, we might have seen a somewhat different trajectory re: choice/tooling/community/etc.


> Just mentioning your IDE as an essential part of the "stack" shows how little core understanding you have

The GP seemed to be indicating they were trying to put together a standard set of tools for others in their company to use. Having one official 'blessed' IDE and a 'standard' way to do things - even as a demonstration process - isn't out of the ordinary. And... given how much any complex Java program relies on the author having an IDE handle things for them (the assumption is that an IDE will help find the correct imports when developing, for example), it's pretty common for people to assume you're using one of the few common ones out there. I guess the author was looking for 'free' up front, but I'm curious why they didn't mention IntelliJ - it's the only thing I'd bother with for 'real' Java development in 2018 (although I'm keeping an eye on the vscode landscape).

> should read up on the documentation of the basics of java, gradle and spring first

There's no 'basics' to those - they are sprawling ecosystems, and any non-trivial task requires a pretty deep understanding of how those pieces fit together.

> maybe rails developers expect everything to be spoon fed to them in pieces of 5 minute screencasts or something?

Perhaps other tech stacks are able to deliver useful/functioning tutorials of information in 5 minute screencasts, without requiring someone to be an expert or have years of the 'tribal knowledge' the GP spoke of in another post?


> The GP seemed to be indicating they were trying to put together a standard set of tools for others in their company to use.

Yup. This is forging a new trail at the company, which is, itself, a painful process.


Ahh - you did mention intellij. :)

I was a grails advocate for a long time. I put up with some of the initial pain (from 0.6 days) because it provided more benefit than not. And, had I not picked up intellij, I may have left the fold a long time ago. :)

As time has gone on, the coupling with Spring has become more obvious - I may have just been blissfully unaware earlier on. The migration to a 'spring boot' based approach has sort of soured me more than I expected. If I wanted to use Spring boot, I'd use it. I preferred some of the Grails conventions, but many have been thrown out or reduced to accommodate the Boot way. Some of the stuff I'd hoped to have to dig in to (and, in some cases, had not needed to be an expert in) have now become requirements to dig in to, and I spend more time configuring and digging through framework problems than the actual application.

No doubt much of this is me, but I'd hoped Grails would improve, but for me, it's just changed. My work with Java/Spring/etc definitely has helped me think about problems differently, and improved my thinking and coding overall, but much of what I was looking for has improved in other ecosystems over the last several years to make continuing in the Java world a harder decision. (context: I'm primarily a solo developer, not working with large teams or large budgets). One minor example: being able to make a code change in a test, run that one test, make another change, and rerun the test, all in a few seconds doesn't seem to be something that's possible in the Spring world, and perhaps not in the Java world in general (no doubt there will be people who tell me "you're doing it wrong" and "we run 4000 spring tests every 7 seconds with 0% CPU!" but it's not been my experience).


> One minor example: being able to make a code change in a test, run that one test, make another change, and rerun the test, all in a few seconds doesn't seem to be something that's possible in the Spring world, and perhaps not in the Java world in general

This was my experience when I began.

What I learned was: unit tests don't need Spring. It seems silly in retrospect, but that's the basic rule. If you need Spring in your unit tests, you probably made a mistake somewhere.

Having worked in a few languages and frameworks, having seen codebases at various levels of maturity and whatnot, I quite like Spring Boot & co. Especially when Kotlin is in the picture.


> What is the "right" framework stack to use to create a Java web application TODAY? And by "right," I mean "most popular," in order to make finding answers as easy as possible.

I understand that motivation, but given that someone else (company) has made some of this decision for you, based on - it seems - ability of other people in the company to take over the apps, is there not some internal standard or existing apps you can learn from?

I realize telling you how this is a stupid decision your company has made doesn't really help, but given the decision, I'd think that would mean there's someone else with existing Java web app knowledge/experience for you to learn from?

Having the app done in Java - even if it means it's 6 months late - seems to be more important than having the app(s) available now, which - that alone must be frustrating. :/


If there's someone else to glean from, they're in one of the myriad consulting companies that we've hired to write existing Java apps, and then bugger off, never to update them again.

Frustrating doesn't even scratch the surface of what this is. And, to be fair, my attitude about how this has gone hasn't exactly helped me find the answers I need. ;-)


> My current direction, which I was all set to get serious with today, was to use Groovy on Grails

Is that version 2 or 3 of Grails? Virtually no-one has updated their Grails 2 websites to version 3, or is starting new projects in Grails 3. Choosing version 3 means first adopter risk.


So I'm quickly discovering. The problem is that I know the kinds of changes Rails introduces from one major revision to the next. If Grails follows that pattern, I don't really want to get started with 2.x, knowing that I'll have to relearn a lot of things on 3.x. It's a bit of a chicken-and-egg problem.


> Choosing version 3 means first adopter risk.

I upgraded a couple v2 to v3, mostly because of concern about security (moderately sensitive data, most of the 2-era plugins aren't updated, etc). The allure of v3 was supposed to be "it's all spring boot!" but... I'm not capable enough of just installing random spring stuff and configuring it for boot - there's still 'stuff' grails does its own way (or... it's just my competency level?) But if I need to become much more proficient in spring boot to get benefit from grails 3... i'll just move to spring boot in the long haul. This seemed an inevitable move for grails, but not one I was excited about.


Go to https://start.spring.io. It will let you down laod zip file which contains base project structure. Choose maven or gradle. Don't create your project using any ide netbeans, eclipse, Inyelij IDEA. USe file -> open menu and open maven(pom.xml) or gradle(build.gradle) file and choose as project.


Yes i do prefer maintainability and same codebase over one tool which one specific developer is very good in and is the only one using it.

On another note: Just don't use Spring 5 or every other framework for a small simple thing which got just released.

There is no harm at all in using Spring 4 and all tools and everything is just working.


> For a couple of weeks, I've been trying to bootstrap an environment to read an existing database

Correct me if I'm wrong: for several WEEKS you're struggling with implementing a database read?


The price one pays for the flexibility Spring offers is in terms of performance. Spring uses a lot of reflection. It makes it very slow. The startup time of Spring applications tends to be around 20-30 secs. If you add Hibernate to the mix the situation becomes even worse.

Yes, Spring offers a lot of flexibility in terms of IoC and testability. I generally avoid Spring for B2C apps. (For B2C apps, I tend to favor Jersey + MyBatis) But for B2B apps and in-house enterprise apps, Spring is a very good candidate.


> Spring uses a lot of reflection. It makes it very slow. The startup time of Spring applications tends to be around 20-30 secs. If you add Hibernate to the mix the situation becomes even worse.

The load time of Spring apps is dominated by the number of classes loaded from disk, which is a function of the libraries pulled in. This is because the JVM loads classes out of JARs more or less linearly.

Think about it for a second: which is faster, in-memory operations (reflection) or I/O (loading classes from disk)?

Dave Syer has done more actual empirical investigation[0] of Spring's launchtime behaviour than anyone. If you can produce better evidence of actual behaviour, I'll be very surprised.

[0] https://github.com/dsyer/spring-boot-startup-bench

Disclosure: I work for Pivotal, we sponsor Spring development. I do not work on Spring.


This is part of the reason that I highly recommend compile time dependency injection (Macwire[1], Dagger 2[2]) over runtime dependency injection (Spring, Guice). It is generally much faster. Also, if it does slow down compilation, it is a price rarely paid due to incremental compilation.

[1] https://github.com/adamw/macwire

[2] https://google.github.io/dagger/


During development, you can throw money(=hardware) at the problem and get pretty decent results. In production, the startup time should not matter much, as warming of caches etc will take longer than tens of secs anyway.

I guess the biggest issue is restarting services in production, but that is mostly alleviated by not having singular copies of crucial services.


In my experience Spring Boot apps tend to start in around 5-7 seconds.

It all depends on what your init logic is I guess.


Since you mentioned Hibernate, it's been years since I had to deal with it, but the "generate bytecode for all the things" start-up time of Hibernate/JPA drove me nuts and I built Joist [1] specifically to fix/avoid it.

All of Joist's Rails-ish code generation (creating the boilerplate lazy-loaded getters/setters/collections/etc.) is done at build-time so your test-/server boot time is very quick.

[1]: http://www.joist.ws/


While startup might be relatively slow, runtime performance should be very fast.


Avoid package scans, they are very slow.


When I was doing Java development full time, it felt, like at the time, Spring Boot was a direct response to Dropwizard, which I was using everywhere I could. In either case I am almost certain Dropwizard's rise in popularity placed a fire underneath Spring and eventually Spring Boot caught up and the ecosystem as a whole was better off, IMO.


FWIW, the SPR-9888 JIRA issue [1], which prompted the creation of Spring Boot and is quoted in the article, actually names Dropwizard as an inspiration.

The article quotes:

"I think that Spring's web application architecture can be significantly simplified if it were to provided tools and a reference architecture that leveraged the Spring component and configuration model from top to bottom. Embedding and unifying the configuration of those common web container services within a Spring Container bootstrapped from a simple main() method."

The very next lines are:

"Though there are many frameworks and platforms today that no longer require a container I think inspiration can be drawn most from DropWizard (http://dropwizard.codahale.com/).

Another project I've seen inspired by DropWizard but leveraging Spring is HalfPipe (https://github.com/32degrees/halfpipe). Though I don't think HalfPipe goes far enough. I think to truly provide simplification the entire architecture, wherever reasonable, must be embedded within the Spring container rather than without. Though it does have several other interesting ideas."

[1] https://jira.spring.io/browse/SPR-9888


I know my comment here isn't adding much -- but that is awesome.


I too felt that Spring Boot was a response to the simplicity of Dropwizard. I worked at a place which had two opposing java camps. One was heavily into Spring Boot, the other, Dropwizard. This might not be a fair representation of Spring Boot, but unfortunately our Spring Boot crowd were card-carrying Spring-for-everything people who would over-engineer their systems to the point where a simple REST API would have thousands of lines of code, magic everywhere, mediocre performance, and present a nightmare learning curve for new engineers. The Dropwizard-based systems were far less magical and much easier to understand. Maybe Spring Boot can be just as nice, if the right people use it?


Absolutely. It makes me laugh when the article says spring boot is opinionated - for dropwizard that meant picking the best tool for the job, for spring boot it seems to mean picking the spring tool for the job. I guess that's just the way the spring ecosystem is, but as a philosophy it's not one I'd be proudly stating.


I've heard multiple origin stories -- one is the issue linked in the article. Another was that Dave Syer worked on a Rails project briefly and thought "oh, this isn't so bad".

Spring is a team of fairly smart individuals who tinker with experimental stuff all the time, so I would not at all be surprised if Dropwizard didn't figure amongst the inspirations. And they do keep up with what other folks are doing, so good ideas tend to be adopted into Spring pretty frequently.

Disclosure: I work for Pivotal, but not on Spring.


Would you use dw or spring boot now? Our current stack is dropwizard but I've never messed around with slring boot


I would definitely use Spring Boot now. It definitely has parity in my view. The simplicity is there too, so for example if you still like DW metrics you can pull those in easily. You also get the other Spring things for free, like Spring Batch which I think is another good piece of software from Spring.


Spring is a very powerful but complex framework. It's very easy to get started (Spring Boot). I especially love JPA as I just need the persistence to be getting done. The architecture is clean and standardized.

However, you have to be prepared for a serious learning curve when needing customizing (e.g. attribute based authorization with Spring Security and AOP). It's a jump in the cold water after the pain- and effortless start using Spring Boot.

I haven't mastered Spring yet (in depth understanding of DI, AOP and the configuration), but I feel that when mastered, Spring is the ultimate framework to build concise and clean applications.


It's always scary to have a lot of power hidden behind an annotation that you don't completely grasp. But I rather take that than having to reimplement all the logic, such as for security, that isn't core to my own business. I have come to trust Spring as a quality product, which will do a better job at those things than I would ever be able to do with the (not in an unhealthy way) resource-challenged teams that I tend to work on.


Personally, I don't like annotations, and it's related to a very specific word you used: Hidden.

Annotations feel very action-at-a-distance-esque because the code that scans for them and processes them is completely separated from the annotation itself. There's no really universally applicable way of just going "show me all the code that processes annotation X" to your IDE... and that's often scary and can also lead to incredibly hard-to-debug problems which would be near-instantly solvable if you could just see the code which processes an annotation immediately.

I feel decorators/higher-order functions are generally to be preferred since it's actually about applying concrete transformations. (Of course they may not always have equal power, but a lot of the time annotations are basically just a HOF in disguise.). Unfortunately, without good type inference the syntax of HOF can get incredibly clunky.


> There's no really universally applicable way of just going "show me all the code that processes annotation X" to your IDE

Isn't "Find References" literally that? All code that makes use of an annotation at runtime (which is the case for all Spring annotations) needs to refer to the annotation's type at some point.


> However, you have to be prepared for a serious learning curve when needing customizing

Can be said about everything in this world, right?


Yes and no -- I often found the difference between a well architected and modularized (when possible) system and one that isn't is that the learning curve is more linear.

Frameworks that are large often have lots to learn in them, necessarily, but how that learning has to be done can differ. Good frameworks will be simple enough that you can almost ignore the ocean of complexity until you need to dive in, and when you dive in all of the pieces that you now must need to learn and know are almost obviously necessary.

For example, compare/contrast a system like express (nodejs) with a system spring in java. The func(req, res, next) paradigm gets you VERY far, but doesn't expose you to too much before you need to. Implementing middleware is much more delightful in nodejs (and other frameworks that adopted the func(req, resp, next) abstraction) than it is in Sprint.


Implementing simple middleware in Spring (boot) is pretty much the same. One class with one method that has access to req, res and the next filter. The @Component annotation is all it takes to enable the filter in your web stack.

  @Component
  public class MyMiddleware extends OncePerRequestFilter {
  
      @Override
      protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
          // your code
          filterChain.doFilter(request, response);
      }
  
  }


I think this is a good example of the difference in complexity grades of both langauges/frameworks. That spring boot example is indeed pretty simple (for java), but to understand it, here's what I'm pretty sure has to happen:

1. Set up your spring boot project properly

2. Set up all the XML that supports your beans properly

3. Know how and when to use @Component

4. Know that OncePerRequestFilter exists, and/or to extend it, which method to override

5. Know to call filterChain properly

Most of these are trivial with some IDE support and maybe a templating school, and probably not even an issue after your second week with Spring boot (or spring in general), and it's an improvement over what life used to be like but compare this with the general jist of how to do it in JS:

1. set up expressjs properly (usually a two-liner). It won't have things like @Cachable that spring boot provides to you out of the gate, but it generally has enough to get you up and serving requests.

2. Know what req/res are (the fact that calling res.send(...) sends stuff and .ends as well is arguably nontrivial) and how to use next

3. Know what a function is.

the code snippet I'm thinking of is:

    app.use(function(req, res, next) {
      // your code
      next();
    })
It is "pretty much" the same, but how much work it is really depends on who you ask -- you can get up to speed with a simply built expressjs app in tens of minutes (many express apps follow a very simple setup pattern), but I've never seen that happen in a spring boot app for an absolutely fresh developer, even worse if the codebase is transitioning from spring to spring boot or has some other hacks in it.

Spring Boot is marvelously simple one of it's best parts (it almost makes me want to use Java for a greenfield project), but there's so much noise in that code -- it should just be a function -- IMO all started with the decision in 1.1 (??) to choose Runnable over lambdas. Most of the complexity I'm ribbing Java over is just due to how you write the langage -- java on it's simplest day just can't be as simple as some of the stuff that came after it, since they had the benefit of hindsight.


1. setting up a Spring Boot project is just File/New Project/Next/Next/Next, or download a starter project from https://start.spring.io

2. It's 2018, we don't use XML anymore, a Main class annotated with @SpringBootApplication is all the configuration you need (and autogenerated by step 1)

3. All you need to know about @Component before you get started is if you annotate a class with it, it will get instantiated with all its dependencies and made available for use in the container

4./5. Yes, to know about Filter, the filterChain and how to use it might take some minutes looking into the documentation or stack overflow, but that is what you are going to have to do anyway if you are going to use a framework.

I put knowing how to use @Component and figuring out what you need from the docs on the same level as knowing about the (req, res, next) pattern and knowing about async/callbacks/promises.

I agree that Java is verbose and has much ceremony but modern IDE's take away a lot of that pain. For my filter example the only things I typed are:

* the class name

* extends OPRF<tab>

* <alt><enter> <enter> to generate the 1 method to implement

* the `// your code` comment and filterChain.doFilter()

I'm not sure what you mean about choosing Runnable over lambdas. Runnable `is` a functional interface so anywhere you can use a Runnable, you can pass a lambda (or method reference)


I find setting up the toolchain for Javascript projects to be an exercise in torture, toil and tears, so it's not quite as simple as all that.

Meanwhile I can get to a running Spring Boot app in quite literally seconds.

The difference is that I know something about Spring Boot and much less about Node. That says nothing about either of them.


The contract of a Java servlet filter is

  doFilter(req, resp, chain)
You could use that if it Is more suited to your style?


I'm pretty spoiled when it comes to ergonomics for libraries I choose to use, and java servlet-based libraries don't do it for me these days.

Last I touched java, Jersey was really exciting to me (https://jersey.github.io/) -- netty + good annotations/flask-like syntax + access to the beast that is the JVM is everywhere I want to be. Jersey doens't necessary force you into the servlet pattern IIRC?


No. "Make the easy things easy, make the hard things possible." Frameworks are usually good at making their target use case easy; they're worthless if they fail at this. The risk is when you need something outside the box, do you need to find a nicely wrapped framework widget to plug in, or can you easily wrap it yourself? Or is the abstraction light enough that you can easily drill through to the implementation layer?

It's about optimizing for the easiest case vs the harder cases in design. This is the design space that answers the question as to how serious the curve is. Serious curves require a leap in complexity, whereas other approaches can have more incremental increases.

Authentication was a fine example. The canonical example in my mind though is Visual Basic vs Delphi. VB (version 3 era, for Windows 3.11) required that you write your components in C++. You could use the framework in Basic but to customize it you needed a leap up a cliff in complexity. Whereas Delphi's VCL was written in Pascal just like your own code, the source shipped with the product, you could step through it, and you could even make a copy of the source and modify it as a step on the way towards writing your own component.


With PHP frameworks, I can monkey patch things by grabbing a text editor and just editing the functions I need fixed.

On the other end of the spectrum, looking at the Windows compile instructions for popular C++ products makes me reach for a bottle, of Advil or Absinthe.

Yes, I can customize any component assuming I have the source (and modification rights), but for some components, the customization comes naturally, with others, just getting a runnable binary is a whole-week ordeal.


Article is already a bit date because Spring 5 and Spring Boot 2 are both in GA now. A big new feature of Spring Boot is first-class support for Kotlin. Sprint Boot 2 + Kotlin is really a dream.


That's awesome! I experimented with server side kotlin some time ago and couldnt quite get things comfortably working (I had no previous JVM experience).

Do you know of any good intro materials?


Spring as a whole is pretty great, but due to its long history there's a lot of out of date information on the web out there, from the likes of mkyong and so on.

Not a problem with the framework per se, but it does add an extra layer of frustration when trying to search for an answer to your specific problem


Some stuff is out of date on best practices, but usually a lot is still supported, which is another reason Spring is popular, you can mostly follow the releases without much rework on code if at all.


Recently I wrote a service using embedded tomcat libraries. It contains few lines of code to boot up tomcat, add servlets, set some context parameters. There are no configuration files, no annotations or a readymade stack of libs that I must use. Now it works fine but no hope of going in production because it does not use the next generation state of the art Spring boot microservices framework as recommended by architecture group.

I guess point here is unless code is smothered with multiple layers of frameworks companies will not like it.


> because it does not use the next generation state of the art Spring boot microservices framework as recommended by architecture group.

Well... how closely are they looking? Not even joking here, although it's kind of funny in a sad way. I've had clueless "enterprise architecture" groups demand that I use some pointless framework or other - some EAI or ESB or ORM or something else that 100% gets in the way and 0% enhances productivity. So what I do is, I declare a dependency on the framework, use just enough of it so they can't say I'm _not_ using it, and then go ahead and write the damned code so that it works and avoids the pointless "framework" they're cramming down my throat.


FWIW this is just the way life is in large companies: you have to trade-off individuality vs. company-wide productivity.

Granted, both extremes are bad, and finding a happy medium is hard.

Hopefully the architecture group's "recommended"/mandated stack also includes great out-of-the-box, company-wide tooling like metrics, error logging, etc., etc.

If their solution doesn't provide these perks, well, yes, that's not as useful.


> Hopefully the architecture group's "recommended"/mandated stack also includes great out-of-the-box, company-wide tooling like metrics, error logging, etc., etc.

Mostly they jump on hype train. Few months back it was netflix stack now it seems they are moving to something else. My main work is on a large(ish) application which is in production long before merger. So for now I am not forced on to jump on their architectural astronautery. I just play around with other technologies etc.


Then you should be able to rewrite that into a spring boot application in a day at most and the company gets the advantage of a more homogeneous software stack that can be more easily be extended with metrics or whatever.


It contains few lines of code to boot up tomcat, add servlets, set some context parameters.

I've done this with Jetty, and sure the first few handlers/servlets are dead simple. But when it starts to grow, manually coding these things becomes unruly quickly. As the other commentor says, converting this to Spring Boot should be easy, and a good learning exercise.


IMO Springs killer feature is the AOP transaction manager. It lets the dev team forget about it completely and only focus on transaction details for corner cases when the default rollback on exceptions mechanism is not desired.


I'm a big fan of SpringBoot and have been using it since the beta version. For enterprise environments that often involve things like security, ActiveDirectory/LDAP integrations, SSO tokens, SOAP/XML, OWASP filters, CSRF tokens, custom logging, audit trails, etc, SpringBoot provides good plugins.

But if I'm doing a new greenfield project, I would rather prefer serverless architectures with light weight libraries and no frameworks (and perhaps golang). Yes, the serverless still lacks proper tooling and has few gotchas like no resource/connection pooling, cold starts, etc.. but the pros far out-weigh the cons. I'm still highly productive with springboot, but I am willing to discard my favorite tool and as I clearly see serverless stack as the next evolutionary step for application development.


As it so happens, a lot of Spring team members are working on Project Riff, which is a FaaS system.


I see CDI as all the good experiences learned in Spring, rolled up and distilled. Spring was my first though, and it's extensibility had withstood the test of time.


Not sure if serious or trolling.

1. CDI has no testing story, this is the biggest point, everything else pales to this. Arquilian is a joke compared to Spring TestContext Framework and strictly speaking not part of CDI.

2. CDI is in general lacking what Spring calls "enterprise integration", convenience layers over a lot of the a bit annoying to use Java EE layers like JDBC.

3. CDI is in general hampered by the Java EE / JCP release model. Spring can in general and does roll out new features quickly. For example we got new functionality into 5.0.4 within a few weeks without having to wait three years for a specification to be perfect and another three years for a supported application server to ship.

4. CDI/Java EE has still no caching story, even in 2018.

5. CDI has no MVC story.


4. JCache (jsr107) is really awful. I don't think you want one.


I was not particularly asking for JCache/JSR-107. Since you seem to have insight in this area would you mind sharing it? Is your beef with the API or the RI?


The API, though I am not a fan of the RI for one reason. It is the first JSR RI that I am aware of where the authors advice against using, it is unsupported, and intentionally low quality. All other RIs that I know of were production grade quality to ensure it met user's needs. This one was to pass a specification requirement.

- The API violates many of Josh Bloch's guidances [1], including items in Effective Java.

- Many of its features are incompatible with itself. For example, the AOP support cannot be used with loaders, writers, or listeners.

- The AOP support does not support atomic memoization (dog piling [2]) and can crash if initializing the same cache concurrently.

- The JavaDoc dictates implementation details that matched the lead's product, rather than being open ended to allow alternative algorithmic choices.

- The JSR defines an configuration API that is not suitable for production use and promotes the silent usage of unbounded anonymous caches.

- The interfaces do not attempt to feel natural alongside the Java's Collection Framework nor the direction that the language has been heading. It redefines terms, like "access", in an incompatible way.

- Despite numerous delays in being accepted, the JSR was not modified to take advantage of significant changes in the language (java.time, lambdas, CompletableFuture, etc).

- The TCK is not robust, does not check concurrency, and bugs in it languished.

- Most importantly, writing code using JCache is not enjoyable and it is often not flexible enough to solve most needs.

There are likely many more, but that is a short list that comes to mind in a few minutes.

[1] https://www.infoq.com/articles/API-Design-Joshua-Bloch

[2] https://en.wikipedia.org/wiki/Cache_stampede


Thank you for sharing.


I should have mentioned that the API flaws breaking with Bloch's advice can be really nasty. I bundled up a bunch of items under that, which might mundane if you don't know of them. Some of the wonderful design choices are,

- Cache.iterator() may return a null entry, despite null key or value is disallowed. This occurs when the cursor points to an entry that no longer exists - hasNext() was true, but the entry disappeared due to removal/eviction/expiration. This is a performance optimization to avoid underlying I/O that leaks to users and violates their assumptions.

- Cache.putAll(map) first invokes CacheWriter.writeAll(list<entry>) prior to storing them. The writer uses an in/out parameter so that if an exception is thrown, the user must remove the successfully written entries first. Then cache must store those successfully written entries before propagating the exception to the caller.

- An amusing bug was that their custom future could not be consumed by multiple threads. It used notify(), not notifyAll(), so only one waiter would wake up. The concerning part was that this existed for a few years due to lack interest in releasing a new version.


I've been using Spring and now Spring Boot for years. I'll I say is thank God for Maven heh


We used spring boot heavily at my last job. It was very fast to stand up services and it led us to move away from a massive monolithic weblogic stack.. changes were pushed out so much faster...


Why do or don't people like IoC?


Personally, when I build something, I prefer to know exactly what will happen prior to compile/build, not hope some configuration will handle things.

I can deal with both, but just a preference.

In general, dynamic integrations like IoC, etc make things harder to troubleshoot/debug as well.


I agree. That is why I prefer to use compile time dependency injection like Macwire[1] or Dagger 2[2]. At least in the case of Macwire, it is super simple to reason about at compile time.

[1] https://github.com/adamw/macwire

[2] https://google.github.io/dagger/


Exactly, right? That's what DI/IOC allows you to do. You can test a component where the variables always return simple deterministic results for one unit of code, or/[preferably] and you can also have a set of tests where you integrate all components.


I think he's talking about autowiring.


Exactly, and a lot of Spring discussions conflate the things and blurry the image a lot.

Inversion of Control is really good and there are no reasons not to use it. When you have something that can be done in multiple ways, make a small interface and several implementations for it.

The trick now is how to decide what to use. The simplest way is just to parse your configuration file or application flags/arguments in main and instantiate the concrete implementation of your classes there, then pass them down all the way until you need them. This is explicit, simple and clean.

Spring makes you (at least) do two things wrong:

1. Configure the concrete implementations the wrong way. You don't want your users to decide which class implements a certain interface. You want them to decide something higher level, like for example "get crash data via e-mail" or "get crash data in logs". The rest is implementation details.

2. Annotations for autowiring: my feeling is that those are just to go around Java verboseness. Instead of typing "VeryLongName veryLongName = new VeryLongName()", "@autowire" it easier to type. I have always seen it misused (used for stuff that is not Inverted/Configurable) and it makes code more magic. Even worse, you are back at having classes pick their dependencies, even if they are interface implementations. If your classes take their dependencies as constructor parameters, everything is much more explicit.


> If your classes take their dependencies as constructor parameters, everything is much more explicit.

This is the guidance that Spring team members give, to the point that Spring now defaults to injecting constructors without annotations.

I agree that field/setter autowiring is Satan's handicraft.

Not all of this is Spring's fault. Java has the JavaBeans standard, which created a universe in which setter injection is common. JPA, for example, requires no-arg constructors. It makes me sad.


Injecting your own dependencies makes lots of sense for some use-cases. For example, you'd probably wanna make it such that your network adapter can be swapped out in order to support different transports. By allowing it to get swapped out you also make it easier to test your code, since you can then use a fake network adapter to replicate any kind of scenario you wish to test.

The problem with the cult of DI fanatics is that they can sometimes take it too far. Sometimes code is tightly coupled to the implementation by necessity, and it doesn't add any value to have additional layers of misdirection. Although I'll admit that this is a bit of a strawman, since IoC can be summed up as "give things what they need", which is generally a sensible approach.


When all your modules' dependencies are injected as constructor parameters, it's straightforward to mock those dependencies when TDD'ing the module. Constructor parameter injection is really vital to isolate the SUT (system under test) when writing your tests. Any other type of injection is magical, and should be avoided.

At test-runtime, one will pass mock objects to the SUT's constructor using the new keyword. These mock objects are used to rig up specific preconditions that drive the scenario to be tested. Mocks can also be used to assert that the SUT called the dependency as expected with parameters.

At runtime, the IoC container handles instantiation of the module and injects the dependencies as appropriate constructor params.

I assume you asked this because Spring Framework is the poster child of dependency injection and IoC in the Java world. With all the Aspect-Oriented Programming and proxification and scope twizzling that occasionally blooms in the Spring ecosystem that is all wired-up using Spring DI, I think Spring sometimes gets a bad rep. Only abusers of those features get bad reps with me. Spring as a whole is a trove of nicely built systems with lots of classy 3rd party integrations. I personally prefer using Google Guice for DI because it is a standalone system, it eschews doing classpath scanning to identify injectable classes which I think makes it faster especially at startup, and it has decent integrations with 3rd party libraries.


FWIW, the Spring team fairly emphatically advise against anything but constructor injection[0], to the point that a major feature of Spring Framework 5 was to rework the code to be exclusively constructor injected[1].

[0] http://olivergierke.de/2013/11/why-field-injection-is-evil/

[1] https://github.com/spring-projects/spring-framework/wiki/Wha...


A reason to like it is that in a system with DI and IoC you spend less time trying to build up objects and pass them to where they need to go, since it's simple to just inject them into the class you want using an annotation. Spring takes care of the object creation under the hood for you. A reason not to like IoC is that since it's so easy to use it can lead to sloppiness since you're not thinking about the overall structure of the application as much.


This explanation always messes with me... Why are you trying to build up objects and pass them into places? (er, sorry, I don't mean you of course, I just mean in general) When / why is that ever a thing that someone needs to do so often that it becomes a concern? How come I rarely if ever see this in the e.g. python or C++ world? I get the idea of decoupling component implementations from their host objects but I just can't see most use cases needing that level of generality. Especially when it comes at the price of smearing a big and complicated IoC framework all over your code.

Past a threshold of codebase size and complexity, I see the value of course, but IoC frameworks get pitched too often as a thing that everyone should be using IMHO. Even for testing we already have mocking tools that handle replacing component objects with mocked versions just fine, and we don't need IoC tools for that.


> Why are you trying to build up objects and pass them into places?

Well, that place needs those objects to do its job.

> When / why is that ever a thing that someone needs to do so often that it becomes a concern?

In web applications, at least, you find yourself with a few controllers, which all need a few services which all need a few repositories to access the database... I guess you can see where this is going. Declaring in your class' constructor that instances need an object of `Type` is the less repetitive way of saying that an instance of a class needs something. Writing the code that builds objects and passes them to your constructors would be quite repetitive.


If you ever see someone implement the command pattern, you'll see passing objects.


> Why are you trying to build up objects and pass them into places?

Maybe something like the mediator pattern? There's definitely use cases for it, but I think a lot of the time the cure isn't any better than the disease.


With DI, that one big messy application root object that every codebase seems to naturally gravitate to becomes a generic, clean, reusable mechanism you did not write yourself. (Unless you put another big messy application root object on top of your DI, which I suppose is a learning experience I am not alone with)


People like it because it lets you unit test in Java. Most of the time IoC involves an interface with a single implementation and there will never be a 2nd.

Note that DI is just a form of IoC and both are separate from Spring. You can "manually" do DI by passing objects to constructors yourself. Some people have a complex web of dependencies and Spring can help make this manageable. Other people don't but have a hatred for passing arguments to constructors.


If you do it right, it makes writing automated unit tests (like JUnit) if not easy, at least possible. If you have a Java class whose constructor instantiates a JDBC connection to a database, you can't write a unit test for that class without having a live database instance for it to connect to. If you have a method call that includes a HTTP invocation to an external REST endpoint, you can't unit test that unless the REST endpoint is up, running and accessible. If you have a function that deletes rows from a database, you can't test it unless the database is not only available, but has the rows that the function is expecting to delete. IoC, if practiced correctly and usefully, "inverts" those parts so that they can be stubbed/mocked out by the unit testing framework. You can also make the case that, practiced correctly, IoC makes it more likely that the code you wrote can be applied to a different, but similar problems (although in my experience this is more theoretical than practical, since "the business" usually asks for things that don't fit into such nice, neat little boxes). The _problem_ with IoC is when it becomes a religion rather than a testability practice. If you're spending extra time doing something, it should at least be worth the time spent on it.


The major advantage IoC provides is decoupling of components. Components do not instantiate their dependencies and therefore are not coupled to specific dependency implementations. Any dependency that satisfies the interface the component expects can be injected.

This is especially useful when implementing tests because it is easy to inject mock implementations of dependencies.


You have it a bit backward IMO. Java (specifically) unit tests normally require that you indirect your dependent code through an object reference in order to mock the implementation, thus creating a composition problem. Unit testing in Java turns a control flow problem into a data flow problem. You then need help in getting all the data to the right places, a problem that unit testing created. IoC containers are a solution to this problem; they then move part of the implementation of your program into your config, or embed it implicitly in constraints in how things are composed. This is usually not an improvement in ease of understanding or navigating a project, since it optimizes for changing it.

Personally I'm deeply suspicious of mocking as an approach to testing code. I much prefer a functional approach with explicit data flow between parts of the system, rather than indirecting control flow through vtables using complex ad-hoc protocols that become part of your specification by getting baked into mocks in tests. IoC and mocking promotes dataless Verber, Doer and Handler classes that have no real place in an OO model of a system.

We shouldn't forget that decoupling isn't good for its own sake. Things that change together are already coupled; decoupling them at the implementation level is usually an obstacle in every way, whether to understanding, effort, performance, whatever. Abstraction use vs programmer experience generally follows a hump shaped curve; beginners know nothing, intermediates abstract everything, while experts use fewer more powerful, more composable abstractions and code more directly elsewhere. Mocking IMO optimizes for the middle case of too many non-reusable abstractions.


Part of the problem is Java environment itself, other platforms allows exporting single instances (import an actual singleton), so there is not so much need for DI

Also, you don't need to swap everything, your application (in fact) has hard dependencies. And mocking everything is not always the best way to test system (sometimes it's totally okay to mock the whole db)


Simple - sometimes you don't need IoC.

Also, Java is statically-typed language and DIC are a way to do more dynamic stuff (@Transactional proxies) - such things are possible without DI in some other languages.


Application consists of components. One component need to talk to another. You either use some kind of global repository or IoC. Repository is easier to use without framework, but with framework support IoC is as easy to use and provides better incapsulation, easier testing.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: