Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
was für mich immer noch nicht klar ist, ist für was das ganze gut sein soll. Es muss für irgendwas gut sein, sonst würde es das ja nicht geben und so häufig heut zu tage verwendet werden. Nur ich habs irgendwie nicht geschnallt.
Jep, nur versteh ich die auch nicht. Was gibts denn für n Vorteil ne Instanz von nem ApplicationContext zu holen anstatt sie a.) Durch nen Konstruktor selber zu erzeugen oder b.) Durch ne Factory erzeugen zu lassen?
Jep, nur versteh ich die auch nicht. Was gibts denn für n Vorteil ne Instanz von nem ApplicationContext zu holen anstatt sie a.) Durch nen Konstruktor selber zu erzeugen oder b.) Durch ne Factory erzeugen zu lassen?
Ok, jetzt weis ich was gemeint war. Das Springframework besteht ja aus vielen nützlichen Dingen.
Der Vorteil, dass man ein Bean über ein Xml-File konfiguriert liegt darin, dass man Abhängigkeiten zu anderen Klassen bewußt vermeidet. Die einzige Abhängigkeit besteht über ein Interface.
Gehen wir von einer klassischen Enterpriseapplikation aus, dann finde ich es z.B. sehr praktisch die eigentliche Kernfunktionalität als ganz einfache Klassen zu Implementieren und zu Testen. Also keine Abhängigkeit z.B. zu einer Datenbank. Es verwendet lediglich ein allgemeines Interface der Persistenzschicht.
Folgendes Beispiel:
Es gibt eine Klasse Person welche eine Person repräsentiert, eine Klasse PersonService die eine Funktion zur
Bewertung einer Person zur Verfügung stellt und ein Interface PersonDao, welches eine Schnittstelle zur Datenbank repräsentiert.
Code:
package com.ms.bsp.spring.model;
/**
* @author ms
*
*/
public class Person {
private Long id = null;
private String name = null;
private int punkte = 0;
/**
* @return the id
*/
public Long getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(Long id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the punkte
*/
public int getPunkte() {
return punkte;
}
/**
* @param punkte the punkte to set
*/
public void setPunkte(int punkte) {
this.punkte = punkte;
}
}
Code:
package com.ms.bsp.spring;
import com.ms.bsp.spring.dao.PersonDao;
import com.ms.bsp.spring.model.Person;
/**
* @author ms
*
*/
public class PersonService {
private PersonDao personDao = null;
public boolean bewerten(Long id, int punkte) {
Person person = personDao.suchen(id);
if (person == null)
return false;
// hier der code zum bewerten
person.setPunkte(punkte);
personDao.update(person);
return true;
}
/**
* @return the personDao
*/
public PersonDao getPersonDao() {
return personDao;
}
/**
* @param personDao the personDao to set
*/
public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
}
}
Code:
package com.ms.bsp.spring.dao;
import com.ms.bsp.spring.model.Person;
/**
* @author ms
*
*/
public interface PersonDao {
public Person suchen(Long id);
public void update(Person person);
}
Zur Entwicklungszeit der Klasse PersonService kann man nun den Fokus ganz auf die eigentliche Funktionalität legen
und hat bis auf das Interface PersonDao keine Logik zum Persistieren. Zum Testen könnte ich jetzt ganz einfach eine
Klasse PersonMockDao schreiben (Mock-Objekt), welches nur für diesen Test eine Person zurückliefert:
Code:
package com.ms.bsp.spring.test;
import com.ms.bsp.spring.dao.PersonDao;
import com.ms.bsp.spring.model.Person;
/**
* @author ms
*
*/
public class PersonMockDaoImpl implements PersonDao {
private Person person = null;
/* (non-Javadoc)
* @see com.ms.bsp.spring.dao.PersonDao#suchen(java.lang.Long)
*/
public void init() {
person = new Person();
person.setName("ms");
person.setId(new Long(1000));
person.setPunkte(23);
}
public Person suchen(Long id) {
if (id != null && id.longValue() == 1000)
return person;
return null;
}
/* (non-Javadoc)
* @see com.ms.bsp.spring.dao.PersonDao#update(com.ms.bsp.spring.model.Person)
*/
public void update(Person person) {
// TODO Auto-generated method stub
}
/**
* @return the person
*/
public Person getPerson() {
return person;
}
}
Das Context-File zum Testen könnte dann so aussehen:
package com.ms.bsp.spring.test;
import junit.framework.TestCase;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ms.bsp.spring.PersonService;
import com.ms.bsp.spring.model.Person;
/**
* @author ms
*
*/
public class PersonServiceTestCase extends TestCase {
private static ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(
"testContext.xml");
public void testPersonService() {
PersonService personService = (PersonService)ctx.getBean("personService");
PersonMockDaoImpl personDao = (PersonMockDaoImpl)ctx.getBean("personMockDao");
assertFalse(personService.bewerten(new Long(500), 20));
assertTrue(personService.bewerten(new Long(1000), 20));
Person person = personDao.getPerson();
assertNotNull(person);
assertEquals(20, person.getPunkte());
}
}
Nun könnte man eine konkrete Implementierung für PersonDao schreiben, welche auf eine "echte" Datenbank zeigt und dies im Context-file einfach festlegen ohne etwas am Code zu ändern. Die Klasse PersonService "weis" also gar nicht, was sich hinter PersonDao verbirgt. Braucht es auch nicht, es soll sich unabhängig von der Persistenzschicht um die eigentliche Logik kümmern. Das Persistieren übernimmt das Dao selbst für welches wir wiederum einen eigenen Testcontext bauen könnten. Als "echte" Datenbank im Testcontext könnte z.B. eine hsqldb dienen, die nur zur Laufzeit des Testcases im Speicher existiert um z.B. komplexere Abfragen zu testen. Aber nicht nur zum Testen ist es hilfreich. Man könnte ein und dieselbe Klasse in einem Richclient, einer Webapplikation oder einem Webservice laufen lassen und dabei je nach Umgebung konfigurieren.
Man kann das Beispiel jetzt noch weiter ausbauen. Z.B. läge es auf der Hand, die Businesmethoden von PersonService auch in ein Interface auszulagern und über die echte Implementierung im Contextfile einen Transaktionslayer einziehen.
Das Beispiel ist natürlich sehr einfach, aber ich hoffe man kann daraus erkennen in welche Richtung es geht. Auch größere Anwendungen mit vielen Entwicklern können mithilfe von Spring IoC/Di in sehr kleine Häppchen unterteilt werden und so den Überblick von überschaubarer Logik schaffen.
Ich hoffe, ich konnte ein wenig helfen.
Der Code ist übrigens getestet.