Autor Thema: Was ist Springframework (Geduld)  (Gelesen 3066 mal)

Marinero Atlántico

  • Gast
Was ist Springframework (Geduld)
« am: 23.04.05 - 12:23:45 »
1. Mythos:

Vielleicht stimmt es ja doch  ;D
4.Eine neue Hoffnung
5.Das Imperium schlägt zurück
6.Die Rückkehr der POJO Ritter

Marinero Atlántico

  • Gast
Re: Was ist Springframework (Geduld)
« Antwort #1 am: 23.04.05 - 13:40:03 »
Spring Framework soll ist eine Art glue-Framework für alles mögliche andere (Frameworks, Komponenten auf AppServern wie EJB, v.a. mehr), egal. Durch einen sogenannten Bean Container, der nach dem Inversion of Control (oder Dependency Injection) Prinzip funktioniert, kann die Initialisierung von Java Klassen in eine xml-Konfig-Datei ausgelagert werden.
Wer jemals code von einem Java-Programmierer mit einem Mindestmaß an Selbstrespekt gesehen hat, wird wissen, dass dort eine Menge Verbindungscode (Singleton-Factories, etc.)  vorhanden ist, um die Objekte zu initialisieren (und gegebenfalls die einzelnen Klassen schnell austauschen zu können).
Mit diesem Inversion of Control tut man das alles einfach in einem xml-File beschreiben.
Hier ist mein Versuch (Auszug):
Code
<beans>
<!-- DB2 Datenquelle -->
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName">
			<value>com.ibm.db2.jcc.DB2Driver</value>
		</property>
		<property name="url">
			<value>jdbc:db2:fussi2</value>
		</property>		
		<property name="username">
			<value>db2admin</value>
		</property>
		<property name="password">
			<value>kennwort</value>
		</property>
	</bean>

<!-- ibatis sqlmap config file -->
	<bean id="sqlMapClient"
		class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
		<property name="configLocation">
			<value>SqlMapConfig.xml</value>
		</property>
		<property name="dataSource"><ref bean="dataSource"/></property>
	</bean>

<!-- transaction stuff -->	
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource"><ref bean="dataSource"/></property>
	</bean>
	
	<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
		<property name="transactionManager">
			<ref bean="transactionManager"/>
		</property>
	</bean>
	
	<!-- DaoFactories Ibatis -->
	<bean id="userDAO" autowire="byName" class="de.aja.fussi.dao.ibatis.UserDaoIbatis">
	<!-- injected property: sqlMapClient -->
	</bean>

	<bean id="stockDescrDAO" autowire="byName" class="de.aja.fussi.dao.ibatis.StockDescrDaoIbatis">
	<!-- injected property: sqlMapClient -->
	</bean>
	
<bean id="stockUserDAO" autowire="byName" class="de.aja.fussi.dao.ibatis.StockUserDaoIbatis">
	<!-- injected property: sqlMapClient -->
	</bean>
	<!-- Business Facades or singletons-->
	<bean id="userRegistrationPolicy" class="de.aja.fussi.UserRegistrationPolicySimple">
	<!-- wie war das nochmal mit value. Setze value HIER -->
	</bean>
	<bean id="userManager" class="de.aja.fussi.UserManagerImpl">
		<property name="txTemplate"><ref bean="transactionTemplate"/></property>
		<property name="userDao"><ref bean="userDAO"/></property>
		<property name="stockDescrDao"><ref bean="stockDescrDAO"/></property>
		<property name="stockUserDao"><ref bean="stockUserDAO"/></property>
		<property name="userRegistrationPolicy"><ref bean="userRegistrationPolicy"/></property>
	</bean>		
</beans>
Ich brauche dann z.B. in der Klasse UserManagerImpl nur noch ein paar setter zu schreiben. Die restlichen Informationen holt er sich aus diesem xml-File.
Also z.B. Es gibt in UserManagerImpl ein property mit dem Namen userDao.
Dieses wird durch das Bean userDAO bestimmt (ref bean=)
Hier steht, dass es durch eine Instanz der Klasse UserDaoIbatis gesetzt wird.
Um diese Beziehung in dem Objekt der Klasse UserManagerImpl zu initialisieren benötigte ich dort nur noch den folgenden äusserst komplizierten code:
Code
private userDao; 
private setUserDao(userDao dao) {
   this.userDao = dao;
}
Eine Instanz des Typs UserManager (UserManagerImpl als Klasse erhalte ich dann einfach so:
Code
UserManager uManager = (UserManager) factory.getBean("userManager");

Spring enthält nicht nur diesen IOC Container sondern außerdem noch eine Menge an Zusatzklassen, um typische Enterprise-Features wie Transaktionen, Persistenz, Security, Scheduling, Webframeworks und vieles, vieles sich einfach aus dem Framework zu holen.
Das ganze führt zu wirklich wenig code und darüber hinaus zeigt das xmlConfig File noch die Struktur des Programms quasi als doku an (wenn man da ein bischen dran gewöhnt, klappt das sehr gut).
Man programmiert automatisch sehr viel gegen Interfaces. Dies führt dazu, dass die implementierenden Klassen in den Layern sehr leicht durch andere ersetzt werden können. Wenn ich keinen Bock mehr habe auf IBatis für den Zugriff auf die Datenbank, dann konfiguriere ich eben Hibernate, jakarta.ObjectRelationalBridge oder was sonst so angeboten wird und schreib halt die Klassen für Hibernate, wobei ich da sowieso auf Spring Hibernate Integrationsklassen zugreifen kann.

Hier die Schritte im Code, um ein transaktionales Insert gegen 2 Tabellen in DB2 mit zugegebenermassen nicht sehr smarten SQL-Code durchzuführen: (dies kann aus Tomcat, Websphere, einer Client Anwendung oder was auch immer aufgerufen werden)
Code
// client code
UserManager uManager = (UserManager) factory.getBean("userManager"); // hole Bean aus IOC Container
		User anUser = new User();
		anUser.setNameUser("Waldi Wuff");
		anUser.setPwd("kennwort");
		anUser.setEmail("waldi.wuff@gmail.com");
		
		try {
			uManager.requestRegistration(anUser);
		} catch (InvalidDataException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
In UserManager.requestRegistration steht:
Code
public User requestRegistration(User user) throws InvalidDataException {
		userRegistrationPolicy.validate(user);

		userRegistrationPolicy.processRegistrationRequest(user);
		saveUser(user);
		return user;
	}
Die userRegistrationPolicy wurde über das xml-Config Dokument (s.o) automatisch in das Objekt gehauen.
Die Methoden validate() und processRegistrationRequest von userRegistrationPolicy sind erstmal nicht so wichtig. Das ist einfach nur so ein bischen Template GoF Pattern (oder ist es Strategy. Egal). Jedenfalls sind das auch jeweils 2 bis 3 Zeilen code.

In saveUser wird nun die Transaktion gegen die Datenbank durchgeführt. Ich kann da verschiedenes setzen wie das Isolationslevel der Transaktion oder ob das nur eine Read-Only Transaktion ist. Ich hab mich erstmal mit dem Default begnügt (Default Einstellungen der Datenbank).

Code
public void saveUser(final User user) {
// starte neue Transaktion --> wurde auch im xml-Config File reingeschossen. 
		txTemplate.execute(new TransactionCallbackWithoutResult() {

protected void doInTransactionWithoutResult(TransactionStatus status) {
				user.setId(userDao.insertUser(user)); // mache Datenbank insert. Über iBatis
				
                              // wenn Registrierungsstatus genehmigt, dann iteriere alle Aktien auf dem Markt und tue die auch direkt in die Datenbank
				if (user.getRegStatus() == UserRegistrationPolicy.REG_STATUS_APPLIED) { 
					Iterator itStockDescrAll = stockDescrDao.getAllStockDescr()
							.iterator();
					// insert all StockUser
					while (itStockDescrAll.hasNext()) {
						Integer idStockDescr = ((StockDescr) itStockDescrAll
								.next()).getId();
						StockUser stockUser = new StockUser(user.getId()
								.longValue(), idStockDescr.intValue(), 300);
                                                // schreibe StockUser in die Datenbank
						Long idStockUser = stockUserDao
								.insertStockUser(stockUser);
						stockUser.setId(idStockUser);
						user.addStockUser(stockUser);
					}
				}

			}

		});

	}
Bezüglich rollback und commit kümmert sich das Framework. Ach ja. Wo ist das SQL?
Das läuft wie gesagt über IBatis.
Das ist in IBatis xml-Konfigurationsdateien (ausserhalb von kompilierten code) definiert. Z.B. hier:
Code
	<insert id="insertUser" parameterClass="User">
	INSERT INTO
		Person (nameUser, pwd, email, regStatus) Values
		(#nameUser#, #pwd#,#email#, #regStatus#)
		<selectKey resultClass="long" keyProperty="id" >
		Values(identity_val_local())
</selectKey>
</insert>
Die aufgerufene Methode von UserDAOIBatis sieht einfach so aus:
Code
	public Long insertUser(User user) {
		return (Long) getSqlMapClientTemplate().insert("insertUser", user);
	}

Zu Spring gibt es mittlerweile 3 gute Bücher (und das von Rod Johnson + Mannschaft kommt dann im Sommer. Die Fehlermeldungen treiben mir fast Tränen in die Augen. Ich sehe in der ersten Zeile was los ist. Jeder der um 2:00 Uhr nachts von JBoss oder auch IBatis Stacktraces angegriffen wurde, weiss das zu würdigen wissen.
« Letzte Änderung: 23.04.05 - 14:36:52 von Marinero Atlántico »

Marinero Atlántico

  • Gast
Spring Matrix
« Antwort #2 am: 24.04.05 - 15:49:56 »
Frustrierend bei Tools wie LEI oder DWF ist, dass man zu wenig Informationen bekommt, wenn etwas falsch läuft.
Bei OpenSores kann man zur Not noch selber nachschlagen. Das Problem ist nur, dass man hierfür erstmal den code verstehen muss. Das kann sehr komplex sein. Auch wenn man den Debugger von Eclipse mitlaufen lässt.
Auf einer Stufe darunter kann man sich einfach Logs konfigurieren. Ist sicher kein Easy-Reading. Aber zumindest bekommt man so ein Gefühl, was die Komponente eigentlich so ungefähr macht (inklusive aller code-generierten SQL-Statements). Ein Auszug:
Code
10859 [main.127] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager .getResource - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@c837cd] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1632847] bound to thread [main]
10875 [main.159] DEBUG org.springframework.orm.ibatis.SqlMapClientTemplate .execute - Executing action on SqlMapSession with Spring-managed JDBC connection
10875 [main.127] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager .getResource - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@c837cd] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1632847] bound to thread [main]
10875 [main.42] DEBUG java.sql.Connection .<init> - {conn-100004} Connection
10875 [main.48] DEBUG java.sql.PreparedStatement .invoke - {pstm-100005} PreparedStatement:    Select     ID as id,     nameUser as NameUser,     pwd As pwd,      email As email,     userType as userType,     version as version,     regStatus as regStatus,     money as money,     positionUser as position,     assetTotalValue As assetTotalValue,     dateCreated as dateCreated,     lastStockUpdate as lastStockUpdate         from Person where ID=?  
10875 [main.49] DEBUG java.sql.PreparedStatement .invoke - {pstm-100005} Parameters: [4]
10875 [main.50] DEBUG java.sql.PreparedStatement .invoke - {pstm-100005} Types: [java.lang.Long]
10937 [main.41] DEBUG java.sql.ResultSet .<init> - {rset-100006} ResultSet
10937 [main.184] DEBUG org.springframework.beans.factory.xml.XmlBeanFactory .getBean - Returning cached instance of singleton bean 'userDAO'
10937 [main.184] DEBUG org.springframework.beans.factory.xml.XmlBeanFactory .getBean - Returning cached instance of singleton bean 'stockDescrDAO'
10953 [main.184] DEBUG org.springframework.beans.factory.xml.XmlBeanFactory .getBean - Returning cached instance of singleton bean 'stockUserDAO'
10953 [main.61] DEBUG java.sql.ResultSet .invoke - {rset-100006} Header: [ID, NAMEUSER, PWD, EMAIL, USERTYPE, VERSION, REGSTATUS, MONEY, POSITION, ASSETTOTALVALUE, DATECREATED, LASTSTOCKUPDATE]
10953 [main.65] DEBUG java.sql.ResultSet .invoke - {rset-100006} Result: [4, Waldi Wuff1, kennwort, waldi.wuff@gmail.com, 1, 0, 5, 20000.00, 0, 0.00, 2005-04-24 00:00:00.0, 2005-04-24 15:36:08.578]
10953 [main.127] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager .getResource - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@c837cd] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1632847] bound to thread [main]
10953 [main.159] DEBUG org.springframework.orm.ibatis.SqlMapClientTemplate .execute - Executing action on SqlMapSession with Spring-managed JDBC connection
10953 [main.127] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager .getResource - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@c837cd] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1632847] bound to thread [main]
10953 [main.42] DEBUG java.sql.Connection .<init> - {conn-100007} Connection
10953 [main.48] DEBUG java.sql.PreparedStatement .invoke - {pstm-100008} PreparedStatement:    Select     ID as id,     longName as longName,     shortName As shortName,      version As version,     price as price,     created as created         from STockDescr    
10969 [main.49] DEBUG java.sql.PreparedStatement .invoke - {pstm-100008} Parameters: []
10969 [main.50] DEBUG java.sql.PreparedStatement .invoke - {pstm-100008} Types: []
11016 [main.41] DEBUG java.sql.ResultSet .<init> - {rset-100009} ResultSet
11016 [main.61] DEBUG java.sql.ResultSet .invoke - {rset-100009} Header: [ID, LONGNAME, SHORTNAME, VERSION, PRICE, CREATED]
11031 [main.65] DEBUG java.sql.ResultSet .invoke - {rset-100009} Result: [1, Bayern München, BMÜ, 0, 0.00, 2005-04-24 15:27:27.796002]
11031 [main.65] DEBUG java.sql.ResultSet .invoke - {rset-100009} Result: [2, Borussia Mönchengladbach, BMÖ, 0, 0.00, 2005-04-24 15:27:27.796004]
11031 [main.65] DEBUG java.sql.ResultSet .invoke - {rset-100009} Result: [3, Schalke 04, S04, 0, 0.00, 2005-04-24 15:27:27.812]
11031 [main.127] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager .getResource - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@c837cd] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1632847] bound to thread [main]
11031 [main.159] DEBUG org.springframework.orm.ibatis.SqlMapClientTemplate .execute - Executing action on SqlMapSession with Spring-managed JDBC connection
11031 [main.127] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager .getResource - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@c837cd] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1632847] bound to thread [main]
11031 [main.42] DEBUG java.sql.Connection .<init> - {conn-100010} Connection
11031 [main.48] DEBUG java.sql.PreparedStatement .invoke - {pstm-100011} PreparedStatement:   INSERT INTO   StockUser (idUser, idStockDescr, amount) Values   (?, ?,?)    
11031 [main.49] DEBUG java.sql.PreparedStatement .invoke - {pstm-100011} Parameters: [4, 1, 300]
11031 [main.50] DEBUG java.sql.PreparedStatement .invoke - {pstm-100011} Types: [java.lang.Long, java.lang.Integer, java.lang.Integer]
11062 [main.48] DEBUG java.sql.PreparedStatement .invoke - {pstm-100012} PreparedStatement:    Values(identity_val_local()) 
11062 [main.49] DEBUG java.sql.PreparedStatement .invoke - {pstm-100012} Parameters: []
11078 [main.50] DEBUG java.sql.PreparedStatement .invoke - {pstm-100012} Types: []
11078 [main.41] DEBUG java.sql.ResultSet .<init> - {rset-100013} ResultSet
11078 [main.61] DEBUG java.sql.ResultSet .invoke - {rset-100013} Header: [1]
11078 [main.65] DEBUG java.sql.ResultSet .invoke - {rset-100013} Result: [10]
11078 [main.127] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager .getResource - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@c837cd] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1632847] bound to thread [main]
11078 [main.159] DEBUG org.springframework.orm.ibatis.SqlMapClientTemplate .execute - Executing action on SqlMapSession with Spring-managed JDBC connection
11078 [main.127] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager .getResource - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@c837cd] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1632847] bound to thread [main]
11078 [main.42] DEBUG java.sql.Connection .<init> - {conn-100014} Connection
11078 [main.48] DEBUG java.sql.PreparedStatement .invoke - {pstm-100015} PreparedStatement:   INSERT INTO   StockUser (idUser, idStockDescr, amount) Values   (?, ?,?)    
11078 [main.49] DEBUG java.sql.PreparedStatement .invoke - {pstm-100015} Parameters: [4, 2, 300]
11078 [main.50] DEBUG java.sql.PreparedStatement .invoke - {pstm-100015} Types: [java.lang.Long, java.lang.Integer, java.lang.Integer]
11094 [main.48] DEBUG java.sql.PreparedStatement .invoke - {pstm-100016} PreparedStatement:    Values(identity_val_local()) 
11094 [main.49] DEBUG java.sql.PreparedStatement .invoke - {pstm-100016} Parameters: []
11094 [main.50] DEBUG java.sql.PreparedStatement .invoke - {pstm-100016} Types: []
11094 [main.41] DEBUG java.sql.ResultSet .<init> - {rset-100017} ResultSet
11094 [main.61] DEBUG java.sql.ResultSet .invoke - {rset-100017} Header: [1]
11094 [main.65] DEBUG java.sql.ResultSet .invoke - {rset-100017} Result: [11]
11094 [main.127] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager .getResource - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@c837cd] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1632847] bound to thread [main]
11094 [main.159] DEBUG org.springframework.orm.ibatis.SqlMapClientTemplate .execute - Executing action on SqlMapSession with Spring-managed JDBC connection
11109 [main.127] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager .getResource - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@c837cd] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1632847] bound to thread [main]
11109 [main.42] DEBUG java.sql.Connection .<init> - {conn-100018} Connection
11109 [main.48] DEBUG java.sql.PreparedStatement .invoke - {pstm-100019} PreparedStatement:   INSERT INTO   StockUser (idUser, idStockDescr, amount) Values   (?, ?,?)    
11109 [main.49] DEBUG java.sql.PreparedStatement .invoke - {pstm-100019} Parameters: [4, 3, 300]
11109 [main.50] DEBUG java.sql.PreparedStatement .invoke - {pstm-100019} Types: [java.lang.Long, java.lang.Integer, java.lang.Integer]
11109 [main.48] DEBUG java.sql.PreparedStatement .invoke - {pstm-100020} PreparedStatement:    Values(identity_val_local()) 
11109 [main.49] DEBUG java.sql.PreparedStatement .invoke - {pstm-100020} Parameters: []
11109 [main.50] DEBUG java.sql.PreparedStatement .invoke - {pstm-100020} Types: []
11125 [main.41] DEBUG java.sql.ResultSet .<init> - {rset-100021} ResultSet
11125 [main.61] DEBUG java.sql.ResultSet .invoke - {rset-100021} Header: [1]
11125 [main.65] DEBUG java.sql.ResultSet .invoke - {rset-100021} Result: [12]
11125 [main.127] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager .getResource - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@c837cd] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1632847] bound to thread [main]
11125 [main.523] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager .triggerBeforeCommit - Triggering beforeCommit synchronization
11125 [main.538] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager .triggerBeforeCompletion - Triggering beforeCompletion synchronization
11125 [main.396] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager .commit - Initiating transaction commit
11125 [main.201] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager .doCommit - Committing JDBC transaction on connection [com.ibm.db2.jcc.uw.UWConnection@1af33d6]
11125 [main.568] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager .triggerAfterCompletion - Triggering afterCompletion synchronization
11125 [main.250] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager .clearSynchronization - Clearing transaction synchronization
11125 [main.175] DEBUG org.springframework.transaction.support.TransactionSynchronizationManager .unbindResource - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@c837cd] for key [org.springframework.jdbc.datasource.DriverManagerDataSource@1632847] from thread [main]
11141 [main.254] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager .doCleanupAfterCompletion - Closing JDBC connection [com.ibm.db2.jcc.uw.UWConnection@1af33d6] after transaction
11141 [main.334] DEBUG org.springframework.jdbc.datasource.DataSourceUtils .doCloseConnectionIfNecessary - Closing JDBC connection

Marinero Atlántico

  • Gast
Die Dunkle Seite der Macht
« Antwort #3 am: 24.04.05 - 23:15:58 »
Open Sores hat natürlich auch seine Schattenseiten.
Zum Beispiel hat man nicht so tolle Marketingpersönlichkeiten wie Ed Brill, die die Moral stärken  ;D
Nein Spaß bei Seite.
Ein auf openSource beruhendes Programm hat meistens Tonnen von jars im Lib Verzeichnis. Also Zusatzklassen zu Standard Java Klassen. Deployed (ein bischen wie installiert) man das Programm in einem komplexeren Container (z.B. Tomcat oder Websphere) kann es schon mal Probleme damit geben, dass die falsche Version einer bestimmten Klasse gezogen wird. Deshalb sollte man sich gut mit Classpath-Angelegenheiten in Java auskennen, was nicht unbedingt trivial ist und kompliziert werden kann. Ich finde übrigens, dass in dieser Angelegenheit der gerne kritisierte Websphere eine gute Lösung hat.
Rechtlich macht dieses openSores Einbinden meist btw. keine Probleme. Gerade in Java. Die meisten Lizenztypen erlauben auch kommerziellen Produkten, dass man openSores nutzt. Man darf nur die Libraries nicht verändern und muß auf das openSores aufmerksam machen. Tatsächlich rührt man in der aller-, allergrößter Regel die openSores Klassen nicht an, sondern benutzt sie einfach als Komponenten/Zusatzlibraries.
Ein weiterer Punkt ist, dass man eine Menge xml-Konfigurationsdateien hat. Viele Libraries sind so aufgebaut, dass man sie in einem gut definierter xml-Datei konfiguriert (was sehr einfach ist). Nur gibt es dann eben für die verschiedenen Komponenten unterschiedliche xml-Dateien. Eine für ibatis, eine für spring, eine für struts und eine für log4j-Logging. Gerade mit Logging sollte man sich ein bischen auskennen, weil die meisten Libraries erwarten, dass für sie Logging aktiviert ist (was vernünftig ist). Über die Konfiguration von den beiden Arten von Logging (Log4j und Sun-Logging) kann man das dann auch in der Produktivumgebung für Performance ausschalten (und bei Problemen wieder anschalten).
Ein weiteres Problem ist, dass viele openSores Projekte sehr schlecht dokumentiert sind (veraltet, nicht vorhanden, uvam.). Deshalb präferiere ich explizit Libraries, die gut dokumentiert sind. Manche sind nämlich extrem gut dokumentiert (Beispiele: Hibernate, Ibatis, Log4j, Spring).
Hier ist ein Bild von den ganzen Libraries, die bei meinem MIni-Projekt dabei sind:
Das sind so viele, weil ein Projekt wie Spring nicht einfach eine spring.jar hat, sondern Tonnnen von anderen Libraries braucht, die aber immer im Lib-Verzeichnis des openSores Projekts zu finden sind.
Manche brauchen da gar nicht zu sein, weil ich bestimmte features der frameworks nicht nutze, aber darüber mache ich mir im Endstadium des Projekts einen Kopf.
« Letzte Änderung: 24.04.05 - 23:19:11 von Marinero Atlántico »

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz