Spring adalah salah satu application framework untuk aplikasi berbasis Java, tepatnya J2EE. Apakah application framework itu? Setelah disarikan dari berbagai macam sumber bacaan, gw simpulkan application framework itu adalah sekumpulan aturan atau standar yang disertai dengan library, yang digunakan untuk mempermudah, mempercepat atau membuat pengembangan aplikasi secara rapi sehingga bisa dikembangkan lagi dengan mudah di kemudian hari. Sedangkan J2EE –sekarang disebut Java EE– oleh situs Sun Microsystem dijelaskan sebagai
“Java Platform, Enterprise Edition (Java EE) builds on the solid foundation of Java Platform, Standard Edition (Java SE) and is the industry standard for implementing enterprise-class service-oriented architecture (SOA) and next-generation web applications“.
Sederhananya, ini adalah edisi Java yang dipakai untuk mengembangkan aplikasi berskala besar atau enterprise. Edisi lainnya, Java SE (Standard Edition) adalah Java yang selama ini gw pakai untuk mengembangkan aplikasi desktop kecil2an). Dan satunya lagi, Java ME (Micro Edition) sesuai namanya, untuk mengembangkan aplikasi untuk perangkat kecil seperti PDA, handphone, dll. Jadi alih2 menggunakan Java SE yang selama ini gw pakai, sekarang gw akan mulai belajar dan menggunakan Java EE. Pak Endy Muhardin berbaik hati memberikan tips bagaimana mulai belajar Java EE di sini.
Sekarang balik lagi ke Spring. Ketika bicara tentang Spring, maka akan sering sekali terdengar istilah Inversion of Control (IoC) dan Dependency Injection. Gw sebagai pendatang baru dalam dunia Spring ini tentu saja bingung dengan kedua istilah itu. Untunglah ada forum berbahasa Indonesia yang membahas mengenai hal2 tersebut. Ada juga contoh yang bagus dari http://www.devx.com/Java/Article/21665. Jadi mari lihat contoh berikut ini.
Misalnya gw mo buat suatu class yang bertugas memproses data, dalam arti membaca data dari suatu file dan memberikan data dari file tersebut pada class yang memanggilnya. Namanya class DataProcessor.
class DataProcessor
{
public Result processData()
{
FileDataReader dataReader = new FileDataReader(“/data/file1.data”);
Data data = dataReader.readData(); //membaca data
return data.calculateResult(); //mengembalikan data pada class yang memanggilnya
}
}
Ini dia potongan class yang memanggil si DataProcessor (disebut client code).
//client code:
DataProcessor fileDataProcessor = new DataProcessor(); //membuat objek DataProcessor
Result result = fileDataProcessor.processData(); //meminta data dari hasil pembacaan file
Di sini terlihat DataProcessor bergantung atau dependent pada FileDataReader. Kalau mau membaca data dari sumber lain, misalnya database, class DataProcessor harus direfactor, biar bisa menerapkan pembacaan data yang lebih general. Salah satu caranya dengan menggunakan interface.
interface DataReader {
public Data readData(); }
class DataProcessor
{
private DataReader dataReader;
public DataProcessor(DataReader reader) {
this.dataReader = reader; }
public Result processData() {
Data data = dataReader.readData();
return data.calculateResult(); }
}
//client code:
FileDataReader dataReader = new FileDataReader(“/data/file1.data”);
DataProcessor fileDataProcessor = new DataProcessor(dataReader);
Result result = fileDataProcessor.processData();
DataProcessor tidak lagi beroperasi pada objek FileDataReader, melainkan pada interface DataReader yang diimplementasikan oleh FileDataReader sehingga lebih generic dan reusable. Masalahnya, setiap client code yang mau memproses data harus membuat objek data reader sendiri dan me-link objeknya dengan DataProcessor. Daripada begitu, kita bisa menginjeksikan kebergantungan (inject the dependency) antara DataReader dengan DataProcessor dengan factory class. Factory ini istilah yang baru gw kenal juga. Jadi ditambahankanlah class DataProcessorFactory ini dan client code-nya menggunakan jasa si factory untuk membuatkan reference ke DataProcessor.
class DataProcessorFactory
{
public static DataProcessor getFileDataProcessor()
{
DataReader reader = new FileDataReader(“/data/file1.data”);;
DataProcessor dataProcessor = new DataProcessor(reader);
return dataProcessor;
}
}
//client code:
DataProcessor fileDataProcessor = DataProcessorFactory.getFileDataProcessor();
Result result = fileDataProcessor.processData();
Si factory-lah yang membuatkan objek dari DataProcessor untuk client. Client tinggal meminta objek dan data hasil baca file melalui factory. Dengan ini telah terjadi apa yang namanya Inversion of Control dengan cara Dependency Injection (DI). Bentuk IoC yang lain adalah Dependency Pull, tapi gw belum ngerti itu.
Semakin besar aplikasi yang dibuat, semakin banyak factory class yang diperlukan. Ini gak menguntungkan karena kebanyakan factory itu merupakan singleton sederhana, yang tugasnya membuat dan menghubungkan objek2, nggak bisa di-inherit sehingga banyak duplikasi. Kelebihan DI dengan Spring, menurut DevX.com adalah
“… its ability to act as a factory to create objects. Spring reads a schematic defined in an external configuration file, creates and wires the objects together using reflection, and then passes the objects back to you. Think of Spring as a factory that you don’t have to write any code for.“
Intinya, Spring membuatkan dan menghubungkan objek2 melalui skema yang didefiniskan di configuration file eksternal, dalam hal ini file XML (gw gak tau hanya bisa XML file apa bisa yang lain). Langsung aja ke contoh kodenya. Client code akan menjadi seperti ini.
//client code:
InputStream is = new FileInputStream(“src/examples/spring/beans.xml”);
BeanFactory factory = new XmlBeanFactory(is);
DataProcessor dataProcessor = (DataProcessor) factory.getBean(“fileDataProcessor”);
Result result = dataProcessor.processData();
dan file XMLnya seperti ini.
<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://www.springframework.org/dtd/spring-beans.dtd”>
<beans>
<bean name=”fileDataProcessor”
class=”examples.spring.DataProcessor”
singleton=”true”>
<constructor-arg>
<ref bean=”fileDataReader”/>
</constructor-arg>
</bean>
<bean name=”fileDataReader”
class=”examples.spring.FileDataReader”
singleton=”true”>
<constructor-arg>
<value>/data/file1.data</value>
</constructor-arg>
</bean>
</beans>
Selalu dibungkus dengan tag <beans></beans>, di dalamnya bisa ada banyak tag <bean>, yang merepresentasikan objek di code Java yang kita buat. Contohnya pada code XML di atas, bean name yang pertama adalah “fileDataProcessor”, ini adalah identifier untuk objek bertipe DataProcessor (class=”examples.spring.DataProcessor”). Singleton = true artinya gw rasa mirip2 static di Java, jadi setiap kali ada request dari client, Spring akan selalu memberikan instance yang sama. Kalau singleton diset false, Spring akan membuat bean (instance kali ya maksudnya) yang berbeda untuk setiap request. Dalam tag <constructor-arg>, <ref bean=”fileDataReader”/> berarti passing objek dengan id “fileDataReader” untuk constructornya. Dari tag bean yang kedua bisa kita lihat bahwa “fileDatReader” ini nama instance dari class FileDataReader. Bean yang kedua ini mempassing nilai ke constructornya (lihat <value>/data/file1.data</value>).
Sampai saat ini itulah yang gw pahami. Masih belum mengerti hal2 lain seperti AOP, DAO, dan ORM. Kesimpulan tentang Spring, katanya sih framework yang satu ini sangat mantep sekali. Ini garis besarnya
- Spring bertujuan untuk meminimalkan dependency antar komponen aplikasi dan menyediakan plug-in architecture. Mungkin inilah yang mendukung terjadinya dynamic workflow seperti yang dijelaskan supervisor KP gw kemaren. Jadi kita bisa pasang komponen aplikasi saat runtime tanpa perlu bongkar kode Java-nya.
- Object linking di Spring didefinisikan di file XML, jadi kita bisa memasang komponen atau konfigurasi yang berbeda saat runtime.
- Berbeda dengan factory yang invasive, di mana client sangat tergantung pada factory karena meminta objek ke sana, Spring menyediakan reference objek ke client yang membutuhkan. Spring secara aktif merangkai dependency dari objek yang gak kenal satu sama lain menjadi aplikasi yang utuh.
- Kemampuannya ini berguna banget buat Test-Driven-Development di Xtreme Programming (gw gak terlalu ngerti ini). Tapi mungkin artinya adalah bisa memudahkan untuk testing sana sini. Karena kode2 gak saling kenal, tp kalo mau disatuin juga gampang. Client gak perlu membuat objek baru (gak pernah membuat reference dengan keyword new), gak perlu lookup ke factory, Spring yang menyediakan dependency-nya secara runtime–dengan real maupun mock object.
- Unit testing jadi mudah dilakukan karena gak ada dependecy yang hard-code, class2 yang ada saling gak kenal satu sama lain.
sumber2 bacaan:
http://dotnet.netindonesia.net/?0::21357
http://www.devx.com/Java/Article/21665
http://arfan86.blogspot.com/2007/02/chating-tentang-spring-framework.html

dwi said,
December 16, 2008 @ 8:29 am
Assalamualaikum…blh tau referensi untuk beljar lebih detail ttg spring dr mana ya..
aku lg ada tugas untuk spring dao,jdbc
terima kasih
dan_ said,
May 5, 2009 @ 2:00 am
mari qt ramekant……… gmn crnya?