Uncategorized

PROFILES IN SPRING using XML

There are times when you have to load different sets beans into your application and ignore few sets of beans at the time of loading.For an example consider I am building an app and it’s in under development stage so, I would need to load only beans of my test environment and ignore the beans of the production environment.To achieve this spring provides a concept of profile using which you can do the profiling of your beans and tell the spring container at the runtime which beans to load and which to not.

To profile your beans you need to place your beans under <beans profile=’name of profile ‘> <bean>…</bean></beans> and using your container you can mention which profile to load like this context.getEnvironment().setActiveProfiles(“name of profile”);

Let’s understand the above description with an example.

Example: Consider there is a restaurant which sells a sandwich for breakfast, burger for lunch and pizza for dinner and sell drinks all the time.Now we will profile our bean sandwich under breakfast, burger under lunch, pizza under dinner profile and drinks under global profile as it is available all the time.

Let’s create our application under above scenarios.

Menu.java


package com.codegeekslab.menu;

public abstract class Menu {
private String name;
private float price;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public float getPrice() {
return price;
}

public void setPrice(float price) {
this.price = price;
}

@Override
public String toString() {
return "Menu [name=" + name + ", price=" + price + "]";
}

}

Burger.java


package com.codegeekslab.items;

import com.codegeekslab.menu.Menu;

public class Burger extends Menu {
private String flavour;

public String getFlavour() {
return flavour;
}

public void setFlavour(String flavour) {
this.flavour = flavour;
}

@Override
public String toString() {
return "Burger [flavour=" + flavour + "]";
}

}

Drinks.java


package com.codegeekslab.items;

import com.codegeekslab.menu.Menu;

public class Drinks extends Menu {
private String flavour;

public String getFlavour() {
return flavour;
}

public void setFlavour(String flavour) {
this.flavour = flavour;
}

@Override
public String toString() {
return "Drinks [flavour=" + flavour + "]";
}

}

Pizza.java


package com.codegeekslab.items;

import com.codegeekslab.menu.Menu;

public class Pizza extends Menu {
private String flavour;

public String getFlavour() {
return flavour;
}

public void setFlavour(String flavour) {
this.flavour = flavour;
}

@Override
public String toString() {
return "Pizza [flavour=" + flavour + "]";
}

}

Sandwhich.java


package com.codegeekslab.items;

import com.codegeekslab.menu.Menu;

public class Sandwich extends Menu {
private String flavour;

public String getFlavour() {
return flavour;
}

public void setFlavour(String flavour) {
this.flavour = flavour;
}

@Override
public String toString() {
return "Sandwich [flavour=" + flavour + "]";
}

}

ShoppingCart.java


package com.codegeekslab.cart;

import java.util.ArrayList;
import java.util.List;

import com.codegeekslab.menu.Menu;

public class ShoppingCart {
private List<Menu> items = new ArrayList<Menu>();

public void addItem(Menu item) {
items.add(item);
}

public List<Menu> getItems() {
return items;
}
}

beans.xml


<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.2.xsd">
<beans profile='breakfast'>
<bean id="first" class="com.codegeekslab.items.Sandwich">
<property name="name" value="veg-sandwhich" />
<property name="price" value="14" />
<property name="flavour" value="american" />
</bean>
<bean id="second" class="com.codegeekslab.items.Sandwich">
<property name="name" value="egg-sandwhich" />
<property name="flavour" value="american" />
</bean>
</beans>
<beans profile='lunch'>
<bean id="third" class="com.codegeekslab.items.Burger">
<property name="name" value="veg-cheese-burger" />
<property name="price" value="22" />
<property name="flavour" value="mexican" />

</bean>
</beans>
<beans profile='dinner'>
<bean id="forth" class="com.codegeekslab.items.Pizza">
<property name="name" value="classic-pizza" />
<property name="price" value="33" />
<property name="flavour" value="italian" />
</bean>
</beans>
<beans profile="global">
<bean id="fifth" class="com.codegeekslab.items.Drinks">
<property name="name" value="coke" />
<property name="price" value="5" />

<property name="flavour" value="c"old />

</bean>
<bean id="sixth" class="com.codegeekslab.items.Drinks">
<property name="name" value="water" />
<property name="price" value="2" />
</bean>
<bean id="shoppingCart" class="com.codegeekslab.cart.ShoppingCart" />
</beans>
</beans>

Test.java


package com.codegeekslab.test;

import org.springframework.context.support.GenericXmlApplicationContext;

import com.codegeekslab.cart.ShoppingCart;
import com.codegeekslab.menu.Menu;

public class Test {

public static void main(String[] args) {
GenericXmlApplicationContext context = new GenericXmlApplicationContext();
context.getEnvironment().setActiveProfiles("global", "breakfast");
context.load("beans.xml");
context.refresh();
Menu item1 = (Menu) context.getBean("first");
Menu item2 = (Menu) context.getBean("second");
Menu item3 = (Menu) context.getBean("sixth");
ShoppingCart cart = (ShoppingCart) context.getBean("shoppingCart");
cart.addItem(item1);
cart.addItem(item2);
cart.addItem(item3);
System.out.println("Shopping cart contains " + cart.getItems());

}
}

Output

INFO: Refreshing org.springframework.context.support.GenericXmlApplicationContext@5e9f23b4: startup date [Fri Mar 31 14:30:38 IST 2017]; root of context hierarchy
Shopping cart contains [Sandwich [flavour=american], Sandwich [flavour=american], Drinks [flavour=cold]]

In our Test.java we are activating only two profiles global and breakfast using context.getEnvironment().setActiveProfiles(“global”, “breakfast”); that means the beans defined under global and breakfast scope are only getting created and if you are to access other beans you will be thrown an exception by spring container.

So if we add this below line in our Test.java and try to run it


Menu item5 = (Menu) context.getBean("third");

we will be thrown this Exception


Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'third' is defined

So if you want to activate or include other beans in your application just add into setActiveProfile method.

There is another way also to achieve this situation like by defining the set of beans into different configuration file like breakfast.xml, lunch.xml, and dinner.xml and load it using our normal way. This method works but it’s very tedious and difficult to maintain this kind of technique.So it’s recommended to go by profile way.

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *