I am taking a look into Spring as a web framework, however I am needing a bit of help getting my head around DI.
The concept of objects getting constructed in the container on run time is such a new concept.
I am just wondering how this will reflect in a big application, would I have some modules doing work that are more highly coupled or should every object be initialised at runtime?
It all seems a little intensive to me, I mean say for example I have a CSV file data mining application that removes the data per row - each rows data is encapsulated in one of my own CSVRow objects for processing or whatever. These objects are instantiated whenever an Excel file maybe uploaded to the server. I don't know how many I will need to create?
I seem to be getting a bit lost, any clarity, an overview or some guidance would be much appreciated.
Thanks in advance!
I'll try to put it simply:
use dependency injection for stateless classes that have logic (business logic, persistence logic, front-end logic)
use new for value objects
Broadly speaking, an application is made up of a collection of classes that implement the business logic.
Normally each object is responsible to obtain references of the objects it needs (and this object's dependencies).
I think it is obvious that this leads to:
1) tightly coupled classes
2) code hard to test since each object instantiates specific classes it depends on and if there needs to be a change, the code must be modified.
So using Dependency Injections the objects do not instantiate the dependent objects themselves but an "external component" provides the dependencies at the object creation time i.e. injects the dependencies into the objects.
So in your example, the idea is that you can have for example a CsvRow object instantiated by Spring (along with all its dependencies) and get an object whenever needed. It is also possible to switch to for example CsvRow2 object (another implementation) by just changing your configuration
You don't need to use DI for your CSV row abstraction. Once you get the file, when you start parsing it, your code can create the CSVRow things as it goes. You don't need to wire them up.
You certainly could if you wanted to. You would grab your applicationContext and just get the beans by name. You would want to do this if the CsvRow had dependencies that you wanted Spring to manage for you.
I think of Spring as a way to create "singletons". When I want to guarantee there's only one instance of a class in the application, use Spring to create it. But, instead of being a traditional singleton with a static INSTANCE field or similar, it's a POJO with whatever constructors / setters you need. Spring creates the instance at runtime for you and makes sure that creation only happens once.
Related
As a new user to programming in general, I'm trying to understand dependency injection.
Is there ever a time where it's appropriate to instantiate an object within another class or is the idea that all objects will be instantiated in Main?
Yes, there are plenty of times where it's appropriate to instantiate objects inside other objects. Dependency injection is for dependencies, not for data objects and such.
But even in the case of "dependencies", there are cases where it's fine to create them inside another object. If the objects you're creating are logically part of the object creating them, then dependency injection may be overkill. Sometimes I'll organize code into multiple classes without intending the smaller pieces to be standalone in any way. In those cases I may just new them inside something else.
But it's a judgment call. Even in such cases it may be nice to be able to unit test the smaller bits in isolation, for example.
I am re-factoring a legacy Java application to use Spring.
This involves declaring the application classes as Spring beans and then replacing all occurrences of new with context.getBean OR with DI.
I'm re-writing application logic in way that some classes become singletons. However since they are being instantiated using new in other locations, multiple copies would exist which would mess up the business logic.
I'd like to ensure that application explicitly fails whenever it tries to instantiate an object by itself, instead of running and misbehaving in unpredictable ways. (I'm not sure that the re-factoring has covered 100% of the application there still might be new lurked up in some corner)
What is the best way of ensuring that a class can only be instantiated by Spring container?
(I'm hoping to avoid writing a factory for each class)
As from your question
In this particular scenario only one copy of an object should exist which is fetched from the context, multiple copies would mess up the business logic.
you can create classic singleton and use getInstance() method as factory method in bean definition in spring's xml file:
<bean id="myBean" class="MyClass" factory-method="getInstance"/>
Make your constructor private, and than no one can call it. Additionally you will see errors in compile time, if some parts of old code uses new to instantiate your class.
So, yeah. That. I'm going through the tutorial one step at a time, so if the answer comes up later, forgive me. It's step 1 in this section.
I understand the ease of using this to have access in other methods in the EntryPoint class, but coming from the Spring MVC world, this sort of thing might be thought of as a controller and be a singleton (bean). Is it wrong to think this way in the GWT world?
With GWT you are coding as if it was a desktop AWT program. So, you do not have CDI or anything similar.
So, if you put all your information in a bean, you still would have to either:
keep a bean attribute in the class
pass it as a parameter in the method call
to get a reference to it (instead of retrieving it from CDI when needed)
While you can still use a bean when needed, these attributes are closely linked to the main class (in fact they are other graphical components to show). In general, I would only use bean when you have a bunch of attributes that are tightly coupled between them but are not tightly coupled to any other class.
I am curious on the way Spring is able to bind together an application (just in simple terms of course). In a standalone Java application you bootstrap the application with a lookup then Spring instantiates and binds the objects together (DI).
If you for example have a for loop where you don't know the number of iterations (user input) would you use the dependency lookup method inside the loop body? And would you implement the BeanFactoryAware interface in this case? Or do you make the object by using new keyword?
Just an thing that came to my mind while reading.
"Lets pretend that you need a new instance each time"
If you have a component A that has a for loop where you need a new instance of a "bean" B on each iteration, why not just inject a B factory into A and call that within a for loop.
It all really comes down to what makes sense:
If you need to create something simple (e.g. a new String) on each iteration, then there is nothing wrong with using a new keyword.
If it is something more complex, where it is best to encapsulate "creation details", it would not do you any good to depend on any particular framework (e.g. BeanFactoryAware). Just use a builder/factory, which can either be another bean that would be injected, or can be called statically.
Less magic more clarity
If I understood your question correctly the answer could be: Spring beans are singletons by default.
So in most cases you would never need to lookup one inside the for loop - you'll use the instance looked up just before your loop.
Also you're probably trying to think about Spring beans as JavaBeans that you create to populate with data. You could read this link to see the difference: http://www.shaunabram.com/beans-vs-pojos/
Spring beans are more like JavaEE Enterprise Beans, you don't create them - you just use them.
I'm writing a small application in RCP to wrap around the business logic in another (non-RCP) simulation library. I can access and use the library fine from any of my plugins, but I don't know where I should put the instance of the Simulation library so that, say, one of the command handlers can make calls to it.
From reading the docs it sounds like I should be storing 'global' information like this in the workbench - but I still don't really understand how to do that.
Help?
First, the business layer (BL) can and should reside in its' own plugin. That will provide decent decoupling between the layers.
Second, you should carefully decide what the interface should be and which classes are exposed. Ideally, you should mostly expose interfaces and data objects.
Finally, decide how the "hand shake" works. E.g., how to obtain the initial interface to the BL. Since it is a Plugin, it could have an Activator which loads it. You could add a method in the activator which returns the BL interface.
If you are looking for something more decoupled, you could create an extension point or deploy the BL as an OSGi service, but that's a bit of an overkill for you need.
If I understand you correctly, I see two ways:
Store the instance in the model plug-in itself, using ‘SimulationFactory.getInstance(String myAppId)‘. The passed String is a constant in you app that is always used, when obtaining the reference.
Define a new class e.g. GlobalAccess in you app that is initilized with an instance of your model and has some getter (whether you use a single instance again or only provide public static methods is a matter of taste).
The seocond way is similar to some classes in eclipse like platfom or platformui, where you can obtain initial references and navigate through the workbench.
edit
i just found a tutorial that might help you:
Passing Data between Plug-ins