Uncategorized

Profiles in Spring using Annotations

In my previous tutorial on Profiles in Spring using XML  we learned about how to do profiling of beans in Spring using XML.Let’s recap the same and implement the same example using Annotations.

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 the 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, Spring provides @Profile(“name of profile”) annotations which you have to place on top your bean method.

Next 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 sells 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 scenario.

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 + ", getName()=" + getName() + ", getPrice()=" + getPrice()
+ ", toString()=" + super.toString() + ", getClass()=" + getClass() + ", hashCode()=" + hashCode()
+ "]";
}

}

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;
}
}

ShoppingCartConfiguration.java


package com.codegeekslab.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

import com.codegeekslab.cart.ShoppingCart;
import com.codegeekslab.items.Drinks;
import com.codegeekslab.items.Pizza;
import com.codegeekslab.items.Sandwich;

@Configuration
public class ShoppingCartConfiguration {

@Bean
@Profile("breakfast")//can be at class level.
public Sandwich first() {
Sandwich sandwich = new Sandwich();
sandwich.setName("veg-sandwhich");
sandwich.setFlavour("american");
sandwich.setPrice(14);
return sandwich;
}

@Bean
@Profile("breakfast")
public Sandwich second() {
Sandwich sandwich = new Sandwich();
sandwich.setName("egg-sandwhich");
sandwich.setFlavour("american");
sandwich.setPrice(14);
return sandwich;
}

@Bean

@Profile("lunch")
public Burger third() {
Burger burger = new Burger();
burger.setName("veg-cheese-burger");
burger.setFlavour("mexican");
burger.setPrice(22);
return burger;
}

@Bean

@Profile("lunch")
public Pizza forth() {
Pizza pizza = new Pizza();
pizza.setName("classic-pizza");
pizza.setFlavour("italian");
pizza.setPrice(33);
return pizza;
}

@Bean

@Profile("global")
public Drinks fifth() {
Drinks drinks = new Drinks();
drinks.setName("coke");
drinks.setPrice(2);
return drinks;
}

@Bean
@Profile("global")
public Drinks sixth() {
Drinks drinks = new Drinks();
drinks.setName("water");
drinks.setPrice(2);
drinks.setFlavour("cold");
return drinks;
}

@Bean
public ShoppingCart shoppingCart() {
return new ShoppingCart();
}

}

Test.java


package com.codegeekslab.test;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

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

public class Test {

public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.scan("com.codegeekslab.configuration");
context.getEnvironment().setActiveProfiles("global", "breakfast");

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


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.

 

 

Leave a Reply

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