15

I love the concept of DI and loosely coupled system, a lot. However, I found tooling in Spring lacking at best. For example, it's hard to do "refactoring", e.g. to change a name of a bean declared in Spring. I'm new to Spring, so I would be missing something. There is no compiling time check etc.

My question is why do we want to use XML to store the configuration? IMO, the whole idea of Spring (IoC part) is to force certain creational pattern. In the world of gang-of-four patterns, design patterns are informative. Spring (and other DIs) on the other hand, provides very prescribed way how an application should be hooked up with individual components.

I have put Scala in the title as well as I'm learning it. How do you guys think to create a domain language (something like the actor library) for dependency ingestion. Writing the actual injection code in Scala itself, you get all the goodies and tooling that comes with it. Although application developers might as well bypass your framework, I would think it's relatively easy to standard, such as the main web site/app will only load components of certain pattern.

Xian Xu
  • 266
  • 3
  • 9
  • 1
    A couple quick thoughts: 1) XML is just the DSL Spring went with; if you prefer Java, try http://www.picocontainer.org. 2) You can always write simple "unit tests" of your Spring configurations, just to make sure the contexts are properly instantiated, without having to fire up your application – Rodney Gitzel Aug 13 '10 at 18:29

7 Answers7

4

There's a good article on using Scala together with Spring and Hibernate here.

About your question: you actually can use annotations. It has some advantages. XML, in turn, is good beacause you don't need to recompile files, that contain your injection configs.

George
  • 8,368
  • 12
  • 65
  • 106
  • 2
    Could you elaborate on scenarios where that actually helps? In my (limited) experience, after the software has been built the injection configuration files are really never changed. But probably you know examples where they are? Thanks! – MarnixKlooster ReinstateMonica Jun 24 '11 at 04:44
4

There is an ongoing debate if Scala needs DI. There are several ways to "do it yourself", but often this easy setup is sufficient:

//the class that needs injection
abstract class Foo {
  val injectMe:String
  def hello = println("Hello " + injectMe)
}

//The "binding module"
trait Binder {
  def createFooInstance:Foo
}

object BinderImpl extends Binder {
  trait FooInjector {
    val injectMe = "DI!"   
  }

  def createFooInstance:Foo = new Foo with FooInjector
}

//The client
val binder:Binder = getSomehowTheRightBinderImpl  //one way would be a ServiceLoader
val foo = binder.createFooInstance
foo.hello
//--> Hello DI!

For other versions, look here for example.

mmmmmm
  • 32,227
  • 27
  • 88
  • 117
Landei
  • 54,104
  • 13
  • 100
  • 195
  • 1
    You mean "if Scala needs Spring", not "if Scala needs DI"? And that "getSomehowTheRightBinderImpl" call implies SOME kind of dependency-building framework. – Rodney Gitzel Aug 13 '10 at 18:32
  • I mean "if Scala needs a DI framework", to be precise, and as I already commented "getSomehowTheRightBinderImpl" could be realized using a ServiceLoader, which is not "real" DI and already built in. Even a class name in a property file could be good enough. We're talking about the one and only place where DI is bootstrapped from, and if this is a little bit messy it's not too bad. You don't need a framework just for this if all other DI parts already work fine (which is the case when the language is powerful enough). – Landei Aug 13 '10 at 22:35
2

There are different approaches to DI in java, and not all of them are necessarily based on xml.

Spring

Spring provides a complete container implementation and integration with many services (transactions, jndi, persistence, datasources, mvc, scheduling,...) and can actually be better defined using java annotations.

Its popularity stems from the number of services that the platform integrates, other than DI (many people use it as an alternative to Java EE, which is actually following spring path starting from its 5 edition).

XML was the original choice for spring, because it was the de-facto java configuration standard when the framework came to be. Annotations is the popular choice right now.

As a personal aside, conceptually I'm not a huge fan of annotation-based DI, for me it creates a tight coupling of configuration and code, thus defeating the underlying original purpose of DI.

There are other DI implementation around that support alternative configuration declaration: AFAIK Google Guice is one of those allowing for programmatic configuration as well.


DI and Scala

There are alternative solutions for DI in scala, in addition to using the known java frameworks (which as far as I know integrate fairly well).

For me the most interesting that maintain a familiar approach to java is subcut.

It strikes a nice balance between google guice and one of the most well-known DI patterns allowed by the specific design of the scala language: the Cake Pattern. You can find many blog posts and videos about this pattern with a google search.

Another solution available in scala is using the Reader Monad, which is already an established pattern for dynamic configuration in Haskell and is explained fairly well in this video from NE Scala Symposium 2012 and in this video and related slides.

The latter choice goes with the warning that it involves a decent level of familiarity with the concept of Monads in general and in scala, and often aroused some debate around its conceptual complexity and practical usefulness. This related thread on the scala-debate ML can be quite useful to have a better grip on the subject.

Community
  • 1
  • 1
pagoda_5b
  • 7,333
  • 1
  • 27
  • 40
2

I love the concept of DI and loosely coupled system, a lot. However, I found tooling in Spring lacking at best. For example, it's hard to do "refactoring", e.g. to change a name of a bean declared in Spring. I'm new to Spring, so I would be missing something. There is no compiling time check etc.

You need a smarter IDE. IntelliJ from JetBrains allows refactoring, renaming, etc. with full knowledge of your Spring configuration and your classes.

My question is why do we want to use XML to store the configuration?

Why not? You have to put it somewhere. Now you have a choice: XML or annotations.

IMO, the whole idea of Spring (IoC part) is to force certain creational pattern. In the world of gang-of-four patterns, design patterns are informative.

ApplicationContext is nothing more than a big object factory/builder. That's a GoF pattern.

Spring (and other DIs) on the other hand, provides very prescribed way how an application should be hooked up with individual components.

GoF is even more prescriptive: You have to build it into objects or externalize it into configuration. Spring externalizes it.

I have put Scala in the title as well as I'm learning it. How do you guys think to create a domain language (something like the actor library) for dependency ingestion.

You must mean "injection".

Writing the actual injection code in Scala itself, you get all the goodies and tooling that comes with it.

Don't see what that will buy me over and above what Spring gives me now.

Although application developers might as well bypass your framework, I would think it's relatively easy to standard, such as the main web site/app will only load components of certain pattern.

Sorry, I'm not buying your idea. I'd rather use Spring.

But there's no reason why you shouldn't try it and see if you can become more successful than Spring. Let us know how you do.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • Thanks, I'll check IntelliJ's Spring refactoring support. The problem I'm having is that we have some in house extension to Spring, probably more along the line of OSGi component/packaging. In this internal paradigm, I need to wire properties among components. When you miss one wiring, no error at build time, but when the complex thing starts up, something will throw up somewhere. Diagnosing it is pretty hard. Actually just trying to figure out what is the missing property is hard. I ended up writing a tool, parsing through the spring and ant files to figure out what's missing. – Xian Xu Aug 12 '10 at 23:19
  • 1
    IntelliJ would have caught that. And if I have logging turned on, I usually get enough information where I don't have writing issues. – duffymo Aug 13 '10 at 00:27
0

I cannot agree that XML is problem in Java and Spring: I use Spring and Java extensively without to much XML because most configuration is done with annotations (type and name is powerful contract) - it looks really nice. Only for 10% cases I use XML because it is easier to do it in XML than code special solution with factories / new classes / annotations. This approach was inspired by Guice and Spring from 3.0 implements its as JSR-330 (but even that I use Spring 2.5 with spring factory configured with JSR-330 annotations instead of default spring-specific @Autowired).

Probably scala can provide better syntax for developing in DI style and I'm looking at it now (pointed Cake Pattern).

kodstark
  • 463
  • 4
  • 11
0

i can't really comment on scala, but DI helps enforce loose coupling. It makes refactoring large apps soooo much easier. If you don't like a component, just swap it out. Need another implementation for a particular environment, easy just plug in a new component.

clarson
  • 556
  • 2
  • 7
  • 15
0

I agree! To me he way most people use Spring is a mild version of hell.

When you look at the standard Springified code there are interfaces everywhere, and you never really know what class is used to implement an interface. You have to look into some fantastic configuration to find that out. Easy read = not. To make this code surfable you need a very advanced IDE, like Intelly J.

How did we end up in this mess? I blame automated unit testing! If you want to connect mocks to each and every class you can not have dependencies. If it wasn't for unit testing we could probable do just as well without loose coupling, since we do not want the customer to replace single classes willy nilly in our Jars.

In Scala you can use patterns, like the "Cake Patten" to implement DI without a framework. You can also use structural typing to do this. The result is still messy compared to the original code.

Personally I think one should consider doing automated testing on modules instead of classes to escape this mess, and use DI to decouple entire modules. This strategy is by definition not unit testing. I think most of the logic lies in the actual connections between classes, so IMHO one will benefit more from module testing than unit testing.

olle kullberg
  • 6,249
  • 2
  • 20
  • 31
  • 3
    "...you never really know what class is used to implement an interface..." - just look in the configuration. The whole point of designing to an interface is that clients don't have to know. – duffymo Aug 12 '10 at 21:21
  • 5
    @duffymo Yes, configuration configuration and once again configuration. Am I the only one totally tired of configuration? I do not object to interfaces, but I do object to interfaces everywhere. – olle kullberg Aug 13 '10 at 06:12
  • 1
    Not everywhere - if everything is an interface, you're doing it wrong. And if you're not expressing those things in configuration, then it's in code. What makes code less tiresome? You've gotta say it somewhere. – duffymo Aug 13 '10 at 09:21
  • At the beginning I was quite sceptical to using Spring annotaions but after some real world examples I am sold. Using Java interfaces + bean implementations and the default nameing convention the point about unbrowsable code becomes moot. Only limited configuration in the XML is necessary. Regarding Unit testing and interfaces, you don't always need to mock all dependencies and unit testing definitely help my productivity. However, in Scala I am still learning and has thus yet to form an opinion! – Christoffer Soop Sep 26 '11 at 06:32
  • @ChristofferSoop Hi old friend! The struggle is really about the definition of Unit Testing. The only definition I know of is that an object is a "unit" and should be "cut off" from the world to be tested as a unit. This requires a lot of mocking Im afraid. – olle kullberg Nov 17 '11 at 12:57