Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kristian Marinkovic and Peter Niederwieser on Tapestry IOC

Kristian Marinkovic and Peter Niederwieser on Tapestry IOC

More Decks by Enterprise Java User Group Austria

Other Decks in Technology

Transcript

  1. Peter Niederwieser, Kristian Marinkovic 2 Tapestry IoC Vortragende • Kristian

    Marinkovic • Freier Software Entwickler • Lead Developer bei Porsche Informatik • Berater bei Smarter Ecommerce • Peter Niederwieser • Senior Developer bei Smarter Ecommerce • Groovy Committer • Autor von Spock Framework
  2. Peter Niederwieser, Kristian Marinkovic 3 Tapestry IoC Agenda • Warum

    Tapestry IoC • Tapestry IoC Basics • Tapestry IoC in der Praxis • Porsche Informatik (POI) • Smarter Ecommerce (Smec) • Zusammenfassung • Beyond Tapestry IoC
  3. Peter Niederwieser, Kristian Marinkovic 4 Tapestry IoC Warum Tapestry IoC

    (I) • Java Konfiguration • Kein XML • Typsicherheit • Annotationen • Modul Konzept • Basis für hochmodulare Anwendungen • Schrittweise Erweiterung von Komponenten • Convention over Configuration • Jedes Modul sieht gleich aus
  4. Peter Niederwieser, Kristian Marinkovic 5 Tapestry IoC Warum Tapestry IoC

    (II) • Contributions • Ähnliches Konzept wie Extension-Points und Extensions in Eclipse • Drop-In Jars • manifest.mf enthält Tapestry-Modules Eintrag mit Module Klasse • Bei Startup werden angegebene Klassen zur Registry hinzugefügt
  5. Peter Niederwieser, Kristian Marinkovic 6 Tapestry IoC Tapestry IoC Basics

    – Background • Sub-Projekt des Tapestry 5 Web Frameworks • Open-source / Apache Software License 2.0 – http://tapestry.apache.org/tapestry5.1/tapestry-ioc/ • Autor Howard Lewis Ship • APIs inspiriert von Google Guice
  6. Peter Niederwieser, Kristian Marinkovic 7 Tapestry IoC Tapestry IoC Basics

    – Modules (I) • Konfiguration erfolgt über Module • Java Klasse zum Definieren/Deklarieren der Services – IoC Services == Spring Beans – Keine Basisklasse • Folgen bestimmter Namenskonvention (*Module.java) package at.ejug.demo; import org.apache.tapestry5.ioc.annotations.SubModule; @SubModule(AnotherModule.class) public class ServiceModule { } private void start() { RegistryBuilder builder = new RegistryBuilder(); builder.add(ServiceModule.class); registry = builder.build(); }
  7. Peter Niederwieser, Kristian Marinkovic 8 Tapestry IoC Tapestry IoC Basics

    – Modules (II) • Beim Startup werden Methoden des Moduls analysiert • build prefix definiert ein Service • contribute prefix erweitert ein Service • advise prefix für AOP • public void static bind(ServiceBinder binder)
  8. Peter Niederwieser, Kristian Marinkovic 9 Tapestry IoC Tapestry IoC Basics

    – Services • Es gibt mehrere Möglichkeiten, Services zu definieren • Via build Methode • Via bind Methode public class BinderServiceModule { public static void bind(ServiceBinder binder) { binder.bind(ServiceA.class, ServiceAImpl.class); binder.bind(ServiceB.class); } } public class ServiceModule { public ServiceA buildServiceA() { return new ServiceAImpl(); } public ServiceB buildServiceB() { return new ServiceB(); } } Optionale Service Id binder.bind(ServiceB.class).withId("ServiceB"); Implementierung muss nicht angegeben werden, falls im gleichen Package
  9. Peter Niederwieser, Kristian Marinkovic 10 Tapestry IoC Tapestry IoC Basics

    – Injection (I) • Mehrere Möglichkeiten zur Service Injection • Typbasierte Injection – Via builder Method Konvention • Konstruktor von SecondImpl erwartet Objekt von Typ First public class InjectionModule { public First buildFirst() { return new FirstImpl(); } public Second buildSecond(First first) { return new SecondImpl(first); } } – Via automatic Injection • Analyse der Service Konstruktoren public class AutomaticInjectionModule { public static void bind(ServiceBinder binder) { binder.bind(First.class, FirstImpl.class); binder.bind(Second.class, SecondImpl.class); } }
  10. Peter Niederwieser, Kristian Marinkovic 11 Tapestry IoC Tapestry IoC Basics

    – Injection (II) • Namensbasierte Injection • Auch auf builder Methode anwendbar public class SecondImpl implements Second { private final First first; public SecondImpl(@InjectService("betterFirst") First first) { this.first = first; } } • Module Injection • Oft benötigte Services können direkt ins Modul injected werden public class ModuleInjectionModule { private final First first; public ModuleInjectionModule(First first) { this.first = first; } public Second buildSecond() { return new SecondImpl(first); }
  11. Peter Niederwieser, Kristian Marinkovic 12 Tapestry IoC Tapestry IoC Basics

    – Injection (III) • Marker Annotation = Refactoring Safe (Guice) • Jeder Service kann durch eine eigene Annotation spezifiziert werden • Auch auf builder Methoden anwendbar public class MarkerInjectionModule { public static void bind(ServiceBinder binder) { binder.bind(First.class, FirstImpl.class).withId("first"); binder.bind(First.class, BetterFirst.class) .withId("better").withMarker(Better.class); binder.bind(Second.class, SecondImpl.class); } } public class SecondImpl implements Second { private final First first; public SecondImpl(@Better First first) { this.first = first; } }
  12. Peter Niederwieser, Kristian Marinkovic 13 Tapestry IoC Tapestry IoC Basics

    – Contributions (I) • Verteilte Konfiguration über Contributions • Ein Service kann aus versch. Modulen Contributions erhalten public class StringSourceImpl implements StringSource { private final Collection<String> contrib; public StringSourceImpl(Collection<String> contrib) { this.contrib = contrib; } public Collection<String> getStrings() { return contrib; } } public class ContributionModule { public static void bind(ServiceBinder binder) { binder.bind(StringSource.class, StringSourceImpl.class); } public void contributeStringSource(Configuration<String> contrib) { contrib.add("tapestry ioc"); contrib.add("spring"); contrib.add("guice"); }
  13. Peter Niederwieser, Kristian Marinkovic 14 Tapestry IoC Tapestry IoC Basics

    – Contributions (II) • Folgende Contribution Typen werden unterstützt • Configuration → Collection • MappedConfiguration → Map • OrderedConfiguration → List – Angabe der Reihenfolge mit Constraints public class OrderedModule { public void contributeFilter(OrderedConfiguration<Long> values) { values.add("tapestry", Long.valueOf(5l), "before:spring"); values.add("spring", Long.valueOf(3l), "before:guice", "after:tapestry"); values.add("guice", Long.valueOf(2l), "after:*"); } }
  14. Peter Niederwieser, Kristian Marinkovic 15 Tapestry IoC Tapestry IoC Basics

    – Service Lifecycles (I) • Alle Services sind per default Singletons • Eine Instanz pro Container • Alle Services sind per default lazy • Werden erst beim ersten Zugriff instantiiert • Jeder Service wird durch einen Proxy repräsentiert – Wie in Spring <aop:scoped-proxy/> – Daher Injection zwischen verschiedenen Scopes uneingeschränkt möglich • Können als eager definiert werden → Initialisierung beim Startup – @EagerLoad Annotation – ServiceBinder.bind().eagerLoad()
  15. Peter Niederwieser, Kristian Marinkovic 16 Tapestry IoC Tapestry IoC Basics

    – Service Lifecycles (II) • PerThread-Lifecycle • Für jeden neuen Thread wir der Service neu instantiiert – In Spring abbildbar mit <aop:scoped-proxy/> • Injection wie bei Singleton Services • Nur bei Services mit Interface • Deklariert via – Annotation auf builder Methode – Annotation auf Implementierung – bind Aufruf @Scope(ScopeConstants.PERTHREAD) public class ThreadedImpl implements Threaded {}
  16. Peter Niederwieser, Kristian Marinkovic 17 Tapestry IoC Tapestry IoC Basics

    – Service Lifecycles (III) • Konkretes Beispiel für PerThread Scope • Tapestry-Hibernate Integration → Session Injection public class Repository { private final Session session; public Repository(Session session) { this.session = session; } public String findById(Long id) { return (String) session.load(String.class, id); } }
  17. Peter Niederwieser, Kristian Marinkovic 18 Tapestry IoC Tapestry IoC Basics

    – Service Override • Service Overrides überschreiben bestehende Services • Contribution zum ServiceOverrides Service public class OverridesModule { public static void bind(ServiceBinder binder) { binder.bind(SomeService.class, NewService.class).withId("new"); } public void contributeServiceOverrides( MappedConfiguration<Class, Object> overrides, @InjectService("new") SomeService newService) { overrides.add(SomeService.class, newService); } }
  18. Peter Niederwieser, Kristian Marinkovic 19 Tapestry IoC Tapestry IoC Basics

    – Chain of Command Builder • ChainBuilder • Erstellt aus einer Contribution eine Chain-of-Command public class ChainModule { public Command buildCommand(List<Command> commands, ChainBuilder builder) { return builder.build(Command.class, commands); } public void contributeCommand(OrderedConfiguration<Command> commands) { commands.addInstance("blue", BlueCommand.class, "after:*"); commands.addInstance("red", RedCommand.class, "before:blue"); commands.add("green", new GreenCommand(), "before:*"); } } public class Executor { private final Command command; public Executor(Command command) { this.command = command; } public void doSomething() { command.process(); } }
  19. Peter Niederwieser, Kristian Marinkovic 20 Tapestry IoC Tapestry IoC Basics

    – Strategy Builder • StrategyBuilder • Generiert aus einer Contribution eine Strategy für versch. Typen public interface Printer<T> { void print(T value); } public class StrategyModule { public Printer buildPrinter(Map<Class, Printer> contrib, StrategyBuilder builder) { return builder.build(Printer.class, contrib); } public void contributePrinter(MappedConfiguration<Class, Printer> contrib) { contrib.add(String.class, new StringPrinter()); contrib.add(BigDecimal.class, new BigDecimalPrinter()); } • PipelineBuilder
  20. Peter Niederwieser, Kristian Marinkovic 21 Tapestry IoC Tapestry IoC bei

    Smarter Ecommerce (I) • Aufgabenstellung • Verschiedene Applikationen mit gemeinsamer Codebasis • Interne Web-Applikation • Von außen zugängliche Dienste – Landing Pages – Online-Suche – Produkt-Empfehlungen • Administrations-Tools – Datenbank-Migration
  21. Peter Niederwieser, Kristian Marinkovic 22 Tapestry IoC Tapestry IoC bei

    Smarter Ecommerce (II) • Projektüberblick • Projektstart: Anfang 2009 • 5 Entwickler • > 50 Tapestry-Module • 50.000 LOC • Technologien: Tapestry Web/IoC, Java, Groovy, Hadoop, HBase, Lucene, Quartz, Maven, …
  22. Peter Niederwieser, Kristian Marinkovic 23 Tapestry IoC Tapestry IoC bei

    Smarter Ecommerce (III) • Projektstruktur business core model web support commons Intern Extern Admin
  23. Peter Niederwieser, Kristian Marinkovic 24 Tapestry IoC Tapestry IoC bei

    Smarter Ecommerce (IV) • Modulstruktur • Published area – öffentlich zugänglich • Module area - Moduldefinition • Internal area – modul-interne Klassen • Zugriffsregeln • Published A → Published B OK • Internal A → Published B OK • Published A → Internal B Fehler • Überprüfung mit Classycle (http://classycle.sourceforge.net/)
  24. Peter Niederwieser, Kristian Marinkovic 25 Tapestry IoC Tapestry IoC bei

    Smarter Ecommerce (V) • Konfiguration • System properties • Application defaults (per Applikation) • • • • Factory defaults (per Module) public static void contributeApplicationDefaults( MappedConfiguration<String, String> configuration) throws IOException { // read config values from configuration file // add config values to configuration object } public static void contributeFactoryDefaults( MappedConfiguration<String, String> configuration) throws IOException { // read config values from module configuration file // add config values to configuration object }
  25. Peter Niederwieser, Kristian Marinkovic 26 Tapestry IoC Tapestry IoC bei

    Smarter Ecommerce (VI) • Konfiguration • Verwendung in Service • Automatische Typ-Konvertierung public class PersistenceServiceImpl implements PersistenceService { public PersistenceServiceImpl( @Symbol(PersistenceConfigSymbols.TABLE_NAME) String tableName, @Symbol(PersistenceConfigSymbols.TIMEOUT_MILLIS) long timeoutMillis) { // initialize service } }
  26. Peter Niederwieser, Kristian Marinkovic 27 Tapestry IoC Tapestry IoC bei

    Smarter Ecommerce (VII) • Service mit Contributions am Beispiel EventBroker public class EventModule { public static EventBrokerService buildEventBrokerService( Collection<EventReceiver> receivers) { EventBrokerServiceImpl service = new EventBrokerServiceImpl(receivers); service.start(); return service; } } public class IndexingModule { public static IndexingService build(...) { ... } public static void contributeEventBrokerService( Configuration<EventReceiver> receivers, IndexingService indexingService) { receivers.add(indexingService); } }
  27. Peter Niederwieser, Kristian Marinkovic 28 Tapestry IoC Tapestry IoC bei

    Smarter Ecommerce (VIII) • Demo: Integrationstest am Beispiel EventBroker
  28. Peter Niederwieser, Kristian Marinkovic 29 Tapestry IoC Tapestry IoC bei

    der Porsche Informatik (I) • Ziele • Web Applikation zur Unterstützung der GW Prozesses – Eingang → Aufbereitung → Angebot → Verkauf • Produktlinienkonzept – Einfache Konfiguration (z.B.: Menü Struktur) – Mandantenfähigkeit • Orientierung an Domain Driven Design • Wartbarkeit • Einsatz von Open Source Software / Libraries – Tapestry 5, Tapestry IoC, Hibernate, Liquibase, Maven, Metro, Quartz, Lucene, Drools, Tomcat, jetty, TestNG, Mockito, fop, Continuum, Trac ...
  29. Peter Niederwieser, Kristian Marinkovic 30 Tapestry IoC Tapestry IoC bei

    der Porsche Informatik (II) • Modul Struktur (ca. 70 modules) organization web logistic web valuation web invoice web ... ... Fachliche Frontend Module organization logistic valuation invoice ... ... Fachliche Backend Module 1:1 Mapping Common Supporting Modules ui admin persistence security rules scheduler
  30. Peter Niederwieser, Kristian Marinkovic 31 Tapestry IoC Tapestry IoC bei

    der Porsche Informatik (III) • Modul Architektur Web Backend Facade Repository DTO Facade Repository Domain Domain Service Service Service Factory Factory Persistence Module Tx Boundary Persistence Query
  31. Peter Niederwieser, Kristian Marinkovic 33 Tapestry IoC Beyond • Tapestry

    5 Web-Framework • Komponenten-Orientiert – Einfache Komponenten Entwicklung • Sehr flexibel • Deklaratives Programmiermodell • Experimentelle OSGi Integration • http://groups.google.com/group/tapestry-osgi/ • JUnit-Erweiterung • https://tapestry.formos.com/projects/tapestry-testify/ • Tapestry Komponenten Sammlung • http://www.chenillekit.org/