JSF – 06 – Managed Bean & IOC & Dependency Injection

Merhaba Arkadaslar,
Bu bolumde Managed Bean’lerin initialize ve DI ( Dependency Injection) konusunu inceleyecegiz.

  • IOC (Inversion Of Control) & Dependency Injection
  • Injection Managed Beans with Annotation
  • Managed Beans XML Configurations
  • Injecting CDI Beans

IOC (Inversion Of Control)

IOC (Inversion Of Control) teknigi bagimliliklarin (dependency) creation/olusturma ve management/yonetim gorevini developerdan alma yaklasimidir.

Computer ile Keyboard arasinda Computer HAS-A Keyboard iliskisi olsun, yani Computer sinifinda Keyboard sinifi tipinde bir instance variable olsun. Geleneksel yontemde dusundugumuz de Keyboard tipinde bir objeyi new anahtar kelimesiyle olusturmamiz gereklidir.

IOC (Inversion Of Control) yaklasimini kullandigimizda Keyboard tipindeki objemiz calisma zamaninda (runtime) otomatik olarak olusturulur ve Computer sinifimizda yer alan Keyboard tipindeki reference degiskenimize inject edilir. Tabiki bu otomatik olusturma islemi icin cesitli ayarlamalar yapmak gereklidir.

public class Computer {
	private Keyboard keyboard;
}

IOC yaklasimi 2 ana gruba ayrilir

  • Dependency Lookup
    Dependency Lookup yaklasimina JNDI API yi ornek veririz. Bu suan konumuz disindadir.
  • Dependency Injection
    Genel olarak IOC (Inversion Of Control)  denildiginde aklimiza Dependency Injection kavrami gelir. IOC yaklasimi icin yaptigimiz tanimi Dependency Injection kavrami icinde soyleyebiliriz.Dependency’lerin creation/olusturma ve management/yonetimini kullandigimiz frameworke birakiriz. Burada konumuz JSF oldugu icin burada Dependency Injection isini JSF implementation yapmaktadir.Dependency Injection da 2 gruba ayrilir.

    • Setter Dependency Injection
      Setter metotlari uzerinden dependency’ler inject edilir.
    • Constructor Dependency Injection
      Constructor uzerinden dependency’ler inject edilir.

Not: Spring yazilarimda Setter/Constructor Dependency injection orneklerini inceleyebilirsiniz.
Bu yazilar ilerleyen zamanlarda guncellenip daha da genisleyecektir.

ManagedBean

Bean; property/ozelliklerin tanimlandigi ve getter/setter metotlarindan olusan , public no-argument yapilandiricya sahip Java siniflaridir.

Managed Bean , JSF tarafindan ulasilan/yonetilen/manage Java bean’leridir. JSF Managed Bean’ler POJO (Plain Old Java Object) yapisindaki Java siniflaridir.

Managed Bean’ler yardimiyla JSF sayfalarimizin (xhtml) durumunu/state tutariz/store.

JSF implementation ;

  • Ihtiyaca gore beanleri olusturur ve yok eder.
  • JSF sayfasi gosterildiginde bean properties degerlerini okur (getter)
  • Form post edildiginde bean properties degeleri yazilir (setter)

Java Standard Convention setter/getter tanimi ;

public T getFoo()
public void setFoo(T newValue)

Eger property boolean ise bu durumda getter metodu “is” ile de baslayabilir.

private boolean connected;
public boolean isConnected()

Injection Managed Beans with Annotation

JSF Managed Bean’lerinde basit bir DI (Dependency Injection) mekanizmasi kullanilabilir. Bunun icin  @ManagedProperty annotation’i kullanilabilir.

MessageBean.java

package _04.inject.bean;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean(name = "message")
@RequestScoped
public class MessageBean {

	private String sayWelcome = "Welcome to www.injavawetrust.com , ";

	public String getSayWelcome() {
		return sayWelcome;
	}

	public void setSayWelcome(String sayWelcome) {
		this.sayWelcome = sayWelcome;
	}

}

HelloInjectBean.java

package _04.inject.bean;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class HelloInjectBean {

	// @ManagedProperty annotation'i ile DI islemini JSF'e birakiyoruz.
	@ManagedProperty(value = "#{message}")
	private MessageBean messageBean;

	// Setter Injection'in gerceklesmesi icin setter metodu tanimlanmalidir.
	public void setMessageBean(MessageBean messageBean) {
		this.messageBean = messageBean;
	}

	@ManagedProperty("admin")
	// @ManagedProperty annotaion ile String tipi icin de DI islemi yapabiliriz.
	// name property'si icin initialize islemini gerceklestirebiliriz.
	private String name;

	public String getName() {
		return name;
	}

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

	public String getSayWelcome() {
		if ("".equals(name) || name == null) {
			return "";
		} else {
			// MessageBean sinifinda yer alan metodu kullaniyoruz.
			// messageBean reference degiskenimiz JSF tarafindan olusturulan
			// MessageBean objesini gostermektedir.

			return messageBean.getSayWelcome() + name;
		}
	}

}

helloInjectBean.xhtml

Ajax ornegimizde oldugu gibi basit bir ornek form

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>@ManagedProperty Example</title>
</h:head>
 
    <h:body>
    	<h3>@ManagedProperty Example</h3>
    	<h:form>
    	   <h:inputText id="name" value="#{helloInjectBean.name}"></h:inputText>
    	   <h:commandButton value="Welcome Me">
    		 <f:ajax execute="name" render="output" />
    	   </h:commandButton>
 
    	   <h2><h:outputText id="output" value="#{helloInjectBean.sayWelcome}" /></h2>	
    	</h:form>
 
    </h:body>
</html>

Sayfamiz calistiginda name property’sine “admin” degeri  setName metodu calismasiyla initialize edilecektir.

managedproperty example

MessageBean sinifinda yer alan sayHello metodu cagiriyoruz. Bunun icin MessageBean objesi gereklidir. messageBean reference degiskenimiz JSF tarafindan olusturulan MessageBean objesini gostermektedir. JSF bizim icin DI ( Dependency Injection)  islemini gerceklestirecek boylelikle messageBean initialize edilmis olacaktir.

managedproperty example2

Managed Beans XML Configuration

JSF 2.0 ‘dan once Managed Beanler XML dosyasinda tanimlanmak zorundaydi. JSF 2.0 ile birlikte artik hem annotation hem de XML konfigurasyonu ile Managed Bean tanimi yapabiliyoruz. Buraya kadar hep annotation kullanarak Managed Bean tanimi yaptik simdi de XML konfigurasyonu yaparak Managed Bean tanimi yapalim.

Managed Bean’lerimizi XML konfigurasyonu ile yapabilmemiz icin WEB-INF dizini altinda faces-config.xml dosyamiz olmasi gereklidir.

  • <managed-bean> Managed Bean tanimi baslangic
  • <managed-bean-name>Managed Bean’e unique bir isim veriyoruz </managed-bean-name>
  • <managed-bean-class>packageName.className bilgisini veriyoruz </managed-bean-class>
  • <managed-bean-scope>scope bilgisi veriyoruz</managed-bean-scope>
  • <managed-property> etiketi @ManagedProperty annotation’a karsilik gelmektedir. Bu etiket icerisinde su etiketler tanimlanir.
    1. <property-name> Managed Bean’deki initialize edecegimiz property ismi yaziyoruz
    2. <value> Initialize edecegimiz degeri/value buraya yaziyoruz.
  • </managed-bean> Managed Bean tanimi bitis.

FacesConfigBean.java

package _05.faces.config;

public class FacesConfigBean {

	private String name;
	private String password;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

JSF Managed Bean’leri annotation kullanarak tanimlandigi gibi xml dosyasinda da tanimlanabilir ve konfigurasyon yapilabilir. Managed Bean’lerimizi faces-config.xml dosyamizda yapabiliriz.

faces-config.xml

<?xml version='1.0' encoding='UTF-8'?>
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
        http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
    version="2.2">

	<!-- managed-bean etiketi ile Managed Bean tanimina baslanir. managed-bean-name 
		etiketi ile unique/tekil bir isim veririz. managed-bean-class etiketi ile 
		sinif tanimini yapariz. managed-bean-scope etiketi ile Managed Bean icin 
		scope tanimini yapariz. Eger property initialize edilecekse bu durumda managed-property 
		etiketini kullaniriz. Hangi property initialize edilecekse bu durumda property-name 
		etiketinde bunu belirtiriz. value etiketi ile ilgili degeri belirtiriz. -->
	<managed-bean>
		<managed-bean-name>facesConfigBean</managed-bean-name>
		<managed-bean-class>_05.faces.config.FacesConfigBean
		</managed-bean-class>
		<managed-bean-scope>request</managed-bean-scope>

		<managed-property>
			<property-name>name</property-name>
			<value>admin</value>
		</managed-property>

	</managed-bean>

</faces-config>

 loginFacesConfig.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html">
<h:head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>FacesConfig xml example</title>
</h:head>
<h:body>
	<h:form>
		<h3>Please enter your name and password.</h3>
		<table>
			<tr>
				<td>Name:</td>
				<td><h:inputText value="#{facesConfigBean.name}" /></td>
			</tr>
			<tr>
				<td>Password:</td>
				<td><h:inputSecret value="#{facesConfigBean.password}" /></td>
			</tr>
		</table>
		<p>
			<h:commandButton value="Login" action="welcome" />
		</p>
	</h:form>
</h:body>
</html>

welcome.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html">
<h:head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Welcome</title>
</h:head>
<h:body>
	<h3>Welcome to www.injavawetrust.com JSF tutorial ,
		#{facesConfigBean.name}</h3>
</h:body>
</html>

loginFacesConfig.xhtml sayfamizi calistirdigimizda ornegimiz sorunsuzca calisacaktir. name property’si icin etiketini kullandik. “admin” degeri sorunsuzca initialize edildi.

faces config example

Managed Bean’leri faces-config.xml dosyasinda tanimlamak zorunda degiliz. Buyuk projeleri dusundugumuzde siniflari package seviyesinde ayirdigimiz gibi bean tanimlarini farkli farkli XML dosyalarinda yapabiliriz. Bunun icin web.xml dosyasinda context-param ekleyebiliriz.

javax.faces.CONFIG_FILES adinda context-param tanimliyoruz ve value olarak XML dosyamizi gosterelim.

	<context-param>
		<param-name>javax.faces.CONFIG_FILES</param-name>
		<param-value>/WEB-INF/managed-beans.xml</param-value>
	</context-param>

 HelloInjectBeanXML.java

package _06.inject.bean.xml;

public class HelloInjectBeanXML {

	private MessageBeanXML messageBean;

	public void setMessageBean(MessageBeanXML messageBean) {
		this.messageBean = messageBean;
	}

	private String name;

	public String getName() {
		return name;
	}

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

	public String getSayWelcome() {
		if ("".equals(name) || name == null) {
			return "";
		} else {
			// MessageBeanXML sinifinda yer alan metodu kullaniyoruz.
			// messageBean reference degiskenimiz JSF tarafindan olusturulan
			// MessageBeanXML objesini gostermektedir.

			return messageBean.getSayWelcome() + name;
		}
	}

}

MessageBeanXML.java

package _06.inject.bean.xml;

public class MessageBeanXML {

	private String sayWelcome = "Welcome to www.injavawetrust.com , ";

	public String getSayWelcome() {
		return sayWelcome;
	}

	public void setSayWelcome(String sayWelcome) {
		this.sayWelcome = sayWelcome;
	}

}

managed-bean.xml

@ManagedProperty(value = “#{message}”) annotation’in karsiligi olarak <managed-property> value etiketi icerisinde Expression Language kullanabiliriz ; #{messageBeanXML}
Boylelikle bir bean’i diger bean’e inject edebiliriz.

<?xml version='1.0' encoding='UTF-8'?>
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
        http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
	version="2.2">

	<managed-bean>
		<managed-bean-name>helloInjectBeanXML</managed-bean-name>
		<managed-bean-class>_06.inject.bean.xml.HelloInjectBeanXML</managed-bean-class>
		<managed-bean-scope>request</managed-bean-scope>

		<managed-property>
			<property-name>messageBean</property-name>
			<value>#{messageBeanXML}</value>
		</managed-property>
	</managed-bean>

	<managed-bean>
		<managed-bean-name>messageBeanXML</managed-bean-name>
		<managed-bean-class>_06.inject.bean.xml.MessageBeanXML</managed-bean-class>
		<managed-bean-scope>request</managed-bean-scope>
	</managed-bean>

</faces-config>

helloInjectBeanXML.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>helloInjectBeanXML Example</title>
</h:head>
 
    <h:body>
    	<h3>helloInjectBeanXML Example</h3>
    	<h:form>
    	   <h:inputText id="name" value="#{helloInjectBeanXML.name}"></h:inputText>
    	   <h:commandButton value="Welcome Me">
    		 <f:ajax execute="name" render="output" />
    	   </h:commandButton>
 
    	   <h2><h:outputText id="output" value="#{helloInjectBeanXML.sayWelcome}" /></h2>	
    	</h:form>
 
    </h:body>
</html>

injectbean with xml example

Injecting CDI Beans

CDI ( Context and Dependency Injection) bean’ini kullanarak Glassfish Application Server uzerinde deploy gerceklestirmistik. Hatirlayacagimiz gibi CDI Bean’leri Tomcat gibi bir Servlet Container uzerinde calismaz , CDI Bean’lerinin calismasi icin Glassfish gibi bir Application Server gereklidir. Ikinci bir nokta @SessionScoped CDI Bean’leri Serializable arabirimini mutlaka implement etmelidir.

HelloInjectBeanCDI.java

CDI Bean’lerini @Named annotation ile tanimlamayi daha once inceledik. Burada @Inject annotation kullanarak MessageBeanCDI objesini messageBean reference degiskenine inject ederiz.

Onemli noktalar;

  • Her iki CDI Bean de Serializable arabirimini implement etmelidir.
  • @SessionScoped annotation icin javax.enterprise.context.SessionScoped sinifini kullanmamiz gereklidir. Managed Beanler icin javax.faces.bean.SessionScoped sinifini kullaniriz. Bu noktayi daha once de belirtmistim.
package _07.inject.bean.cdi;

import java.io.Serializable;

import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;

@Named(value="helloInjectBeanCDI")
@SessionScoped
public class HelloInjectBeanCDI implements Serializable{

	@Inject
	private MessageBeanCDI messageBean;

	public void setMessageBean(MessageBeanCDI messageBean) {
		this.messageBean = messageBean;
	}

	private String name;

	public String getName() {
		return name;
	}

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

	public String getSayWelcome() {
		if ("".equals(name) || name == null) {
			return "";
		} else {
			// MessageBeanCDI sinifinda yer alan metodu kullaniyoruz.
			// messageBean reference degiskenimiz JSF tarafindan olusturulan
			// MessageBeanCDI objesini gostermektedir.

			return messageBean.getSayWelcome() + name;
		}
	}

}

MessageBeanCDI.java

package _07.inject.bean.cdi;

import java.io.Serializable;

import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@Named(value="messageBeanCDI")
@SessionScoped
public class MessageBeanCDI implements Serializable{

	private String sayWelcome = "Welcome to www.injavawetrust.com , ";

	public String getSayWelcome() {
		return sayWelcome;
	}

	public void setSayWelcome(String sayWelcome) {
		this.sayWelcome = sayWelcome;
	}

}

helloInjectBeanCDI.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>helloInjectBeanCDI Example</title>
</h:head>
 
    <h:body>
    	<h3>helloInjectBeanCDI Example</h3>
    	<h:form>
    	   <h:inputText id="name" value="#{helloInjectBeanCDI.name}"></h:inputText>
    	   <h:commandButton value="Welcome Me">
    		 <f:ajax execute="name" render="output" />
    	   </h:commandButton>
 
    	   <h2><h:outputText id="output" value="#{helloInjectBeanCDI.sayWelcome}" /></h2>	
    	</h:form>
 
    </h:body>
</html>

Onemli :
helloInjectBeanCDI.xhtml sayfamizi Glassfish uzerinde calistirmamiz gereklidir ! Tomcat uzerinde calistiramayiz.

inject bean cdi glassfish

Backing Bean

Backing Bean , JavaBean style tanimlanan sayfadaki/page UI Component’lerle iliskili bean’lerdir.
Backing Bean JSF Managed Bean’lerin bir alt tipidir , UI Component’ler icin ozellesmis bir tipidir.

Orneklerimizde h:inputText ve h:inputSecret Component’lerini kullandik. UI Component Tree olusturulunca bu Component’lerin UIInput objesine karsilik geldiginden bahsetmistik.

private String name;
yerine
private UIInput name;
kullanabiliriz.

HelloBackingBean.java

package _08.backing.bean;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIInput;

@ManagedBean(name="backingBean")
@RequestScoped
public class HelloBackingBean {

    private UIInput name;
    private UIInput password;

    public UIInput getName() {
	return name;
    }

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

    public UIInput getPassword() {
	return password;
    }

    public void setPassword(UIInput password) {
	this.password = password;
    }
}

xhtml sayfamizda dikkat etmemiz gereken nokta h:inputText ve h:inputSecret Componentleri icin binding attribute’u kullaniyoruz.

loginBackingBean.xhtml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html">
<h:head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Backing Bean Example</title>
</h:head>
<h:body>
	<h:form>
		<h3>Please enter your name and password.</h3>
		<table>
			<tr>
				<td>Name:</td>
				<td><h:inputText binding="#{backingBean.name}" /></td>
			</tr>
			<tr>
				<td>Password:</td>
				<td><h:inputSecret binding="#{backingBean.password}" /></td>
			</tr>
		</table>
		<p>
			<h:commandButton value="Login" action="welcome" />
		</p>
	</h:form>
</h:body>
</html>

backing bean example

Yazimi burada sonlandiriyorum.
Herkese Bol Javali Gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
OCE, Java EE 6 Web Component Developer

Print Friendly, PDF & Email

Leave a Reply

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