What is the difference between creating a new object and dependency injection? Please explain in detail.
Well, they're not exactly comparable. You will always have to create a new object by instantiating a class at some point. Dependency injection also requires creating new objects.
Dependency injection really comes into play when you want to control or verify the behavior of instances used by a class that you use or want to test. (For Test Driven Development, dependency injection is key for all but the smallest example).
Assume a class Holder which requires an object of class Handle. The traditional way to do that would be to let the Holder instance create and own it:
class Holder {
private Handle myHandle = new Handle();
public void handleIt() {
handle.handleIt();
}
}
The Holder instance creates myHandle and no one outside the class can get at it. In some cases, unit-testing being one of them, this is a problem because it is not possible to test the Holder class without creating the Handle instance which in turn might depend on many other classes and instances. This makes testing unwieldy and cumbersome.
By injecting the Handle instance, for example in the constructor, someone from the outside becomes responsible for the creation of the instance.
class Holder {
private Handle myHandle;
public Holder(Handle injectedHandle) {
myHandle = injectedHandle;
}
public void handleIt() {
handle.handleIt();
}
}
As you can see the code is almost the same, and the Handle is still private, but the Holder class now has a much loser coupling to its outside world which makes many things simpler. And when testing the Holder class a mock or stub object can be injected instead of a real instance making it possible to verify or control the interaction between the Holder, its caller and the handle.
The actual injection would take place at some other place, usually some "main" program. There are multiple frameworks that can help you do that without programming, but essentially this is the code in the "main" program:
...
private Handle myHandle = new Handle(); // Create the instance to inject
private Handler theHandler = new Handler(myHandle); // Inject the handle
...
In essence, the injection is nothing more than a fancy set method. And of course, you can implement the injection mechanism using that instead of in the constructor like the simple example above.
Of course, both create objects. The difference is in who is responsible for the creation. Is it the class that needs its dependencies or a container like Spring for example, which wires the component's dependencies? You configure the dependencies in a separate(typically XML) configuration file.
It is really a separation of concerns. The class says I need this, this, and this component to function properly. The class doesn't care how it gets its components. You plug them into the class with a separate configuration file.
To give you an example let's consider having a shopping class that needs a payment module. You don't want to hardcode which payment module will be used. To achieve this you inverse the control. You can change the used payment module with a few keystrokes in the configuration file of the container. The power is that you aren't touching any Java code.
Well,
creating a new object is as explicit as it can get - you create a new instance of the desired class.
Dependency injections is a mechanism that provides you with references where you need them.
Imagine a class that represents a connection pool to your database - you usually only have one instance of that class. Now you need to distribute that reference to all the classes that use it.
Here is where Dependency Injection comes in handy - by using a DI framework such as Spring you can define that the one instance of your pool will be injected into the classes that need it.
Your question itself is not easy to answer since the creation of an object and dependency injection can't be compared that easily...
Dependency injections adds a layer of configurability into your application. In the sense, when you hard code object construction, you need to re-build and re-deploy your app, but when you use dependency injection, you can re configure the XML and change the behavior without re-building and re-deploying. There are a large variety of use cases where this can save a lot of tie and effort.
When using an inversion-of-control container to perform dependency injection, the container creates the objects, and not the developer. This is done so that the container can "inject" these objects into other objects.
The answer to the following question may also give the answer you are looking for: Why is the new operator an anti-pattern? Well, the simple answer is that using the new operator may create a hidden, inaccessible dependency within the containing class. This makes testing the containing class more difficult because it involves testing the hidden dependency at the same time (barring MOCK frameworks of course). However, you can avoid this situation by not using the new operator and injecting the dependent object instead. This also has the following advantages:
For test purposes you can inject a different object.
The resulting containing class is more reusable because it can support different implementations of the dependent object.
Related
"Dependency Injection" and "Inversion of Control" are often mentioned as the primary advantages of using the Spring framework for developing Web frameworks
Could anyone explain what it is in very simple terms with an example if possible?
Spring helps in the creation of loosely coupled applications because of Dependency Injection.
In Spring, objects define their associations (dependencies) and do not worry about how they will get those dependencies. It is the responsibility of Spring to provide the required dependencies for creating objects.
For example: Suppose we have an object Employee and it has a dependency on object Address. We would define a bean corresponding to Employee that will define its dependency on object Address.
When Spring tries to create an Employee object, it will see that Employee has a dependency on Address, so it will first create the Address object (dependent object) and then inject it into the Employee object.
Inversion of Control (IoC) and Dependency Injection (DI) are used interchangeably. IoC is achieved through DI. DI is the process of providing the dependencies and IoC is the end result of DI. (Note: DI is not the only way to achieve IoC. There are other ways as well.)
By DI, the responsibility of creating objects is shifted from our application code to the Spring container; this phenomenon is called IoC.
Dependency Injection can be done by setter injection or constructor injection.
I shall write down my simple understanding of this two terms: (For quick understanding just read examples)
Dependency Injection(DI):
Dependency injection generally means passing a dependent object as a parameter to a method, rather than having the method create the dependent object.
What it means in practice is that the method does not have a direct dependency on a particular implementation; any implementation that meets the requirements can be passed as a parameter.
With this implementation of objects defines their dependencies. And spring makes it available. This leads to loosely coupled application development.
Quick Example:EMPLOYEE OBJECT WHEN CREATED,IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT (if address is defines as dependency by Employee object)*.
Inversion of Control(IoC) Container:
This is common characteristic of frameworks, IoC manages java objects - from instantiation to destruction through its BeanFactory. - Java components that are instantiated by the IoC container are called beans, and the IoC container manages a bean's scope, lifecycle events, and any AOP features for which it has been configured and coded.QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it. By implementing Inversion of Control, a software/object consumer get more controls/options over the software/objects, instead of being controlled or having less options. Inversion of control as a design guideline serves the following purposes:- There is a decoupling of the execution of a certain task from implementation.- Every module can focus on what it is designed for.- Modules make no assumptions about what other systems do but rely on their contracts.- Replacing modules has no side effect on other modules
I will keep things abstract here, you can visit following links for detail understanding of the topic.
A good read with example
Detailed explanation
In Spring Objects are loosely coupled i.e., each class is independent of each other so that everything can be tested individually. But when using those classes, a class may be dependent on other classes which need to be instantiated first.
So, we tell spring that class A is dependent on class B. So, when creating bean(like class) for class A, it instantiates class B prior to that of class A and injects that in class A using setter or constructor DI methods. I.e., we are telling spring the dependency at run-time. This is DI.
As, we are assigning the responsibility of creating objects(beans), maintaining them and their aggregations to Spring instead of hard-coding it, we call it Inversion Of Control(IOC).
Inversion of control-
It means giving the control of creating and instantiating the spring beans to the Spring IOC container and the only work the developer does is configuring the beans in the spring xml file.
Dependency injection-
Consider a class Employee
class Employee {
private int id;
private String name;
private Address address;
Employee() {
id = 10;
name="name";
address = new Address();
}
}
and consider class Address
class Address {
private String street;
private String city;
Address() {
street="test";
city="test1";
}
}
In the above code the address class values will be set only when the Employee class is instantiated, which is dependency of Address class on Employee class. And spring solves this problem using Dependency Injection concept by providing two ways to inject this dependency.
Setter injection
Setter method in Employee class which takes a reference of Address class
public void setAddress(Address addr) {
this.address = addr;
}
Constructor injection
Constructor in Employee class which accepts Address
Employee(Address addr) {
this.address = addr;
}
In this way the Address class values can be set independently using either setter/constructor injection.
Inversion Of Control (IOC):
IoC is a design pattern that describes inverting the flow of control in a system, so execution flow is not controlled by a central piece of code. This means that components should only depend on abstractions of other components and are not be responsible for handling the creation of dependent objects. Instead, object instances are supplied at runtime by an IoC container through Dependency Injection (DI).
IoC enables better software design that facilitates reuse, loose coupling, and easy testing of software components.
Dependency Injection (DI):
DI is a technique for passing dependencies into an object’s constructor. If the object has been loaded from the container, then its dependencies will be automatically supplied by the container. This allows you to consume a dependency without having to manually create an instance. This reduces coupling and gives you greater control over the lifetime of object instances.
click to view more
Spring: Spring is “Inversion of Control” container for the Java Platform.
Inversion of Control (IoC): Inversion of Control (IoC) is an object-oriented programing practice whereby the object coupling is bounded at runtime by an "assembler" object and are typically not knowable at compile time using static analysis.
Dependency Injection (DI): "Dependency injection is a software design pattern that allows the removal of hard-coded dependencies and makes it possible to change them, whether at run-time or compile-time." -wiki.
In simple terms..
IOC(Inversion of Control) is a concept that means: Instead of creating objects with the new operator,let the container do it for you.
DI(Dependency injection) is way to inject the dependency of a framework component by the following ways of spring:
Contructor injection
Setter/Getter injection
field injection
Inversion of Control is a generic design principle of software architecture that assists in creating reusable, modular software frameworks that are easy to maintain.
It is a design principle in which the Flow of Control is "received" from the generic-written library or reusable code.
To understand it better, lets see how we used to code in our earlier days of coding. In procedural/traditional languages, the business logic generally controls the flow of the application and "Calls" the generic or reusable code/functions. For example, in a simple Console application, my flow of control is controlled by my program's instructions, that may include the calls to some general reusable functions.
print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);
//More print and scan statements
<Do Something Interesting>
//Call a Library function to find the age (common code)
print Age
In Contrast, with IoC, the Frameworks are the reusable code that "Calls" the business logic.
For example, in a windows based system, a framework will already be available to create UI elements like buttons, menus, windows and dialog boxes. When I write the business logic of my application, it would be framework's events that will call my business logic code (when an event is fired) and NOT the opposite.
Although, the framework's code is not aware of my business logic, it will still know how to call my code. This is achieved using events/delegates, callbacks etc. Here the Control of flow is "Inverted".
So, instead of depending the flow of control on statically bound objects, the flow depends upon the overall object graph and the relations between different objects.
Dependency Injection is a design pattern that implements IoC principle for resolving dependencies of objects.
In simpler words, when you are trying to write code, you will be creating and using different classes. One class (Class A) may use other classes (Class B and/or D). So, Class B and D are dependencies of class A.
A simple analogy will be a class Car. A car might depend on other classes like Engine, Tyres and more.
Dependency Injection suggests that instead of the Dependent classes (Class Car here) creating its dependencies (Class Engine and class Tyre), class should be injected with the concrete instance of the dependency.
Lets understand with a more practical example. Consider that you are writing your own TextEditor. Among other things, you can have a spellchecker that provides the user with a facility to check the typos in his text. A simple implementation of such a code can be:
Class TextEditor
{
//Lot of rocket science to create the Editor goes here
EnglishSpellChecker objSpellCheck;
String text;
public void TextEditor()
{
objSpellCheck = new EnglishSpellChecker();
}
public ArrayList <typos> CheckSpellings()
{
//return Typos;
}
}
At first sight, all looks rosy. The user will write some text. The developer will capture the text and call the CheckSpellings function and will find a list of Typos that he will show to the User.
Everything seems to work great until one fine day when one user starts writing French in the Editor.
To provide the support for more languages, we need to have more SpellCheckers. Probably French, German, Spanish etc.
Here, we have created a tightly-coupled code with "English"SpellChecker being tightly coupled with our TextEditor class, which means our TextEditor class is dependent on the EnglishSpellChecker or in other words EnglishSpellCheker is the dependency for TextEditor. We need to remove this dependency. Further, Our Text Editor needs a way to hold the concrete reference of any Spell Checker based on developer's discretion at run time.
So, as we saw in the introduction of DI, it suggests that the class should be injected with its dependencies. So, it should be the calling code's responsibility to inject all the dependencies to the called class/code. So we can restructure our code as
interface ISpellChecker
{
Arraylist<typos> CheckSpelling(string Text);
}
Class EnglishSpellChecker : ISpellChecker
{
public override Arraylist<typos> CheckSpelling(string Text)
{
//All Magic goes here.
}
}
Class FrenchSpellChecker : ISpellChecker
{
public override Arraylist<typos> CheckSpelling(string Text)
{
//All Magic goes here.
}
}
In our example, the TextEditor class should receive the concrete instance of ISpellChecker type.
Now, the dependency can be injected in Constructor, a Public Property or a method.
Lets try to change our class using Constructor DI. The changed TextEditor class will look something like:
Class TextEditor
{
ISpellChecker objSpellChecker;
string Text;
public void TextEditor(ISpellChecker objSC)
{
objSpellChecker = objSC;
}
public ArrayList <typos> CheckSpellings()
{
return objSpellChecker.CheckSpelling();
}
}
So that the calling code, while creating the text editor can inject the appropriate SpellChecker Type to the instance of the TextEditor.
You can read the complete article here
IOC is technique where you let someone else to create the object for you.
And the someone else in case of spring is IOC container.
Dependency Injection is a technique where one object supplies the dependency of another object.
IOC stands for inversion of control and is a higher level concept that states that we invert the control of the creation of objects from the caller to the callee.
Without inversion of control, you are in charge of the creation of objects. In an inversion of control scenario a framework is in charge to create instances of a class.
Dependency injection is the method through which we can achieve inversion of control. In order for us to leave the control up to the framework or job we declare dependencies and the IOC container injects those dependencies in our class (i.e. the framework creates an instance for us and provides that to our class).
Now what are the advantages of this?
First of all the classes and their lifecycle will be managed by Spring. Spring completely manages the process from creation to destruction.
Secondly, you will get reduced coupling between classes. A class is not tightly coupled with an implementation of another class. If an implementation changes, or if you want to change the implementation of the injected interface you can do so easily without needing to change all the instances in your code base by hand.
Third, there is an increased cohesion between classes. High cohesion means keeping classes that are associated with one another together. Because we are injecting interfaces in other classes it is clear which classes are necessary for the calling class to operate.
Fourth, there is increased testability. Because we are using interfaces in the constructor we can easily swap out the implementation with a mock implementation
fifth, the use of JDK dynamic proxy to proxy objects. the JDK dynamic proxy requires interfaces to be used which is true, because we are injecting these interfaces. This proxy can then be used for Spring AOP, transaction handling, Spring data, Spring security and more
The traditional way of getting address instance in Employee would be by creating a new instance of Address class.Spring creates all dependent object ton us hence we need not to worry about object.
So in Spring we just depend on the spring container which provide us with the dependency object.
The Spring framework can be considered as a collection of sub-frameworks, also referred to as layers, such as Spring AOP, Spring ORM, Spring Web Flow, and Spring Web MVC. You can use any of these modules separately while constructing a Web application. The modules may also be grouped together to provide better functionalities in a web application.
Prior to penetrating down to Spring to container do remember that Spring provides two types of Containers namely as follows:
BeanFactory Container
ApplicationContext Container
The features of the Spring framework such as IoC, AOP, and transaction management, make it unique among the list of frameworks. Some of the most important features of the Spring framework are as follows:
IoC container
Data Access Framework
Spring MVC
Transaction Management
Spring Web Services
JDBC abstraction layer
Spring TestContext framework
Spring IoC Container is the core of Spring Framework. It creates the objects, configures and assembles their dependencies, manages their entire life cycle. The Container uses Dependency Injection(DI) to manage the components that make up the application. It gets the information about the objects from a configuration file(XML) or Java Code or Java Annotations and Java POJO class. These objects are called Beans. Since the Controlling of Java objects and their lifecycle is not done by the developers, hence the name Inversion Of Control.
I am trying to apply ioc into a school project. I have an abstract class Application without any field
public abstract class Application {
abstract public void execute(ArrayList<String> args, OutputStream outputStream, InputStream inputStream) throws IOException;
}
And I will call the concrete class that extends Application by
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Application app = (Application)context.getBean(appName);
My questions are:
Is it a bad practice to initialise a bean without any field (or all the fields are constants) using Spring?
As there is no dependency to other classes in Application, are we still consider this as a dependency injection or IOC? If no, what is the difference between this and a normal factory pattern? It seems that what Spring does here is simply matching the class and initializing it.
UPDATE
Here is the code snippet of the class where the instance of Application is needed.
String appName = argument.get(0);
Application app = ApplicationFactory.getApplication(appName);
ArrayList<String> appArgs
= new ArrayList<String>(argument.subList(1, argument.size()));
app.execute(appArgs, outputStream, inputStream);
Further questions:
in my code the class X will call the instance of Application by specifying a concrete application class name. In this case, it is still not possible for Spring to inject the dependency to Application, right? As what I need is a concrete class but not Application itself.
if Application does have fields but these fields are initialsed somewhere higher than X (X receives them as inputs and passes them to Application), can I use DI in this case?
Is it a bad practice to initialise a bean without any field (or all the fields are constants) using Spring?
No, its totally fine. Its true that you won't be able to "take advantage" of the automatic dependency injection mechanisms provided by spring (because obviously there are no dependencies in the class Application in your example), however spring can still:
Make sure that the Application as a singleton "obeys" the rule of being a single instance in the whole application context. For "manually" maintaining singletons you need to write code. Spring does it for you.
Manages the lifecycle of the object. Example, Spring has "postConstruct"/"preDestroy" methods that can can be run in the appropriate time and make example any custom code of the class Application.
If this class does some heavy-lifting (even without spring) than it can make sense to define it "lazy" so that the initialization of this instance will actually be done upon the first request to it.
Sometimes you/or spring itself will create a proxy of this class in runtime (for many different reasons, for example this aforementioned lazy functionality, but there are also other use cases). This is something that spring can do for you only if it manages the Application and not if its defined outside the spring.
Ok, you don't have dependencies in the application, This means that this Application class has some useful methods (at least on method, like public void foo() for
simplicity). But this in turn means that there is some class (lets call it X) that calls this method. So this class has an instance of Application as a dependency. So now the real question is who manages this class X. Probably it makes sense to manage it in Spring as well, and then you will benefit of the Dependency Injection mechanisms in this class X only because Application is also managed by Spring. In general Spring can inject dependencies only if these dependencies are managed by Spring.
I know, this last paragraph may sound vague given the use case you've presented, but you've got a point, for example in real application people make an initial bootstrapping in very certain places. Usually also people use spring boot that kind of encapsulates this kind of things for you.
As there is no dependency to other classes in Application, are we still consider this as a dependency injection or IOC? If no, what is the difference between this and a normal factory pattern? It seems that what Spring does here is simply matching the class and initializing it.
So as you see, the concept of DI container goes far beyond of what the factory pattern has to offer. In short, factory pattern only specifies the way to create the objects. Spring on the other hand, not only creates the objects but also manages them.
First, I very strongly suggest that you use Spring Boot instead of manually manipulating Spring at a low level like this.
It's perfectly ordinary to use beans that don't have their own fields for settings, but this is usually so that other beans can have pluggable strategies or providers and you can define in your application setup which to use.
If your Application class doesn't need anything else, then there really is not much advantage to Spring. Most real-world programs get complicated soon, however, and that's where it becomes useful.
Finally, you should almost never pass ArrayList as a parameter; use List instead. In the code you showed, however, if you have String[] args, you couldn't say app.execute(Arrays.asList(args), System.out).
I have class A which instantiate class B which in turn do same for class C and so on, forming a large tree. I now need to instantiate an object that should be available all across the tree and I don't want to individually inject this object manually in all classes. I don't want to use a static because there could be different instances of class A running concurrently in different thread and this shared object must be unique per thread. I don't have much experience with thread safe operations.
Use Spring to manage the instance. That way you can inject your instance into any class that needs it and, provided the creation of the parent class is spring managed, the injected bean will be populated.
In some more detail, what you can do is define a class.
public class MyBean {
// Add your class details.
}
And ensure that Spring is either scanning its package or you have defined the bean in your applicationContext.xml file like this. The next stage is to inject this bean where you need to, using the #Autowired annotation..
#Autowired
private MyBean myBean;
And on the creation of that class, myBean will be populated with the same instance of MyBean that was initially created.
Advantages
Doing it this way means that your solution scales well. You can inject it anywhere without constantly changing constructors (and when you're creating more and more sub classes and relationships between classes, this is a prime candidate for Shotgun Surgery.
It's always good to learn about technologies that are used in industry.
Managing a single instance of a class using other methods (like the Singleton pattern) is usually a bad idea.
Disadvantages
Spring does a lot more than just inject objects, and you're pulling down a lot of classes to do just this, which will increase the size of your solution, although not significantly.
Extra Reading
Have a look at a basic Spring tutorial to get you going.
Have a look at the different scopes that you can create beans with, in case some of them suit your needs better.
You either need a local reference in the context that you want to use the object or you need a static reference. Since you don't want to use static you need to get a local reference. You can do this by passing the object in in the constructor or by adding a setter method. Then higher up the tree where ever you construct the child node you pass in the needed object.
You can have kind of a "Parallel Singleton" so to say, i.e. instead of having only one instance it will keep as many instances as there are threads, in a hashmap with a thread-related object being the key.
I have the below classes:
class Validator {
private final SchemaFetcher schemaFetcher;
#Inject
Validator(SchemaFetcher schemaFetcher) {...}
}
class DatabaseSchemaFetcher implements SchemaFetcher {
#Override
Schema loadSchema(final SchemaDefinition schemaDef);
#Override
boolean compareSchemaWithSource(final SchemaDefinition schemaDef, final Schema updatedSchema);
}
This is just one of the examples, I have some other classes like this which I inject into other classes as dependencies. But it makes my SchemaFetcher class like a singleton and I keep passing the schemaDefinition to every single method of it. This seems very procedural and I want to actually make SchemaDefinition an instance variable to the DatabaseSchemaFetcher class but in that case I would not be able to inject a SchemaFetcher Object into my Validator class and instead I should be doing
validate(String schemaName) {
SchemaDefinition schemaDef = buildSchemaDefinitionFrom(schemaName);
SchemaFetcher fetcher = new DatabaseSchemaFetcher(schemaDef);
}
But this makes me tightly coupled to the fetcher which is why I wanted to use Dependency Injection in the first place.
I can see that I could possibly have a default constructor for DatabaseSchemaFetcher and then a setSchemaDefintion() setter to acheive this but that violates the principle of building your object completely using the constructor.
How do I improve this to not have a procedural style fetcher but also inject my dependencies into the constructor? I prefer constructor injection because it clearly defines my dependencies without anyone looking into the implementation of the class to figure out the dependencies the class uses if I use a factory or service locator.
Dependency Injection is one of those very good ideas that seems so good that it gets badly overused. I would not inject the Fetcher into the Validator using the DI framework. Rather, I'd have the DI framework inject a factory into "main". The factory creates the Fetcher with the appropriate SchemaDefinition and passes it to the Validator.
Remember that we want a boundary separating "main" from the rest of the application, and all dependencies should point from "main" to the application. The application should not know about "main". i.e. "main" is a plugin to the application.
In general, DI should be used to inject into "main", and then main uses more traditional techniques to pass factories, strategies, or just regular old abstract interfaces into the application.
Why do you say you're tightly coupled to SchemaFetcher in your 2nd solution?
You're providing there an interface, so you're not coupled to any specific implementation, but only to the definition of what SchemaFetcher is (i.e - the contract of the SchemaFetcher)
You may consider to have a Validator class which takes into its CTOR the SchemaDefinition, and your DatabaseSchemaFetcher can hold a field to it. This way you will also be able to extend the Validator class change the validation logic if required.
But once again, the question of how to pass the schema definition object rises. Not sure injection should be used here - consider altering your design.
I'm not exactly sure what the use of Dependecy Injection and Procedural have to do with each other in this instance.
I think the real issue is that the way you've chosen to model you're objects does not reflect the stated goal.
In the code you've supplied Validator serves no purpose that I can see. If its purpose is to validate SchemaFetcher objects then it probably should have no state beyond the rules for validation then accept arbitary SchemaFetcher objects to validate.
As for DataBaseSchemaFetcher I once again struggle to understand what this does. If its stated purpose is only to fetch schemas then it requires no state in regards to DatabaseSchema objects and as such should accept DatabaseSchema for the methods in which it is charged with acting on a DatabaseSchema. Any internal state should only be related to the classes's fetching behavior.
One tried and true way to get past these painted in a corner situations is to sit down and try really hard to assign each class a single responsibility and keep in mind the following:
Thing really hard about the domain of the exact problem you are trying to solve.
Do not solve any problems you don't have.Take your dreams of extensibility and throw them away. They will almost always be wrong and will just be a huge time sink.
Accept that your design is necessarily deficient and you will have to change it later.
Is it possible to assure that only spring can instantiate a class, and not by the keyword new at compile time? (To avoid instantiating by accident)
Thank you!
If you want to detect it at compile time, the constructor must be non-public.
Private is probably too strict (it makes code analysis tools assume it will never be called, and may even cause warnings in some IDEs), I'd say the default (no modifier, package protected) is best there. In cases you want to allow subclasses in other packages (but that's impossible without allowing calling the constructor directly from that subclass) you can make it protected.
Make sure to comment the constructor appropriately, so it is clear to anyone reading the code why the constructor is like that.
Spring will call this non-public constructor without any problems (since Spring 1.1, SPR-174).
The question if this not allowing anything else to call your constructor, the idea of forcing every user of a class to use the Spring dependency injection (so the whole goal of this question) is a good idea or not, is a whole different matter though.
If this is in a library/framework (that is just usually used with Spring), limiting the way it may be used might not be such a good idea. But if it's for classes that you know will only be used in your closed project, which already forces the use of Spring, it might make sense indeed.
Alternatively, if your real goal is just to avoid the possibility of someone creating an instance and not initializing it with its dependencies, you can just use constructor dependency injection.
And if your goal is only to prevent accidental usage of the constructor (by developers not aware that the class was supposed to be initialized by Spring), but don't want to totally limit possibilities, you can make it private but also add static factory method (with an explicit name like createManuallyInitializedInstance or something like that).
Bad idea: Another possible alternative is to make the constructor publicly available, but deprecate it. This way it can still be used (without resorting to hacks like using reflection) but any accidental usage will give a warning. But this isn't really clean: it is not what deprecation is meant for.
The only obvious way I can think of doing this is at Runtime via a massive hack; Spring works with normal Java after all (i.e. anything that can be accomplished in Spring must be accomplishable via standard Java - it's therefore impossible to achieve as a compile time check). So here's the hack:
//CONSTRUCTOR
public MyClass() {
try {
throw new RuntimeException("Must be instantiated from with Spring container!");
}
catch (RuntimeException e) {
StackTraceElement[] els = e.getStackTrace();
//NOW WALK UP STACK AND re-throw if you don't find a springframework package
boolean foundSpring = false;
for (StackTraceElements el : els) {
if (el.getDeclaringClass().startsWith("org.springframework")) {
foundSpring = true; break;
}
}
if (!foundSpring) throw e;
}
}
I really would not advise doing this!
While I can understand why you would want to ensure that a class is instantiated only by Spring, this is actually not a good idea. One of the purposes of dependency injection is to be able to easily mock out a class during testing. It should be possible, then, during unit tests to manually instantiate the various dependencies and mock dependencies. Dependency injection is there to make life easier, and so it is usually good to instantiate with DI, but there are cases where using new is perfectly sensible and one should be careful not to take any design pattern or idiom to the extreme. If you are concerned that your developers are going to use new where they should use DI, the best solution for that is to establish code reviews.
I'll tell you why not to do this - you won't be able to mock your classes. And thus you won't be able to make unit-tests.
Not sure if Spring supports this as I haven't tried, and haven't used Spring in quite awhile, however with another IOC container a sneaky route I once took was to make the class one wishes to be returned as your injected interface an abstract class, and have the IOC container return that as a derived class instance. This way no-one can create an instance of the class (as it's abstract) and the container can return a derived class of this.
The container itself will generate the definition of the derived class so there's no worry of someone trying to construct one of these
Write an aspect around the call to the constructor and abort if not via Spring
don't know about spring, but if you want to have some control on creating new instances, you should make constructor private, and create public static YourClass getInstance() method inside your class which will handle checks and return new instance of that object. You can then create new class with constructor whichi will call getInstance().. and hand that class to Spring. Soon you will discover places where you had that 'illegal' calls outside spring...