Spring – Dependency Check | Code Factory


Donate : Link

Medium Blog : Link

Applications : Link

This image has an empty alt attribute; its file name is image-1.png

Spring Tutorial Index Page: Link

  • In Constructor DI injecting properties are mandatory, in case of Setter method DI it is not mandatory. To make it mandatory we should use dependency-check attribute with <bean> tag.
  • * dependency-check is no loger supported since Spring 3.x.
  • From none, simple, objects, and all we can pass any single value to dependency-check.
  • If we use none then w/o calling setter method we can create Car class object.
class Car {
	private String carName;
	private Engine engine;
	// setters
}
class Engine {
	private String modelYear;
	// setters
}

<beans>
	<bean id="c" class="com.Car" dependency-check="none">
	</bean>
</beans>
  • If we apply dependency-check=”simple” then only Primitive are restrict. Compulsary we should pass primitive values. Refernce/Secondary types are not mandatory.
<beans>
	<bean id="c" class="com.Car" dependency-check="simple">
		<property name="carName" value="JLR" />
	</bean>
</beans>
  • If you want to make secondary object dependency injection compulsory then you can go through dependency-check=”objects”.
<beans>
	<bean id="c" class="com.Car" dependency-check="objects">
		<property name="engine" ref="e" />
	</bean>
	<bean id="e" class="com.Engine" />
</beans>
  • If you want to make primitive and secondary both types DI compulsory then you can go through dependency-check=”all”.
<beans>
	<bean id="c" class="com.Car" dependency-check="all">
		<property name="carName" value="JLR" />
		<property name="engine" ref="e" />
	</bean>
	<bean id="e" class="com.Engine" dependency-check="simple">
		<property name="modelYear" value="2020" />
	</bean>
</beans>
  • * By this dependency-check (Dependency Checking) we can make setter DI mandatory. By default setter DI is not mandatory, constructor DI is mandatory.

Create Java Project

  • Open Eclipse
  • Go to File -> New -> Others… -> Java Project
  • Create DI-Setter-Checking project
  • Right click on project -> Build Path -> Configure Build Path -> Libraries tab -> Add External JARs (Used 2.X jars)
    • commons-logging-X.X.jar
    • spring-beans-X.X.X.jar
    • spring-context-X.X.X.jar
    • spring-core-X.X.X.jar
  • * You can find dtd information from spring-beans-X.X.X.jar -> org -> springframework -> beans -> factory -> xml -> spring-beans.dtd (line no 36 & 37)

spring.xml

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
	"http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>
	<!-- <bean id="c" class="com.codeFactory.beans.Car" dependency-check="none">
		no need to call any setter
	</bean> -->
	
	<!-- <bean id="c" class="com.codeFactory.beans.Car" dependency-check="simple">
		we must need to call primitive setter
		try to run this after commenting below property
		<property name="companyName" value="" />
	</bean> -->
	
	<!-- <bean id="c" class="com.codeFactory.beans.Car" dependency-check="objects">
		we must need to call secondary setter
		<property name="engine" ref="e" />
	</bean> -->
	
	<bean id="c" class="com.codeFactory.beans.Car" dependency-check="all">
		<!-- we must need to call primitive, secondary setter -->
		<property name="companyName" value="JLR" />
		<property name="engine" ref="e" />
	</bean>
	
	<bean id="e" class="com.codeFactory.beans.Engine" dependency-check="simple" >
		<property name="modelYear" value="2020" />
	</bean>
</beans>

Car.java

package com.codeFactory.beans;

/**
 * @author code.factory
 *
 */
public class Car {

	private String companyName;
	private Engine engine;

	public Car() {
		System.out.println("Car.Car()");
	}

	public void setCompanyName(String companyName) {
		this.companyName = companyName;
	}

	public void setEngine(Engine engine) {
		this.engine = engine;
	}

	public void print() {
		System.out.println("Company Name " + companyName);
		System.out.println("Engine - Model Year " + engine.getModelYear());
	}
}

Engine.java

package com.codeFactory.beans;

/**
 * @author code.factory
 *
 */
public class Engine {
	private int modelYear;

	public Engine() {
		System.out.println("Engine.Engine()");
	}

	public int getModelYear() {
		return modelYear;
	}

	public void setModelYear(int modelYear) {
		this.modelYear = modelYear;
	}

}

Client.java

package com.codeFactory.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.codeFactory.beans.Car;

/**
 * @author code.factory
 *
 */
public class Client {
	public static void main(String... args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("com/codeFactory/resources/spring.xml");
		
		Car t = (Car) context.getBean("c");
		t.print();
	}
}

Output:

Car.Car()
Engine.Engine()
Company Name JLR
Engine - Model Year 2020
  • Disadvantage of dependency-check is that if from 4 properties we only require to assign value to 2 properties only. Example is MySql connection. To connect MySql we require only driver name and url, username and password are not mandatory. In that case if we use dependency-check=”sample” then it force to assign values to 4 properties.
  • To solve this issue we have annotation @Required. If we use annotation then in xml file no need to use dependency-check attribute.
  • By using @Required annotation you can make your DI mandatory. You can apply this @Required to primitive methods and as well as secondary datatypes methods also.
  • @Required annotation is use on top of method.
  • There are 3 types of annotation.
    • Class level
    • Property level
    • Method level
  • To activate this @Required annotation you must require to create object of RequiredAnnotationBeanPostProcessor through IOC container.

Create Java Project

  • Open Eclipse
  • Go to File -> New -> Others… -> Java Project
  • Create DI-Setter-Required project
  • Right click on project -> Build Path -> Configure Build Path -> Libraries tab -> Add External JARs (Used 2.X jars)
    • commons-logging-X.X.jar
    • spring-beans-X.X.X.jar
    • spring-context-X.X.X.jar
    • spring-core-X.X.X.jar
    • spring-expression-X.X.X.jar
    • mysql-connector-java-X.X.X.jar
  • * You can find dtd information from spring-beans-X.X.X.jar -> org -> springframework -> beans -> factory -> xml -> spring-beans.dtd (line no 36 & 37)

spring.xml

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
	"http://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>
	<!-- Oracle connection -->
	<!-- must include ojdbc14.jar file -->
	<!-- <bean id="t" class="com.codeFactory.beans.Test" dependency-check="simple">
		<property name="driver" value="oracle.jdbc.OracleDriver" />
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
		<property name="user" value="user" />
		<property name="password" value="password" />
	</bean> -->
	
	<!-- MySql connection -->
	<!-- must include mysql-connector-java-X.X.X.jar file -->
	<bean id="t" class="com.codeFactory.beans.Test">
		<!-- if you are commenting below properties and run then you'll get BeanInitializationException -->
		<property name="driver" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost:3306/test" />
		<property name="user" value="root" />
		<property name="password" value="root" />
	</bean>
	
	<!-- to activate @Required anotation -->
	<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" />
</beans>

Test.java

package com.codeFactory.beans;

import java.sql.Connection;
import java.sql.DriverManager;

import org.springframework.beans.factory.annotation.Required;

/**
 * @author code.factory
 *
 */
public class Test {

	private String driver;
	private String url;
	private String user;
	private String password;

	@Required
	public void setDriver(String driver) {
		this.driver = driver;
	}

	@Required
	public void setUrl(String url) {
		this.url = url;
	}

	@Required
	public void setUser(String user) {
		this.user = user;
	}

	@Required
	public void setPassword(String password) {
		this.password = password;
	}

	public void printConnection() throws Exception {
		Class.forName(driver);
		/*for Oracle we must have to pass username and password*/
		Connection con = DriverManager.getConnection(url, user, password);
		System.out.println(con);
		
		System.out.println("Driver " + driver);
		System.out.println("Url " + url);
		System.out.println("User " + user);
		System.out.println("Password " + password);
	}
}

Client.java

package com.codeFactory.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.codeFactory.beans.Test;

/**
 * @author code.factory
 *
 */
public class Client {
	public static void main(String... args) throws Exception {
		ApplicationContext context = new ClassPathXmlApplicationContext("com/codeFactory/resources/spring.xml");
		
		Test t = (Test) context.getBean("t");
		t.printConnection();
	}
}

Output:

com.mysql.cj.jdbc.ConnectionImpl@145f66e3
Driver com.mysql.jdbc.Driver
Url jdbc:mysql://localhost:3306/test
User root
Password root

Leave a comment