Leichtgewichtige Architekturen mit Spring, JPA, Maven und Groovy
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Leichtgewichtige Architekturen mit Spring, JPA, Maven und Groovy

  • 4,895 views
Uploaded on

Gute Software sollte sich an der entsprechenden Fachdomäne orientieren und nicht an der zugrundeliegenden Technologie. Um dies zu erreichen, wird allerdings eine Basis benötigt, die technisch......

Gute Software sollte sich an der entsprechenden Fachdomäne orientieren und nicht an der zugrundeliegenden Technologie. Um dies zu erreichen, wird allerdings eine Basis benötigt, die technisch ausgereift ist ohne Einschränkungen für die Entwicklung. Eine solche Basis kann mit dem Springframework geschaffen werden. Die Kombination von Spring, Annotations, Java Persistence (JPA) und Unit-Testing erlaubt eine flexible und modulare Architektur und könnte eine mögliche technische Basis für ein solches Softwaresystem sein.

Dieser Vortrag stellt einen Lösungsansatz anhand eines einfachen Beispiels vor. Die Aufbereitung der Inhalte orientiert sich dabei an einem typischen test-zentrierten Entwicklungsprozess. Folgende Themen werden angesprochen:

* Einleitung Spring und JPA, Maven, Groovy
* Projektstruktur
* Entwicklung der API (der Schnittstellen)
* Test-getriebene Entwicklung der Implementierung
* Spring-unterstützte Integrationstests

Ausblick:

* Spring 2.5 - mehr Annotations; Verwaltung von Entities mit Spring
* Webschicht - Anbindung einer Webanwendung mit Java Server Faces (JSF)
* Spring-Webservices - Contract-First Webservices mit Spring-WS 1.0

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
4,895
On Slideshare
4,777
From Embeds
118
Number of Embeds
4

Actions

Shares
Downloads
30
Comments
0
Likes
0

Embeds 118

http://www.thorsten-kamann.de 89
http://www.slideshare.net 18
http://blog.kamann.info 10
http://static.slidesharecdn.com 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1.  
  • 2. Ziele der Software-Entwicklung…
  • 3. Was ist „gute“ Software?
  • 4. … und was man dafür braucht
  • 5. Das Thema heute ist:
  • 6.  
  • 7. Technische Infrastruktur
  • 8. Technische Infrastruktur
  • 9. Technische Infrastruktur
  • 10. Technische Infrastruktur
  • 11. Technische Infrastruktur
  • 12.  
  • 13. Leichtgewichtige Architekturen?
  • 14. Leichtgewichtige Architekturen
  • 15. Leichtgewichtige Architekturen
  • 16. Leichtgewichtige Architekturen
  • 17.  
  • 18. Beispiel: Das Domänenmodell
  • 19. Beispiel: Komponenten
  • 20. Beispiel: Komponenten
  • 21. Beispiel: Komponenten
  • 22. Beispiel: Komponenten
  • 23. Beispiel: Komponenten
  • 24. Beispiel: Komponenten
  • 25.  
  • 26. Exkurs: Maven
  • 27. Exkurs: Maven - Repositories
  • 28. Exkurs: Maven
  • 29. Exkurs: Maven
  • 30. Exkurs: Maven - Abhängigkeiten <project> <modelVersion>4.0.0</modelVersion> <groupId>spring2.jpa.basic</groupId> <artifactId>spring2-jpa-basic-impl</artifactId> <version>1.0.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> <version>2.5.1</version> </dependency> […] </dependencies> […] </project> Artefakt-Beschreibung SNAPSHOT! Abhängigkeit liefert alle benötigten Bibliotheken
  • 31. Exkurs: Maven-PlugIns <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.4-SNAPSHOT</version> <configuration> <suiteXmlFiles> <suiteXmlFile>quick-suite.xml</suiteXmlFile> </suiteXmlFiles> </configuration> </plugin> </plugins> </build> PlugIn für Testausführung Lädt Testsuite
  • 32.  
  • 33. Exkurs: Spring [Was ist Spring?] Inversion of Control Ansammlung von API's Programmier- modell
  • 34. Exkurs: Spring [Komponenten] Spring Core AOP Spring AOP AspectJ-Integration DAO Spring JDBC Transaction- Management ORM JPA Hibernate Toplink JDO JEE JMX JMS JCA Remoting EJB's Email WEB Spring MVC Struts WebWork Tapestry JSF PDF Portlets
  • 35. Exkurs: Spring [Features]
  • 36. Exkurs: Spring [Features]
  • 37. Exkurs: Spring [Features]
  • 38. Exkurs: Spring [Features]
  • 39. Exkurs: Spring [Features]
  • 40.  
  • 41. Exkurs: Java Persistence API
  • 42. Exkurs: Java Persistence API
  • 43. Exkurs: Java Persistence API
  • 44.  
  • 45. Exkurs: Groovy
  • 46. Exkurs: Groovy
  • 47. Exkurs: Groovy The Groovy Truth Runtime type Evaluation criterion required for truth Boolean Booleanwert muss true sein Matcher Der reguläre Ausdruck muss mindestens 1 Treffer haben Collection Die Collection darf nicht leer sein Map Die Map darf nicht leer sein String Der String darf ebenfalls nicht leer sein Number Muss ungleich 0 sein Alles andere Die Objektreferenz muss ungleich null sein
  • 48. Exkurs: Groovy – Listen und Ranges def list = [„item1“, „item2“, „item3“] assert list.size() def emptyList = [] assert !emptyList list << „item4“ assert list.size() == 4 def range = [1..4] assert range.size() == 4 def range1 = [1..<4] assert range1.size() == 3 Eine Liste mit 3 Einträgen Eine leere Liste Der ersten Liste wird ein Element hinzugefügt Eine Range mit den Werten 1, 2, 3, 4 wird erstellt Eine Range mit den Werten 1, 2, 3 wird erstellt
  • 49. Exkurs: Groovy – Listen und Closures def list = [„item1“, „item2“, „item3“] list.each{ print it+“ „} > item1 item2 item3 assert list.find{it==„item2“} list = [„a1“, „a2“, „a3“, „i1“, „i2“] assert list.findAll{ it.startsWith(„i“)}.size() == 3 Each-Closure Ein bestimmtes Element finden Eine Anzahl an Elementen aus der Liste finden
  • 50. Exkurs: Groovy - Maps def map = [key1: „value1“, key2: „value2“] assert map.size() == 2 assert map.key1 == „value1“ map.key3 == „value3“ assert map.size() == 3 assert map[„key2“] == „value2“ assert map.get(„key2“) == „value2“ def emptyMap = [:] assert !emptyMap Eine Map mit 2 Einträgen wird erstellt Ein 3. Eintrag wird hinzugefügt Alternative Zugriffsmethode auf die Elemente der Map Eine leere Map wird erstellt
  • 51.  
  • 52.  
  • 53. Beispiel: API - Domänenmodell
  • 54. Beispiel: API
  • 55.  
  • 56. Zum Beispiel: Impl - Entities @Entity(table=„CUSTOMERS“) public class Customer{ @Id @GeneratedValue( strategy = GenerationType.AUTO) private Long id; @OneToOne(targetEntity = Address.class, cascade = { CascadeType.ALL}) private IAddress address; @Column(length = 40) private String firstName; … } Entity auf Tabelle CUSTOMERS mappen Primary Key 1-zu-1 Beziehung Konfiguration einer Column in der Tabelle CUSTOMERS
  • 57. Zum Beispiel: Impl – persistence.xml <persistence …> <persistence-unit name=&quot;spring2-jpa-basic-persistence-unit&quot;> <properties> <property name=&quot;hibernate.jdbc.batch_size&quot; value=&quot;0&quot;/> <property name=&quot;hibernate.default_batch_fetch_size&quot; value=&quot;5&quot;/> […] </properties> </persistence-unit> </persistence> Eindeutiger Name der Persistence-Unit Eigenschaften der Persistence-Unit
  • 58. Zum Beispiel: Impl – DAO‘s @Repository public class CustomerDao implements ICustomerDao { @PersistenceContext( unitName = &quot;spring2-jpa-basic-persistence-unit&quot;) protected EntityManager entityManager; public List<ICustomer> findAll() { return entityManager .createQuery(&quot;from Customer c&quot;) .getResultList(); } […] } Sorgt für die Übersetzung von Exceptions Injection des Entity-Managers über Spring Plain Java
  • 59. Zum Beispiel: Impl – Spring-Config <bean class=„PersistenceAnnotationBeanPostProcessor&quot; /> <bean class=„PersistenceExceptionTranslationPostProcessor&quot; /> Support der Annotations in den DAO‘s Excpetion Translation
  • 60. Zum Beispiel: Impl – Spring-Config <bean id=&quot;entityManagerFactory&quot; class=„LocalContainerEntityManagerFactoryBean&quot;> <property name=&quot;dataSource&quot; ref=&quot;dataSource&quot; /> <property name=&quot;jpaVendorAdapter&quot;> <bean class=„HibernateJpaVendorAdapter&quot;> <property name=&quot;databasePlatform&quot; value=&quot;${jpa.provider.databasePlatform}&quot; /> <property name=&quot;showSql&quot; value=&quot;${jpa.provider.showSql}&quot; /> <property name=&quot;generateDdl&quot; value=&quot;${jpa.provider.generateDdl}&quot; /> </bean> </property> </bean> JPA-Vendor Eigenschaften des JPA-Vendors Kein JNDI
  • 61. Zum Beispiel: Impl – Spring-Config <bean id=&quot;dataSource&quot; class=„DriverManagerDataSource&quot; p:driverClassName=&quot;${jdbc.driver.classname}&quot; p:url=&quot;${jdbc.connection.url}&quot; p:username=&quot;${jdbc.connection.uid}&quot; p:password=&quot;${jdbc.connection.pwd}&quot; /> DataSource Konfiguration
  • 62. Zum Beispiel: Impl - Services @Transactional public class CustomerService implements ICustomerService { private ICustomerDao customerDao; private IAddressDao addressDao; […] @Transactional(readOnly = true) public List<ICustomer> findAllCustomers() { return customerDao.findAll(); } […] }
    • Dieser Service nimmt an
    • einer Transaction teil:
    • PROPAGATION_REQUIRED
    • READWRITE
    • ROLLBACKFOR:
      • jede RuntimeException
    Diese Methode hat nur einen lesenden Zugriff
  • 63. Zum Beispiel: Impl – Spring-Config <bean id=&quot;transactionManager&quot; class=„JpaTransactionManager&quot;> <property name=&quot;entityManagerFactory&quot; ref=&quot;entityManagerFactory&quot; /> </bean> <tx:annotation-driven transaction-manager=&quot;transactionManager&quot; /> JPA Transaction-Manager Transaktionen werden per Annotations konfiguriert
  • 64. Zum Beispiel: Impl – Spring-Config <tx:advice id=&quot;txAdvice&quot; transaction-manager=&quot;transactionManager&quot;> <tx:attributes> <tx:method name=&quot;get*&quot; read-only=&quot;true&quot; /> <tx:method name=&quot;*&quot; /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id=“dataaccess&quot; expression=&quot;execution(* […].dataaccess.*.*(..))&quot; /> <aop:advisor advice-ref=&quot;txAdvice&quot; pointcut-ref=“dataaccess&quot; /> </aop:config> Alternative Transaktionskonfiguration
  • 65. Zum Beispiel: Problem Annotation @Service public class CustomerService{ @Autowired private ICustomerDao customerDao; } Spring-eigene Annotations @Target(value = ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Service public @interface MyService { } Eigene Annotation Basierend auf @Service @MyService public class CustomerService{ } Verwendung der eigenen Annotation
  • 66. Zum Beispiel: Impl – Unit Testing
  • 67. Zum Beispiel: Impl – Unit Testing
  • 68. Zum Beispiel: Impl – Unit Testing public final void testChangeAddress() { IAddress expAddress = new Address( street: &quot;s1&quot;, city: &quot;c1&quot;, country: &quot;c1&quot;, zipCode: &quot;z1&quot;); def addressDao = [ store:{entity -> expAddress}] as IAddressDao ICustomerService customerService = new CustomerService(addressDao: addressDao) def result = customerService .changeAddress(expAddress) assert expAddress == result } Erzeugung einer neuen Instanz mit Constructor- Enhancement Implementierung des IAddressDao Neue Instanz des ICustomerService Ausführen und Ergebnis vergleichen
  • 69.  
  • 70. Zum Beispiel: Webapp
  • 71.  
  • 72. Zum Beispiel: Integration
  • 73. Zum Beispiel: Integration
  • 74. Zum Beispiel: Integration
  • 75. Zum Beispiel: Integration
  • 76. Zum Beispiel: Integration
  • 77. Zum Beispiel: Integration
  • 78. Zum Beispiel: Integration (Selenium)
  • 79.
    • WW
    Zum Beispiel: Integration (Testcode) public class SimpleWebtest{ @BeforeClass() @Parameters([&quot;browser&quot;]) final void prepareSelenium(String browser){} @BeforeMethod final void startSelenium(){} @AfterMethod final void stopSelenium(){} @Test final void testTheStuff(){} } Parameterisierte Methode wird einmal pro Klasseninstanz ausgeführt Wird pro Testmethode ausgeführt
  • 80. Zum Beispiel: Integration (Testsuite) <suite name=&quot;gidp-sample-integration&quot;> <test verbose=&quot;2&quot; name=&quot;FFIntegrationtests&quot; annotations=&quot;JDK&quot;> <parameter name=&quot;browser&quot; value=&quot;firefox&quot;/> <packages> <package name=“[…].integration&quot;/> </packages> </test> <test verbose=&quot;2&quot; name=&quot;IEIntegrationtests&quot; annotations=&quot;JDK&quot;> <parameter name=&quot;browser&quot; value=&quot;iexplore&quot;/> <packages> <package name=&quot;de.gidp.sample.integration&quot;/> </packages> </test> </suite>
  • 81.  
  • 82. Fazit
  • 83. Fazit
  • 84.  
  • 85. Ressourcen: Links
  • 86. Über den Referenten