I use spring in large scale Java projects but I rarely take advantage of the @Autowired feature because I find it very confusing as I define my pojos in XML configuration files. if I have autowired fields all over the place I have to look at source code AND XML files to understand what the heck is going on and from where a given field is autowired.
I suspect this introduces extra complexity. I have not yet had the chance to try Guice (https://code.google.com/p/google-guice/) so I wonder if it solves many of Spring's problems (one of the top issues is verbosity of configuration files).
From Spring 3 (3.1 I think it was) you don't need to do configuration with XML. Current version (Spring 4) even supports configuring Spring Security with no XML at all. You can configure everything in Java and use profiles (@Profile) when you have multiple configuration scenarios. http://spring.io/blog/2011/02/14/spring-3-1-m1-introducing-p...
Also, don't forget that you can use @Resource (jsr250), not only @Autowired.
The author also says:
> So reuse and decoupling are opposing forces. I find myself siding with decoupling.
The developer has to make a balance between reuse and decoupling. In my opinion everything doesn't have to be 100% reused or decoupled.
Auto wiring is great for test code. Most of you need to know about the test is contained in the testing class.
But I don't like using auto wired in the main code because it means I am required to use that wiring for every use. I find that we want to use classes in a few different ways, and keeping the dependency definitions and configuration values in the XML decouples it from the code and increases both reusability as well as exposing the XML configurations after deployment so that a recompile isn't required in the field.
Different DB drivers and connection pool setups for example.
Taken to extremes I've also used Spring to configure a rudimentary ETL framework for example, where the entire pipeline could be (re-)configured post release.
But why would you want to mix your config and code? When does it make sense to lock these values at compile time, but also use an abstraction layer which suggests these values are configured at runtime?
You can still have .property files for the values of the configuration fields (e.g. API keys), and you can say with which profile (by configuring with @Profile in Spring) the application to start. With that you are still able to separate the actual configuration. As I see it, the point is not to clutter yourself with beans in xml files.
There's no sense at all in putting configuration of DI separately from the code. Normally, 99% of DI configs are not environment-specific (if this is not the case, "Houston, we have a problem"). In most cases you ship your software not like IKEA, but like Boeing - already assembled and ready for use. The customer (possibly, internal one) has to fill the fridge with meals for passengers and tanks with fuel, not to assemble the engines or avionics.
Wiring objects together and configuring applications are tangentially related. Both can be done in Spring config, both can be done without Spring config, both can be done at compile or runtime.
Dependency glue (wiring) in runtime config helps keep objects decoupled, makes test writing easier, and eliminates any dependency on a specific IOC framework. Whether or not the wiring config comes boxed with the code or not is a completely different concern.
I prefer to configure in code because that way I can reason about it in the normal way I reason about code, or I can use code to solve problems in the usual way. E.g. I can "find usages" on a constructor and expect to find where the object is constructed. If there's some common aspect to the construction of several different objects, I can factor that out into a helper method, the same way I would with any other piece of code.
I consider @Autowired and bean config in code as harmful. It also seems like one of the main things Spring was all about n the beginning - decoupling your application from the configuration framework - is now come full circle to tight coupling with Spring. Not only that, but code which references config files for one spaghetti mess of code and config that is a pain to test. More and more I run into library packages with direct dependencies on Spring config - and it makes integration painful.
I'd be happy to see Spring config in a format other than XML (JSON, YAML, whatever), but even more than that, a complete elimination of any Spring config directly in Java files.
Well, you can already do java based config, which is not the same as annotation based config. As with XML config, Java based config lives outside of your application code in classes dedicated to configuration. You just use Java instead of XML, which makes things much nicer.
Is there any good, recent ( but past the beta stage), fast, non bloated java framework anyone here could recommend ?
I've done a medium sized spring project last year, and found the language quite good, but the framework itself and the general ecosystem really too cumbersome.
As most of my daily tasks are being done in J2EE environment, I have goosebumps each time I hear "java" & "framework" used in one sentence. And that's not excitement, that's fear.
The only framework which I can recommend, is Dropwizard (http://dropwizard.codahale.com/), which tries not to be a framework, just a glue between some really nice libraries and tools.
Really helpful comment, thanks. I probably overestimated the importance of a "framework" in the java world, where everything is standardized, and every standard is implemented through standalone libraries (which is probably another reason spring became so famous when i come to think of it, with its original glue-like approach).
I'll start with "raw" java next time i'll want to try playing with rest services.
Is there any good, recent ( but past the beta stage), fast, non bloated java framework anyone here could recommend ?
For? If you are developing REST applications, the JAX-RS standard is great, lightweight, and mature. I have used both Jersey and RestEasy without any problems.
Take a look at http://vertx.io/ . It's basically the Java community's answer to modern, fast, straight forward technologies like NodeJS. Just by the performance improvements alone I've been hearing people tout you can often justify it in big business jobs.
I am the founder of Crudzilla Software (check my profile for link).
Our product is a browser based web development tool that comes with its own middleware/framework with a UI built just for it.
I think this approach while not as generic is superior because you get the benefit of real tooling not just a generic framework that you need to manually glue together.
Spring like many frameworks are designed to be generic and pluggable into other tools/IDEs, unfortunately once they become complex their benefit is greatly reduced for most projects.
Support us so we can continue to improve on the product, visual UI building and integration is on the horizon :)
How about Google Guice? I can't recommend it because I personally haven't used it, but I was under the impression that it is supposed to be the answer to this.
If it isn't what you're looking for, I'd be curious to hear which of these qualifications it fails at.
Go for Guice if you just want DI. You won't regret it. But always remember, all "auto" stuff might mislead you. For example, you need somebody to start things for you, so in Spring, the Servlet container will invoke the Spring Servlet, which will take things up from there. That's the catch, it's not magic, right? So with Guice, you need to figure out who will so that "auto" for you. Btw, if you're just building a small library, Guice is definitely the DI choice. HTH.
From the article, the author clearly states he has issues with the DI-driven design in general; Spring just happened to be the DI framework he was using at the time. Guice or any other framework for that matter would not have made any difference.
Money quotes:
>>>> In the end, creating a coherent, small system is to me of much higher value than to create one that is decoupled just for the sake of decoupling. Coherence and decoupling are opposing forces and I side with coherence.
>>>> So reuse and decoupling are opposing forces. I find myself siding with decoupling.
If it's a library, not an app, it's better not to rely on DI at all, leaving the choice of container to user. As a library designer you can implement reasonable manual auto-wiring of default configuration.
For small applications (both server-side and client-side) Spring 4 is as easy to use as Guice.
This post is too abstract and neither offers a good explanation of a problem nor suggests an alternative solution.
The task of dependency injection appears right after the decomposition of a problem: you cannot avoid it, so you either do it manually by constructing and wiring all necessary objects (self-managed singleton anti-pattern is quite common here, let his fathers burn in hell) or using a DI container. Unless you want to invent your own bicycle with poker and curvy girls (which may make sense in very specific cases, but not in general), you will use Spring, Guice or CDI.
How to choose the right solution? It always depends on requirements, not on generic concepts from theory of OOD. In small project you can follow KISS principle by sacrificing decoupling and wiring objects manually. In bigger one you always need to look at the other libraries and environment you are going to use. If it's a JEE container (a modern one, compatible with latest specs), your choice can be CDI. If you are going to work with GWT, it's Guice (it's the best for programmatic configuration, but lacks some features). In all other cases Spring 4 is the best option.
What's wrong with the talk about reuse vs decoupling? The author addresses the problem of sustainability of a system to changes by rejecting the core concept of OOD - the reuse - and avoiding the use of DI, just to avoid some hypothetic bug in implementation module. However, our industry developed a lot of tools and best practices to address such problems when writing reusable code: unit tests, SOLID (SRP is my favorite one), incremental compilers and smart IDEs. Avoiding reuse is like not using electricity if you afraid of fire.
This was an excellent post, it was abstract but at least he kept it short.
I had an argument about DI with a friend months ago and it boiled down in his use (Guice) that it was only for testing components.
I think of DI as a big meta-constructor in the sky, it gives dynamic scope to a lexically scoped language. And the problem with it as we currently use it, is that it hides intent behind a config file so we can't read what the code is actually doing, only doing abstractly.
What if the tooling ghosted those abstract classes and put the concrete classes in their place with reading and navigating? It could effectively "statically link" in the IDE those dependencies.
In good design the intent is clearly defined in interface on which you depend. If the code has side effects, if it does something not specified by interface, if it has more than one role, this code needs to be fixed and it is not a problem with DI. It's a problem with your design.
As I already said, you always need to wire your objects. You do it, possibly, without realizing it, but you still do it. If you reject the idea of DI just because the code is bad and DI is "Not Invented Here", you will not do the wiring better. Writting custom DI is hard, and it's very likely that you will end with unmaintainable nightmare that needs to be rewritten completely. For 15 years I've seen this nightmare too much and never seen the successful projects with custom DI.
For enterprise software, for large projects, probably, yes. Together with more advanced reflection (I imagine MOF/EMF as a native part of Java) to allow meta-programming and smarter code generation.
My tools already do that. With IntelliJ and its Spring support I can easily jump directly to the actual implementation that is being wired in, just as easily as I would jump to source if it was a concrete class. But in a properly designed system I rarely need to go poking into the implementations of my dependencies.
I found Scala lazy initialization to be great alternative to Spring IoC. Also constructor arguments are part of class definition and it makes constructor injection very easy.
This post is awesome and correctly describes that frameworks try to teach you certain methodologies by enforcing them. Once you understand the principles, you're often better of ditching the framework.
This is especially true with DI, which is a design principle and not a framework, countrary to popular belief.
I would also like to add that specific technologies such as xml are not inherently declarative. If some api or config is declarative it only means that it is well designed and that it's easy to express your intentions when using it. If you want counter-examples, look at imperative ant or declarative jmock.
XSLT's a better example of XML not being declarative, as it's a turing-complete pure functional programing language. There's also some toy languages actually intended to be full programming languages that happen to use XML as their syntax.
Welcome to the club:) But you should be careful being too open about it. I didn't last 15 min in my last interview, when I told them that I didn't use database in my latest project, since all data (the whole 200 rows) did fit in one json file. Haven't passed the "Technology Stack" qualification.
And indeed, code without frameworks is so much smaller, cleaner and pleasant to work with!
One thing that drove me nuts about programming with Spring (.NET, in my case) was that it was so hard to follow the flow. So much flipping back and forth between the config and the code. Also, the error messages for misconfigured applications were frequently inscrutable. This was addressed to some extent with a build phase that verifies the type names in Spring configs. Lastly, more than once we were bit by defaults, where an object that should have been a singleton wasn't, or the reverse. Lots of power to shoot your foot off.
I'm not sure I understand the point about reuse and decoupling being opposing forces.
A simplistic example that comes to mind is a calculator module with a well-defined interface (interface in the Java sense of the term). Maybe there are a few different implementations of the interface available in the codebase.
Both implementations are reusable in the sense that I can plug one implementation in many places wherever the interface is supported. When I need something else, I plug in a different implementation. The module that has a dependency on the calculator module should be none the wiser since all it does is call out to a certain interface.
Am I missing something here? Maybe I didn't understand the OP's point well enough.
What you're talking about is decoupling interface from implementation. This is good (well, it's good if there is a genuine need for more than one implementation, otherwise it's just decoupling for the sake of decoupling which is a form of waste. Remember YAGNI)
My understanding of reuse is when the same peace of code is used in different areas of the project. This could be different classes, different packages, different modules, etc. Now the more the code is reused, the more tight coupling between the two pieces of code i.e. change to the interface of the reused code 'could' mean change(s) to each and every place the reused code is being called.
Secondly, if you put reuse high up in the design requirement, what you sometimes end up with are very generic interfaces/classes that can be reused in lots of places as opposed to very specific interfaces/classes or unnecessary inheritence trees required to change the base class behaviour in those places where the required behaviour is 'slightly different'.
Lastly, not so long ago, DI containers did not support package private visibility. This means all injection (constructor, setter, etc.) required public visibility. This lead to a lot of developers also 'reusing' code even in places where they shouldn't just because they could i.e. it's right there!
47 comments
[ 4.0 ms ] story [ 60.2 ms ] threadI suspect this introduces extra complexity. I have not yet had the chance to try Guice (https://code.google.com/p/google-guice/) so I wonder if it solves many of Spring's problems (one of the top issues is verbosity of configuration files).
Also, don't forget that you can use @Resource (jsr250), not only @Autowired.
The author also says:
> So reuse and decoupling are opposing forces. I find myself siding with decoupling.
The developer has to make a balance between reuse and decoupling. In my opinion everything doesn't have to be 100% reused or decoupled.
But I don't like using auto wired in the main code because it means I am required to use that wiring for every use. I find that we want to use classes in a few different ways, and keeping the dependency definitions and configuration values in the XML decouples it from the code and increases both reusability as well as exposing the XML configurations after deployment so that a recompile isn't required in the field.
Taken to extremes I've also used Spring to configure a rudimentary ETL framework for example, where the entire pipeline could be (re-)configured post release.
Dependency glue (wiring) in runtime config helps keep objects decoupled, makes test writing easier, and eliminates any dependency on a specific IOC framework. Whether or not the wiring config comes boxed with the code or not is a completely different concern.
I'd be happy to see Spring config in a format other than XML (JSON, YAML, whatever), but even more than that, a complete elimination of any Spring config directly in Java files.
See here: http://docs.spring.io/spring/docs/3.2.7.BUILD-SNAPSHOT/sprin...
I've done a medium sized spring project last year, and found the language quite good, but the framework itself and the general ecosystem really too cumbersome.
The only framework which I can recommend, is Dropwizard (http://dropwizard.codahale.com/), which tries not to be a framework, just a glue between some really nice libraries and tools.
I'll start with "raw" java next time i'll want to try playing with rest services.
For? If you are developing REST applications, the JAX-RS standard is great, lightweight, and mature. I have used both Jersey and RestEasy without any problems.
Our product is a browser based web development tool that comes with its own middleware/framework with a UI built just for it. I think this approach while not as generic is superior because you get the benefit of real tooling not just a generic framework that you need to manually glue together.
Spring like many frameworks are designed to be generic and pluggable into other tools/IDEs, unfortunately once they become complex their benefit is greatly reduced for most projects.
Support us so we can continue to improve on the product, visual UI building and integration is on the horizon :)
If it isn't what you're looking for, I'd be curious to hear which of these qualifications it fails at.
Money quotes:
>>>> In the end, creating a coherent, small system is to me of much higher value than to create one that is decoupled just for the sake of decoupling. Coherence and decoupling are opposing forces and I side with coherence.
>>>> So reuse and decoupling are opposing forces. I find myself siding with decoupling.
For small applications (both server-side and client-side) Spring 4 is as easy to use as Guice.
Pretty similar to Guice, but faster.
The task of dependency injection appears right after the decomposition of a problem: you cannot avoid it, so you either do it manually by constructing and wiring all necessary objects (self-managed singleton anti-pattern is quite common here, let his fathers burn in hell) or using a DI container. Unless you want to invent your own bicycle with poker and curvy girls (which may make sense in very specific cases, but not in general), you will use Spring, Guice or CDI.
How to choose the right solution? It always depends on requirements, not on generic concepts from theory of OOD. In small project you can follow KISS principle by sacrificing decoupling and wiring objects manually. In bigger one you always need to look at the other libraries and environment you are going to use. If it's a JEE container (a modern one, compatible with latest specs), your choice can be CDI. If you are going to work with GWT, it's Guice (it's the best for programmatic configuration, but lacks some features). In all other cases Spring 4 is the best option.
What's wrong with the talk about reuse vs decoupling? The author addresses the problem of sustainability of a system to changes by rejecting the core concept of OOD - the reuse - and avoiding the use of DI, just to avoid some hypothetic bug in implementation module. However, our industry developed a lot of tools and best practices to address such problems when writing reusable code: unit tests, SOLID (SRP is my favorite one), incremental compilers and smart IDEs. Avoiding reuse is like not using electricity if you afraid of fire.
I had an argument about DI with a friend months ago and it boiled down in his use (Guice) that it was only for testing components.
I think of DI as a big meta-constructor in the sky, it gives dynamic scope to a lexically scoped language. And the problem with it as we currently use it, is that it hides intent behind a config file so we can't read what the code is actually doing, only doing abstractly.
What if the tooling ghosted those abstract classes and put the concrete classes in their place with reading and navigating? It could effectively "statically link" in the IDE those dependencies.
As I already said, you always need to wire your objects. You do it, possibly, without realizing it, but you still do it. If you reject the idea of DI just because the code is bad and DI is "Not Invented Here", you will not do the wiring better. Writting custom DI is hard, and it's very likely that you will end with unmaintainable nightmare that needs to be rewritten completely. For 15 years I've seen this nightmare too much and never seen the successful projects with custom DI.
Cost-benefit uber alles! All of these things -- features, functions, frameworks, objects, patterns -- must pay rent!
This is especially true with DI, which is a design principle and not a framework, countrary to popular belief.
I would also like to add that specific technologies such as xml are not inherently declarative. If some api or config is declarative it only means that it is well designed and that it's easy to express your intentions when using it. If you want counter-examples, look at imperative ant or declarative jmock.
And indeed, code without frameworks is so much smaller, cleaner and pleasant to work with!
A simplistic example that comes to mind is a calculator module with a well-defined interface (interface in the Java sense of the term). Maybe there are a few different implementations of the interface available in the codebase.
Both implementations are reusable in the sense that I can plug one implementation in many places wherever the interface is supported. When I need something else, I plug in a different implementation. The module that has a dependency on the calculator module should be none the wiser since all it does is call out to a certain interface.
Am I missing something here? Maybe I didn't understand the OP's point well enough.
My understanding of reuse is when the same peace of code is used in different areas of the project. This could be different classes, different packages, different modules, etc. Now the more the code is reused, the more tight coupling between the two pieces of code i.e. change to the interface of the reused code 'could' mean change(s) to each and every place the reused code is being called.
Secondly, if you put reuse high up in the design requirement, what you sometimes end up with are very generic interfaces/classes that can be reused in lots of places as opposed to very specific interfaces/classes or unnecessary inheritence trees required to change the base class behaviour in those places where the required behaviour is 'slightly different'.
Lastly, not so long ago, DI containers did not support package private visibility. This means all injection (constructor, setter, etc.) required public visibility. This lead to a lot of developers also 'reusing' code even in places where they shouldn't just because they could i.e. it's right there!