13 ms·
History of Spring Framework and Spring Boot
- chris_wot 9y agoWhy do or don't people like IoC?
- Cyclone_ 9y agoA 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.
- makmanalp 9y agoThis 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.
- _xgw 9y ago> 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.
- chris_wot 9y agoIf you ever see someone implement the command pattern, you'll see passing objects.
- tytytytytytytyt 9y ago> 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.
- usrusr 9y agoWith 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)
- jmspring 9y agoPersonally, 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.
- exabrial 9y agoExactly, 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.
- chris_wot 9y agoI think he's talking about autowiring.
- dullgiulio 9y agoExactly, 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.
- Chickenosaurus 9y agoThe 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.
- barrkel 9y agoYou 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.
- cztomsik 9y agoPart 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)
- TheAceOfHearts 9y agoInjecting 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.
- vbezhenar 9y agoApplication 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.
- EdSharkey 9y agoWhen 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.
- jacques_chester 9y agoFWIW, 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/ http://olivergierke.de/2013/11/why-field-injection-is-evil/ [1] https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-Spring-Framework-5.x#general-core-revision https://github.com/spring-projects/spring-framework/wiki/Wha...
- sbov 9y agoPeople 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.
- cztomsik 9y agoSimple - 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.
- commandlinefan 9y agoIf 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.
- royalghost 9y agoSpring 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.
- copperx 9y ago> 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).
- postcynical 9y agoI 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.
- jimmy1 9y agoWhen 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.
- slow_donkey 9y agoWould you use dw or spring boot now? Our current stack is dropwizard but I've never messed around with slring boot
- jimmy1 9y agoI 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.
- cs02rm0 9y agoAbsolutely. 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.
- bjslade 9y agoI 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?
- exabrial 9y agoI 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.
- needusername 9y agoNot 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.
- deleted 9y ago[deleted]
- NovaX 9y ago4. JCache (jsr107) is really awful. I don't think you want one.
- needusername 9y agoI 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?
- NovaX 9y agoThe 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 https://www.infoq.com/articles/API-Design-Joshua-Bloch [2] https://en.wikipedia.org/wiki/Cache_stampede https://en.wikipedia.org/wiki/Cache_stampede
- tootie 9y agoArticle 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.
- rattray 9y agoThat'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?
- JTenerife 9y agoSpring 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.
- viach 9y ago> However, you have to be prepared for a serious learning curve when needing customizing Can be said about everything in this world, right?
- hardwaresofton 9y agoYes 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.
- w4tson 9y agoThe contract of a Java servlet filter is doFilter(req, resp, chain) You could use that if it Is more suited to your style?
- dlhavema 9y agoWe 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...
- pritambarhate 9y agoThe 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.
- djhworld 9y agoIn my experience Spring Boot apps tend to start in around 5-7 seconds. It all depends on what your init logic is I guess.
- nikanj 9y agoDuring 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.
- eeperson 9y agoThis 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 https://github.com/adamw/macwire [2] https://google.github.io/dagger/ https://google.github.io/dagger/
- jacques_chester 9y ago> 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 https://github.com/dsyer/spring-boot-startup-bench Disclosure: I work for Pivotal, we sponsor Spring development. I do not work on Spring.
- djhworld 9y agoSpring 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
- gldalmaso 9y agoSome 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.
- chasd00 9y agoI've been using Spring and now Spring Boot for years. I'll I say is thank God for Maven heh
- geodel 9y agoRecently 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.
- cc81 9y agoThen 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.
- stephen 9y agoFWIW 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.
- geodel 9y ago> 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.
- gldalmaso 9y agoIMO 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.
- guru4consulting 9y agoI'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.
- jacques_chester 9y agoAs it so happens, a lot of Spring team members are working on Project Riff, which is a FaaS system.