I'm comfortable programming in Java, but am fairly new to Spring. I've been reading about dependency-injection/inversion of control (and using it with Spring for the past few months), but I can't figure out the need for a separate language (xml/spring) to accomplish it.
What is wrong with creating a singleton in Java called DependencyHandler, and keeping everything in the same language? What are the advantages I get by using xml/Spring?
Dependency Injection does not require a separate language.
Spring is a framework for Java that historically required configuration in xml. Now you can configure it using xml, or java annotations.
Google's Guice is a simple dependency injection framework that has all configuration in Java.
There can be legitimate reasons why a custom language (in xml) can be better than Java for a specific purpose. For DI though, the reasons are stretchy, and in fact, not the real reasons.
From countless testimonies from happy Spring users, the overwhelming reason is that they somehow think xml is not code. They are so tired of writing boilerplate Java code, they are happy to switch to boilerplate xml. And that makes them happy.
Human beings are not rational when it comes to economic matters. We have elaborate systems that transfer resources in circles, finding comfort and security in such pointless waste of efforts.
But I guess happiness is the most important thing, however retarded it could be.
You can make dependency injection frameworks that use Java syntax, too. Just look at Google Guice, for example.
I'll answer the "benefits" part for XML specifically, although there aren't many.
Having configuration completely separate from code removes all framework artifacts from the source, which can be beneficial.
It's easier (not ridiculously so, but enough to be noteworthy) to create toolchains that affect configuration files: property loading/replacement, config-aware GUI config editors, documentation generation, etc.
Centralized configuration; instead of config being strewn around the codebase, it's in a group of files (or single file). This isn't an XML-only vitrue, it depends on how things are configured.
I think some types of configuration lend themselves to external configuration more than others. I choose based on what seems appropriate given the reqs, what the framework allows, and how the framework handles config aspects.
Spring is just an easy way to manage dependency injection in large projects.
But you can inject dependencies by using a static factory method on your class:
public class Foo
{
public Foo static mkFoo(/* dependencies */)
{
// assign dependencies to members
}
// ordinary class stuff
}
Then you just do Foo.mkFoo(/*dependencies*/) whenever you want a Foo. No spring required.
What is wrong with creating a singleton in Java called DependencyHandler, and keeping everything in the same language?
Handling all your dependencies in a single class is going to get messy quickly, and will result in coupling with all of your other classes. But that isn't a reason to not handle DI in plain java.
Related
I think my understanding of spring beans is a bit off.
I was working on my project and I was thinking about this situation.
Say I have class Foo
class Foo(){
public void doSomething(Object a , Object b){ // input parameters does not matter actually.
//do something
}
}
If I am using this class in another class like :
class Scheduler{
....
#Autowired
private Foo foo;
someMethod(){
foo.doSomeThind(a,b);
}
....
}
In the above case Instead of Autowiring the Foo, I can make doSomeThing static and directly use Foo.doSomeThing(a,b)
I was just wondering if there any advantage of creating a bean or if there any disadvantage of using static methods like this?
If they are same, When should I go for spring bean and when should do I simply use a static method?
Static methods are ok for small utility functions. The limitation of static code is that you can't change it's behavior without changing code itself.
Spring, on the other hand, gives you flexibility.
IoC. Your classes don't know about the exact implementation of their dependencies, they just rely on the API defined by interface. All connections are specified in configuration, that can be different for production/test/other.
Power of metaprogramming. You can change the behavior of your methods by merely marking them (via annotations of in xml). Thus, you can wrap method in transactions, make it asynchronous or scheduled, add custom AOP interceptors, etc.
Spring can instrument your POJO method to make it an endpoint to remote web service/RPC.
http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/
Methods in Spring beans can benefit from dependency injection whereas static methods cannot. So, an ideal candidate for static method is the one that does things more or less independently and is not envisioned to ever need any other dependency (say a DAO or Service)
People use Spring not because of some narrow specific futures that cannot be replaced by static classes or DI or whatever. People use Spring because of a more abstracted features and ideas it provide out of the box.
Here is a nice quote from Someone`s blog:
Following are some of the major benefits offered by the Spring Framework:
Spring Enables POJO Programming. Spring enables programmers to develop enterprise-class applications using POJOs. With Spring, you are able to choose your own services and persistence framework. You program in POJOs and add enterprise services to them with configuration files. You build your program out of POJOs and configure it, and the rest is hidden from you.
Spring Provides Better Leverage. With Spring, more work can be done with each line of code. You code in a more fast way, and maintain less. There’s no transaction processing. Spring allows you to build configuration code to handle that. You don’t have to close the session to manage resources. You don’t have to do configuration on your own. Besides you are free to manage the exceptions at the most appropriate place not facing the necessity of managing them at this level as the exceptions are unchecked.
Dependency Injection Helps Testability. Spring greatly improves your testability through a design pattern called Dependency Injection (DI). DI lets you code a production dependency and a test dependency. Testing of a Spring based application is easy because all the related environment and dependent code is moved into the framework.
Inversion of Control Simplifies JDBC. JDBC applications are quite verbose and time-taking. What may help is a good abstraction layer. With Spring you can customize a default JDBC method with a query and an anonymous inner class to lessen much of the hard work.
Spring’s coherence. Spring is a combination of ideas into a coherent whole, along with an overall architectural vision to facilitate effective use, so it is much better to use Spring than create your own equivalent solution.
Basis on existing technologies. The spring framework is based on existing technologies like logging framework, ORM framework, Java EE, JDK timers, Quartz and other view related technologies.
During unit testing you have more flexibility using bean because you can easily mock your bean methods. However, that is not the same with static methods where you may have to resort to PowerMock (which I recommend you stay away from if you can).
It actually depends on the role of the component you are referring to: Is this feature:
An internal tooling: you can use static (you wouldn't wrap Math.abs or String.trim in a bean)
Or a module of the project: design it to be a bean/module-class (a DAO class is best modular to be able to change/mock it easily)
Globally, you should decide w.r.t your project design what are beans and what are not. I think many dev put too much stuff inside bean by default and forget that every bean is an public api that will be more difficult to maintain when refactoring (i.e. restrained visibility is a good thing).
In general, there are already several answers describing the advantages of using spring beans, so I won't develop on that. And also note that you don't need spring to use bean/module design. Then here are the main reasons not to use it:
type-safety: Spring bean are connected "only" at runtime. Not using it, you (can) get much more guaranties at compile time
It can be easier to track your code as there is no indirection due to IoC
You don't need the additional spring dependency/ies which get quite heavy
Obviously, the (3) is correct only if you don't use spring at all in your project/lib.
Also, The (1) and (2) really depend on how you code. And the most important is to have and maintain a clean, readable code. Spring provides a framework that forces you to follow some standard that many people like. I personally don't because of (1) and (2), but I have seen that in heterogeneous dev teams it is better to use it than nothing. So, if not using spring, you have to follow some strong coding guidelines.
I have been reading the book Spring in Action for a few weeks now to learn about the spring framework. I have about 2 years of programming experience mostly in java with some distractions here and there in Ruby and Python.
After reading the first few chapters, I didn't quite get what the big deal is about dependency injection in spring. I was expecting a AHAAA moment but didn't quite experience that yet. I'm sure I'm missing something important.
Why would I want to wire my beans in xml rather than instantiating them the good old way with the = new myclass();
I understand I can wire beans in the xml via constructor args and properties as well as configure datasources in spring so that I can hide away connection details in an xml file. But why? There is more to this especially when it comes to good software design. Can some one explain the big deal?
Three Words: INVERSION OF CONTROL
In a nutshell:
As soon as you instantaniate "the good old way" you create tight coupling, e.g.: your controller depends on a specific template engine, your entities on a concrete database layer, etc. And that's something you want to prevent and where the dependency injection container (DIC) comes in very handy. It manages your services and you don't really have to care anymore about specific implementations as long as those implement the same interface.
Imagine a simple storage layer class called InMemoryLayer that gets instantiated by you when need it. Now you want to switch it for an awesome new open-source github solution called SuperSecretRemoteCloudLayer. Normally you would now hit "Search and Replace" in your IDE of choice and replace all occurrences of InMemoryLayer with the SuperSecretRemoteCloudLayer. But that's not really handy and quite errorprone, why would you want to do all that hard work by hand? The DIC can do that for you and all you need to take care of, is that both *Layer implement the same interface (so your application won't break).
Spring's big deal is more about dependency injection, not XML-based configuration. As others have noted, Spring has been moving away from XML-based configuration. But DI is core to Spring.
The a-ha is that DI offers a different model for linking components together. Instead of components creating each other directly (and thus being tightly coupled), the components stop doing that, and you inject the linkages from a central location. It turns out that this helps with testing and transaction management in particular.
You don't truly appreciate Spring until you've had to do things the hard way. The hard way being maintaining multiple large projects without a coherent framework. If you have 4 big enterprise wide applications that all have their own way of starting themselves, and managing resources, you're in for a headache. If you know that each application uses spring, then just look for the application context xml! This also makes it incredibly easy to setup a new context for different environments, and test cases, all without mucking up your code base.
I'm looking for some best practices when using Spring 3 annotations.
I'm currently moving to Spring 3 and from what I've read so far I see a lot of accent placed on using annotations and moving away from XML configuration.
Actually what is recommended is a mix of both styles, with annotations covering things that won't change often or from one run to the next (e.g. a #Controller will remain like that for the life time of the application), while the things that change and must be configurable go into XML (e.g. a mail smtp address, endpoints for web services that your application talks to etc).
My question is what should go into annotations and to what extent?
At which point annotations make things harder instead of easier? Is the technology (Spring 3) fully adopted as to be able to make such statements or does it take some more time for people to gain experience with it and then reflect on the issue?
It is always difficult to get real advanced information.
The easy tutorial with "look on my blog, I copied the hello word tutorial from Spring Source website... Now you can put fancy annotations everywhere, it the solution of all of our problems including cancer and starvation." is not really usefull.
If you remember right spring core had several purposes, among them:
to be non intrusive
to change any
implementation/configuration of a
bean at any time
to give a centralized and controlled
place to put your configuration
Anotation fail for all theses needs:
They introduce coupling with spring
(you can use standard anotation only
but as soon as you have at least one
spring anotation this is no longer
true)
You need to modify source code and
recompile to change bean
implementation or configuration
Annotations are everywhere in your
code. It can be difficult to find
what bean will be really used just by
reading the code or XML configuration
file.
In fact we have shifted our focus:
We realized that we almost never
provide several implementations of
our services.
We realised that being dependant of
an API is not that bad.
We realized that we use spring not only
for real dependancy injection
anymore, but mainly to increase
productivity and reduce java code
verbosity.
So I would use anotations when it make sence. When it is purerly to remove boilerplate code, verbosity. I would take care of using the XML configuration file for thing that you want to make configurable, even if it is only to provide a stub implementation of the service in unit tests.
I use #Value for properties that are configured in external properties file via PropertyPlaceholderConfigurer, as kunal noted.
There is no strict line for when to use xml, but I use xml:
when the bean is not a class I control
when the object is related to the infrastructure or configuration rather than to the business logic.
when the class has some primitive properties that I would like configurable, but not necessarily via externalized configurations.
In response to your comment: spring is very widely adopted, but "good" and "bad" are very subjective. Even my lines are not universal truths. XML, annotations and programmatic configuration all exists for a purpose, and each developer / company have their preferences.
As I said - there is no strict line, and no universal good practice for annotations.
Annotations are surely the way by which "newer" programming in java will continue. I use annotations for various uses...like #Scope for scope of bean, #Required for making dependency necessary, #Aspect for configuring advices,#Autowired for constructor injection using annotations. Since spring 2.5, annotation support has been good.
See here for spring tutorial, where annotation based issue are covered here.
I think that two cases that the usage of annotations could cause some problems. Firstly, if you want to write complex named queries (JPA) in your entities. I saw some entity code samples and asked myself whether the code is really java code or not. To many metadata in program code will reduce the readability of it which kills clean code principles.
Second problem is portability between JVM versions. Annotation is a feature 1.5+. If your software should support earlier JVM versions, then you may not use these.
Anyway, you can enjoy with annotations everytime without having any doubt and spare your time not changing IDE tabs to check XMLs if the property is still there or not, or entered correct etc.
For very small projects you could still XML version if you haven't too many stuff to be declared in spring. But, if you are in a huge project, the things could be very troublesome if you had 10 xml configs.
This will perhaps not help you much but at work they don't want to use autowiring because it needs a classpath scan (but that can be package-defined i think). So it increases the startup time of the application according to the size of the project.
Spring framework is NON - INTRUSIVE.
Can you please elaborate this?
Thank You :)
Here, "non-intrusive" means that your application code doesn't need to depend on the Spring framework directly. Anything that can inject the appropriate dependencies will (theoretically) work just as well.
The main appeal of a nonintrusive framework is that it stays out of the way of your design and modelling activities. It stays completely out of the way until you need it.
It is perfectly possible to use Spring without any direct dependencies on the spring framework in your application code. That doesn't mean the code will continue to function without spring, since the functionality provided by spring will need to be replaced by another IoC container or code which directly instantiates all objects in a dependency chain, but it does mean that you can choose to wire things up with spring, or via some other mechanism.
However, to be really unintrusive with spring, you need to keep all of your configuration outside of your code, which means using XML for everything. This works beautifully in spring, but its a pain in the neck for developers and, since the advent of the widespread use of annotations in Java 5, isn't really the java way. So spring provides lots of annotations for wiring things together directly in your code. This can obviously create dependencies on Spring within the code, although all of the Spring tags are resolved at compile time, so you can still execute your classes outside of a spring context without any dependencies on spring jars and such. Also, wherever possible, custom spring annotations have been replaced with generic JEE annotations. With Spring 3, it is really pretty easy to use only JEE annotations plus a limited quantity of XML to initialize the application context.
The beauty of the spring way of doing things is that the underlying functionality which implements a feature can often be selected at runtime. If you are using an ORM system in a non-managed container for development, using a native session manager, you can easily switch to container managed sessions in production without changing any code whatsoever if you have configured the app to let spring handle transaction management. Methods that are marked as #Transactional will pick up a session and transaction automatically, regardless of the source, without any changes to the code. In fact, you can trivially switch to an entirely different ORM framework, if you are so inclined, though that's a pretty rare use case, in truth, so most applications will tend to have ORM framework specific code and/or queries in their data access code.
The difference between spring and an old-fashioned 'intrusive' framework is that intrusive frameworks often require you to implement particular interfaces or, even worse, force you to inherit from particular base classes, in order to access framework functionality. In the latter case, not only do you have a dependency on the framework you are using, but it severely limits your class hierarchy structure, too - in a language which only allows single inheritance. Recent versions of EJB learned from the elegance of Spring's (and others') less-intrusive model and EJB itself has since become much less intrusive (It's all about the POJOs).
I don't really see any support for irreputable's argument that spring is now a billion dollar beast that locks users in. Spring is, if anything, less intrusive than it has ever been while offering ever more functionality. It is certainly possible to lock yourself into spring, and a lot of devs are perfectly willing to do so precisely because the runtime overhead of using spring is so trivially small that most of us can't imagine a lot of scenarios in which we might remove spring from a project. If I want a fully managed JEE environment, I can configure for that (and run in the container of any available vendor). If I want to run in tomcat or jetty with 100% of configuration and runtime management coming from spring, I can do that, too. So I'm generally perfectly happy to use spring-specific functionality at the risk of lock-in unless the project requirements specifically forbid it. Spring adds very little overhead at runtime, so it is a low risk choice.
When push comes to shove, I find Spring to be far easier to learn than EJB. I can accomplish the same things with either methodology, but it is easier to bring in devs who are inexperienced if I'm using Spring compared to EJB, so hiring is easier, long term maintenance costs are lower, and release cycles are shorter.
No matter what the language direction, generally speaking, a framework is too intrusive, which is a voice of criticism, so I guess it is not because of this that non intrusiveness has become a "selling point" of publicity.
For example, spring and struts 2 use annotations, configuration files, conventions or reflection (other languages may be other ways) to achieve non-invasive, and the compilation and operation does not have formal dependence on the framework API.
But in essence, without this framework, our program simply cannot run correctly. These so-called annotations are customized. When and how they are processed are different. Think about the migration from gson to Jackson. The migration has costs and risks. Do you need users to write a new one?
In addition, how high is the probability of real migration? It feels very small.
years ago, there was this EJB beast, which was very "intrusive". Spring was touted to be a much simpler set of helper classes, and it was more like libraries than frameworks.
today, Spring becomes the new beast. As a billion dollar business, it is in their best interest to lock people in. Yeah, sure, you don't have a dependency problem, and you can quit Spring anytime.
With EJB, at least you have a few vendors to choose from.
We basically need to be able to adjust behaviour at start-up time, by providing desired classes to be produced by various factories inside our application (to avoid the hard binding of the "new" operator).
I am aware that this is provided by several large frameworks, but I was looking for something easily used by a stand-alone Java application without being gigantic.
Any suggestions?
Edit: It is my experience that frameworks tend to grow big as part of maturing (and complex too). I need this to be retrofittable to a legacy application as part of major refactoring (technical debt), so simplicity is essential of the used libraries. I do not mind having to do a bit of coding in our application, but it must be very visible what is going on. AOP has a tendency for moving stuff out of the way, and that may make the application harder to maintain.
Edit: We have now reached the point where we actually need to make a decision. The application will probably live for decades so we need to make a reversible decision with a framework that will be maintained for hopefully as long. I really like the static type check available with Guice, but not that the annotations bind explicitly to Guice instead of being external like in Spring. I also like that code appears to be more concise when using Guice as opposed to Spring. We need something that is robust and helpful. We do not need more than just DI at the moment. Is there a use case that definitive says go for one of these?
Edit 2011-07-27: The final decision was to use the JSR-330 API in code, and choose on a per-project basis if to use Spring, Guice or Weld. For stand-alone applications Guice has worked well so far as the JSR-330 implementation.
You can always use Spring Framework 2.5. It is a big one, but if you planning to use only DI you can use spring-core and spring-beans modules, which are pretty small (ca. 500KB and 300KB).
There is also Google Guice 2.0 which comes with a package with only basic stuff (no AOP) and it's 430KB.
Have you looked at the Google Guice framework? It's pretty lightweight and annotation-based, avoiding XML configuration files
There's also Pico- and Nano-container (from codehaus) which are quite lightweight although the last time I looked (admittedly a few years ago) the documentation was lacking.
I must say that I agree with others about what I assume is your presumption that Spring is massive and confusing. It's really a very simple IoC container and to be recommended.
There are a couple I know of you might find useful:
PicoContainer
Plexus (used in Maven)
I've found Plexus very useful in standalone apps as it has optional utility components for CLI interaction.
By "gigantic" I'm going to assume you're referring to Spring, but that's unfair, since you can cherry-pick the bits of Spring you want to use. If all you need is the IoC container, just use the appropriate JAR files and the appropriate bit of the API, and ignore the rest of it.
Most answers so far seem to be concerned with the size of the jar files to be added.
However I think the more important question is the impact on the project: How many lines of code must be added/changed in order to use the framework?
Even the "big" spring framework is actually very easy to use:
You basically need:
a xml file that describes your factories.
one line of code to initialize the container by loading the xml file
The nice thing is that spring is non-intrusive. So you do not have to implement specific interfaces or add any specific annotations or imports to your classes.
At best the single spot where you actually initialize the Spring container is the only
place in your application that has an actual dependency to spring classes.
I would strongly suggest to take a look at Spring ME. Although originally meant to be a way to use Spring on Java ME applications, it also works fine for standalone applications.
True, it doesn't give you all of the bells and whistles that Spring (Full) has to offer, but then again, Full Spring is much much more than a simple dependency injection framework.
On the plus side: it's based on a (compliant) subset of Spring's configuration files, and the footprint of the runtime is 0%. In fact, there isn't any. Spring ME will take your application context, and turn it into a class that has no dependencies on classes other than your own.
What's wrong with Spring?
These days it's packaged pretty well so you wouldn't need to take the whole kit and caboodle.
As an aside, I'm not a fan of the annotation based injection frameworks. This is because the annotations are bound to the class rather than the instance, the later being a pre-requisite, imho, for DI. This means every instance of a given class gets the same object(s) injected, which seems to defeat the point.
Also consider that DI doesn't even need a framework, what's wrong with your main method wiring together the application?
If you want something maximally simple and appropriate, then write some code that does what you want done. Presumably this involves wiring together factories based partly on fixed logic, and partly on run-time settings.
This has the advantage that the set of possible run-time configurations is known, and so documentable and testable.
It has the disadvantage that an deploying an unanticipated logic change inherently takes an extra second or so of compile time, and (more significantly) can't be sneaked into production without full testing by disguising it as 'just a configuration change'.
About a year ago I asked myself a question very like this. So I spend a few hours reading the Spring and Guice documentation. After about an hour with Spring I was left feeling that I could get a basic web app going, but had no idea how to use it in a stand alone application. After an hour with the Guice document everything had clicked and I could see just how I to do what I wanted to get done.
Now on to recommending Guice? Well no. What does your team already know? If someone already knows say Spring leaver that knowledge and have them spread it about. Like wise with Guice or Pico.
If you want something really light weight you might want to have a look at fuse it's fairly extendable so might be what you're looking for.
cheers
N