[Spring]: XML Configuration
spring
09/10/2019
Methods to create a spring container
- Full XML Config
- Java Annotation
- Java Configuration Class (No XML needed)
xml configuration (and IoC)
There are three differnet ways to create/configure Spring container. This is a first method to create with xml configuration file. Link to IoC
Main method
JAVA
public static void main(String args[]) { // load spring config file (create spring container) ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("fileName.xml");
// retrieve bean from spring container Player player = context.getBean("myPlayer", Player.class);
// Call methods on the bean System.out.println(player.getWorkout()); System.out.println(player.getFortune());
// close the context context.close();}
- make sure that xml file is located in src directory
XML file
XML
<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Creating an object --> <bean id="myPlayer" class="com.ellismin.BasketballPlayer"> </bean>
</beans>
Explanation
JAVA
Player player = context.getBean("myPlayer", Player.class);
XML
<bean id="myPlayer" class="com.ellismin.BasketballPlayer"></bean>
- Retrives the bean from xml config file. This grabs the bean object with name myPlayer
- Without the use of IoC, above codes would look like:
JAVA
Player myPlayer = new BasketballPlayer();
- Player.class in parameter is required because when Spring pass the interface to the method behind the scenes, Spring will cast the object for you
- com.ellismin.BasketballPlayer is a fully qualified name; packageName.className
Dependency Injection
- Spring allows you to inject dependency(helper) from xml config
- Code below includes examples of constructor injection, setter injection
XML
<?xml version=1.0 encoding="UTF-8"?><beans...> <!-- Create dependency(helper) object --> <bean id="myWeather" class="com.ellismin.SunnyWeather"></bean>
<bean id="myPlayer" class="com.ellismin.BasketballPlayer">
<!-- Constructor injection --> <constructor-arg ref="myWeather" />
<!-- Setter injection --> <property name="weather" ref="myWeather"/>
<!-- Setter injection w/ literal value -->
<!-- Setter injection from properties file --> <property name="email" value="${john.email}" />
</bean></beans...>
How interfaces & classes look like
JAVA
public interface Player { public String getWorkout(); public String getWeather();}
JAVA
public class BasketballPlayer implements Player { private Weather weather; private String email;
public BasketballPlayer(Weather weather) { this.weather = weather } @Override public String getWorkout() { return "playing basketball"; } @Override public String getWeather() { return weather.getWeather(); } // Setter injection example public void setWeather(Weather weather) { this.weather = weather; } // Setter injection example w/ literal value OR properties file public void setEmail(String email) { this.email = email; }
}
JAVA
public interface Weather { public String getWeather();}
JAVA
public class SunnyWeather implements Weather { @Override public String getWeather() { return "Today will be sunny all day!" }}
Explanation
XML
<bean id="myWeather" class="com.ellismin.SunnyWeather"></bean>
- This creates the dependency (helper) object that will be used as parameter for BasketballPlayer class
- Above would look like:
JAVA
SunnyWeather weather = new SunnyWeather();
XML
<bean id="myPlayer" class="com.ellismin.BasketballPlayer"></bean>
- This code piece would be equivalent to:
JAVA
Player myPlayer = new BasketballPlayer();
XML
<bean id="myPlayer" class="com.ellismin.BasketballPlayer"> <!-- Constructor injection --> <constructor-arg ref="myWeather" /> </bean>
- With constructor injection:
JAVA
Player myPlayer = new BasketballPlayer(weather);
Setting literal value & value from properties file
XML
<bean id="myPlayer" class="com.ellismin.BasketballPlayer"> <!-- Setter injection --> <property name="weather" ref="myWeather"/> <!-- Setter injection w/ literal value --> <!-- Setter injection from properties file --> <property name="email" value="${john.email}" />
</bean>
- With setter injection:
- property name weather will look for a setter method setWeather and pass in the reference weather.
- similarly, property name email will look for setEmail method and pass in the literal value or value from file
- To inject value from properties file, xml needs extra code to scan the file
XML
<?xml version=1.0 encoding="UTF-8"?><beans...><!-- Load properties file: emailList.properties --> <context:property-placeholder location="classpath:emailList.properties" /></beans...>
- emailList.properties would look like:
BASH
In the above example, \${john.email} will grab [email protected] from file then pass it into setEmail method as parameter
The program outputs:
BASH
playing basketballToday will be sunny all day!
Scope for xml
XML
<beans...> <bean id="myPlayer" class="com.ellismin" scope="singleton"> ...</beans...>
- Singleton is set by default. We can chance it to prototype for desired usage
Init / Destroy
Init and Destroy methods can be accomplished with added methods in java along with method names in xml file
XML
<beans...> <bean id="myPlayer" class="com.ellismin" init-method="doStartUp" destroy-method="doCleanUp"> ...</beans...>
JAVA
public class BasketballPlayer implements Player { ... // Init method public void doStartUp() { System.out.println("Start up"); } // Destroy method public void doCleanUp() { System.out.println("cleanUp"); }}
- Note: For prototype scoped beans, SPring does not call the destroy method!
- Spring doesn't manage the complete lifecycle of a prototype bean