Each java-based application has a work together to show what the user sees as a few objects of work application. When writing a complex Java application, application classes should be as independent of other Java classes as possible to increase the reuse of these classes and to test them independently of other classes, and thus the likelihood of unit testing. Dependency injection (or sometimes called wiring) helps to glue these classes together while maintaining their independence.
Consider an application that has one of the text editor components to provide a spelling check. The standard code will look like this:
public class TextEditor {
private spellchecker spellchecker;
Public TextEditor () {
spellchecker = new Spellchecker ();
}
}
What we're doing here is creating a dependency between text editing and spell checking. In the reversal of the control scheme, we would do something like this:
public class TextEditor {
private spellchecker spellchecker;
Public TextEditor (Spellchecker spellchecker) {
this.spellchecker = spellchecker;
}
}
Here, text editors should not worry about spelling checker implementation. The spelling checker will be implemented independently, and will be provided to text editors when text edits are instantiated, the entire process is controlled by the spring framework.
Here, we have removed full control from text editing and kept it in other places (i.e. XML configuration files) and dependencies (ie, class spell checking) are injected into class text edits through class constructors. Therefore, process control has been "inverted" through dependency injection (DI) because it has been effectively delegated to rely on some external systems.
The second way to rely on injection is through the text editing class, where we will create a setter method for the spell checker instance that will be used to invoke the setter method to initialize the properties of the text editing.
Therefore, Di has two main variants and the following two sub chapters will cover both examples of the combination:
Dependency Injection based on constructors
when the container invokes the constructor of the class with multiple parameters, each is done by a di that represents the constructor dependency in the other class.
Example:
The following example shows that a class text editing TextEditor can only be dependency injection and constructor injection.
We use the Eclipse IDE, and then follow these steps to create a spring application:
Here are the contents of the Texteditor.java file:
Package Com.yiibai;
public class TextEditor {
private spellchecker spellchecker;
Public TextEditor (Spellchecker spellchecker) {
System.out.println ("Inside texteditor.");
This.spellchecker = spellchecker;
}
public void SpellCheck () {
spellchecker.checkspelling ();
}
}
Here is another related class file Spellchecker.java content:
Package Com.yiibai;
public class Spellchecker {public
spellchecker () {
System.out.println ("Inside Spellchecker constructor.")
Public
void CheckSpelling () {
System.out.println ("Inside checkspelling.");
}
The following are the contents of the Mainapp.java file:
Package Com.yiibai;
Import Org.springframework.context.ApplicationContext;
Import Org.springframework.context.support.ClassPathXmlApplicationContext;
public class Mainapp {public
static void Main (string[] args) {
ApplicationContext context =
new ClassPath Xmlapplicationcontext ("Beans.xml");
TextEditor te = (texteditor) context.getbean ("TextEditor");
Te.spellcheck ();
}
The following is a constructor-based injection in the configuration file Beans.xml file:
<?xml version= "1.0" encoding= "UTF-8"?> <beans xmlns=
"Http://www.springframework.org/schema/beans"
xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemalocation= "http:// Www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">
<!--Definition for texteditor Bean-->
<bean id= "TextEditor" class= "Com.yiibai.TextEditor" >
<constructor-arg ref= "spellchecker"/>
</bean>
<!--Definition for spellchecker bean-- >
<bean id= "spellchecker" class= "Com.yiibai.SpellChecker" >
</bean>
</beans>
After creating the source code and the bean configuration file, let's run the application. If all goes well the following information will be printed:
Inside Spellchecker constructor.
Inside TextEditor constructor.
Inside checkspelling.
Parameter resolution of the constructor:
There may be ambiguity, and there is more than one argument in the case of passing parameters to the constructor. To resolve this uncertainty, the order in which the constructor parameters are defined in a bean definition is the order in which these parameters are supplied to the appropriate constructors. Please consider the following class:
Package x.y;
public class Foo {public
foo (bar bar, Baz Baz) {
//...
}
}
The following configuration works fine:
<beans>
<bean id= "foo" class= "X.y.foo" >
<constructor-arg ref= "bar"/>
< Constructor-arg ref= "Baz"/>
</bean>
<bean id= "bar" class= "X.y.bar"/> <bean "id="
Baz "class=" X.y.baz "/>
</beans>
Let's examine a more case where we pass different types of constructors. Please consider the following class:
Package x.y;
public class Foo {public
foo (int year, String name) {
//...
}
}
A container can also use type matching with a simple type if you explicitly specify the parameter type of the constructor that uses the type attribute. For example:
<beans>
<bean id= "Examplebean" class= "examples". Examplebean ">
<constructor-arg type=" int "value=" 2001 "/> <constructor-arg" type=
" Java.lang.String "value=" Zara "/>
</bean>
</beans>
Finally, by using the best method of constructing function parameters, an index property is used to explicitly specify the index of a constructor parameter. The index here is starting from 0. For example:
<beans>
<bean id= "Examplebean" class= "examples". Examplebean ">
<constructor-arg index=" 0 "value=" 2001 "/>" <constructor-arg index=
"1" value= " Zara "/>
</bean>
</beans>
Finally, if you pass a reference to an object, you need to use the ref attribute of the <constructor-arg> tag, and if you pass a value directly, you should use the Value property.
Dependency injection based on setter method
based on setter di, the container calls the setter method to complete after the bean calls the parameterless constructor or the parameterless static factory method to instantiate the bean.
Here are the contents of the Texteditor.java file:
Package Com.yiibai;
public class TextEditor {
private spellchecker spellchecker;
A setter method to inject the dependency.
public void Setspellchecker (Spellchecker spellchecker) {
System.out.println ("Inside setspellchecker.");
This.spellchecker = spellchecker;
}
A getter method to return spellchecker public
spellchecker Getspellchecker () {return
spellchecker;
} Public
void SpellCheck () {
spellchecker.checkspelling ();
}
}
Here, you need to check the naming convention for setter methods. Set we use the Setspellchecker () method, which is very similar to the Java Pojo class variable's spelling checker. Let's create another related class file Spellchecker.java, which reads as follows:
Package Com.yiibai;
public class Spellchecker {public
spellchecker () {
System.out.println ("Inside Spellchecker constructor.");
}
public void CheckSpelling () {
System.out.println ("Inside checkspelling.");
}
The following are the contents of the Mainapp.java file:
Package Com.yiibai;
Import Org.springframework.context.ApplicationContext;
Import Org.springframework.context.support.ClassPathXmlApplicationContext;
public class Mainapp {public
static void Main (string[] args) {
ApplicationContext context =
new Classpathxml ApplicationContext ("Beans.xml");
TextEditor te = (texteditor) context.getbean ("TextEditor");
Te.spellcheck ();
}
Here is the configuration file Beans.xml file is configured to be based on setter method injection:
<?xml version= "1.0" encoding= "UTF-8"?> <beans xmlns=
"Http://www.springframework.org/schema/beans"
xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemalocation= "http:// Www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">
<!--Definition for texteditor Bean-->
<bean id= "TextEditor" class= "Com.yiibai.TextEditor" >
<property name= "spellchecker" ref= "Spellchecker"/>
</bean>
<!--Definition for Spellchecker Bean-->
<bean id= "spellchecker" class= "Com.yiibai.SpellChecker" >
</bean>
</beans>
Attention should be paid to the difference between defining Beans.xml files based on constructor injection and setter injection. The only difference is that we have used <constructor-arg> tags for constructor based injection and <property> tags for the <bean> element based on setter injection.
The second important point to note is that if you pass a reference to an object, you need to use the ref attribute of the <property> label, and if you pass a value directly, you should use the Value property.
After creating the source code and the bean configuration file, let's run the application. If all goes well, this will print the following information:
Inside Spellchecker constructor.
Inside Setspellchecker.
Inside checkspelling.
XML configuration with the P namespace:
If you have a lot of setter methods, you can easily use the XML configuration file in the P namespace. Let's look at their differences:
Let's use the example of the <property> tag standard XML configuration file:
<?xml version= "1.0" encoding= "UTF-8"?> <beans xmlns=
"Http://www.springframework.org/schema/beans"
xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemalocation= "http:// Www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd ">
<bean id= "John-classic" class= "Com.example.Person" >
<property name= "name" value= "John Doe"/>
<property name= "spouse" ref= "Jane"/>
</bean>
<bean name= "Jane" class= " Com.example.Person ">
<property name=" name "value=" John Doe "/>
</bean>
</beans >
The above XML configuration can be overridden by using P-namespace as follows a concise approach:
<?xml version= "1.0" encoding= "UTF-8"?> <beans xmlns=
"Http://www.springframework.org/schema/beans"
xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xmlns:p= "http://www.springframework.org/schema/ P "
xsi:schemalocation=" Http://www.springframework.org/schema/beans
http://www.springframework.org/ Schema/beans/spring-beans-3.0.xsd ">
<bean id=" John-classic "class=" Com.example.Person "P:name="
John Doe "
p:spouse-ref=" Jane "/>
</bean>
<bean name=" Jane "class=" Com.example.Person "
p:name= "John Doe"/>
</bean>
</beans>
Here, you should not specify the difference between the original value and the reference to the space object. The-ref section indicates that this is not a straight chain value, but rather a reference to another bean.