Slide 1

Slide 1 text

Whoops! Where did my architecture go? Oliver Gierke, Senior Member Technical Staff [email protected] - @olivergierke © 2012 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Slide 2

Slide 2 text

2 Oliver Gierke Spring Source engineer Project lead Core/JPA/MongoDB [email protected] www.olivergierke.de olivergierke

Slide 3

Slide 3 text

3 Spring Data Modern Data Access For Enterprise Java NoSQL JPA JDBC Redis Big Data Hadoop HBase MongoDB Neo4j REST exporter Roo Hive Pig Querydsl Repositories 1 free copy per attendee! Gemfire Splunk

Slide 4

Slide 4 text

4 Background 5 years of consulting Lots of code reviews Eoin Woods‘ talk on InfoQ

Slide 5

Slide 5 text

Roadmap Architecture 101 A plain Java based approach Spring Plugin 5

Slide 6

Slide 6 text

The 3 C' of Architecture Constraints Complexity Change 6

Slide 7

Slide 7 text

The 2 C' of Architecture 7 Complexity Change

Slide 8

Slide 8 text

Architecture 101 8

Slide 9

Slide 9 text

Know your dependencies 9

Slide 10

Slide 10 text

Granularity Modules Layers Vertical slices Subsystems 10

Slide 11

Slide 11 text

Granularity Java ARchive Package Class 11

Slide 12

Slide 12 text

Of layers and slices… 12

Slide 13

Slide 13 text

Presentation Service Data Access Account Customer Core 13

Slide 14

Slide 14 text

14 Layers Well understood Known to developers Less important to business

Slide 15

Slide 15 text

Slices Hardly understood New to developers Key for business req 15

Slide 16

Slide 16 text

Presentation Service Data Access Account Customer Core 16

Slide 17

Slide 17 text

17 "How to implement an architecture inside a codebase?

Slide 18

Slide 18 text

Architecture VS. Codebase 18

Slide 19

Slide 19 text

19 "How to implement an architecture inside a codebase?

Slide 20

Slide 20 text

20 "How to enforce an architecture inside a codebase?

Slide 21

Slide 21 text

Code analysis JDepend Sonar 21

Slide 22

Slide 22 text

Demo 22

Slide 23

Slide 23 text

Sonargraph Formerly known as SonarJ 23

Slide 24

Slide 24 text

Demo 24

Slide 25

Slide 25 text

A plain Java based approach 25

Slide 26

Slide 26 text

26 "How far can we get with plain Java means only?

Slide 27

Slide 27 text

Presentation Service Data Access Account Customer Core 27

Slide 28

Slide 28 text

28 Packages

Slide 29

Slide 29 text

29 …. layer.slice ? …. slice.layer ? … slice ?

Slide 30

Slide 30 text

30 …web.core …service.core …repository.core

Slide 31

Slide 31 text

31 …core.web …core.service …core.repository

Slide 32

Slide 32 text

32 … core … customer … account

Slide 33

Slide 33 text

Layers first 33 Leaks slice internals Lower layers visible to everyone

Slide 34

Slide 34 text

Slices first/only Start with package per slice Expose interfaces and domain types Keep implementations private 34

Slide 35

Slide 35 text

Slices first/only Encapsulates business module Internals understood anyway 35

Slide 36

Slide 36 text

36 "Start with less packages and the least visibility possible…

Slide 37

Slide 37 text

Presentation Service Data Access Account Customer Core 37

Slide 38

Slide 38 text

Presentation Service Data Access Account Customer Core 38

Slide 39

Slide 39 text

Subsystems 39

Slide 40

Slide 40 text

Background 40 Risk management at German public bank Quite a few other SpringSource clients

Slide 41

Slide 41 text

Systems grow big! 41

Slide 42

Slide 42 text

Remember the 2 C's? 42

Slide 43

Slide 43 text

Complexity & Change 43

Slide 44

Slide 44 text

44 "How to localize change?

Slide 45

Slide 45 text

45 "Separate frequent from infrequent change!

Slide 46

Slide 46 text

46 Granularity Class Package Java ARchive

Slide 47

Slide 47 text

Host SPI SPI SPI Plugin Plugin 47

Slide 48

Slide 48 text

48 Context No OSGi Spring based Build-time composition Don‘t touch the host system

Slide 49

Slide 49 text

Host Plugin Plugin App 49

Slide 50

Slide 50 text

50 "How to make the host aware of the plugins?

Slide 51

Slide 51 text

51 "How to dynamically collect Spring beans of a given type?

Slide 52

Slide 52 text

52 classpath*:META-INF/ spring/plugin-context.xml

Slide 53

Slide 53 text

Host SPI SPI SPI Plugin Plugin 53

Slide 54

Slide 54 text

classpath*:META-INF/ spring/plugin-context.xml SPI SPI SPI META-INF/ spring/plugin- context.xml META-INF/ spring/plugin- context.xml 54

Slide 55

Slide 55 text

@Component public class MyComponentImpl implements TransferService { private List plugins; @Autowired public MyComponentImpl(List plugins) { this.plugins = plugins; } … } public interface MyPlugin { void doSomething(); } 55

Slide 56

Slide 56 text

Demo 56

Slide 57

Slide 57 text

XML? 57 Back in the days

Slide 58

Slide 58 text

(XML?) Back in the days Probably not a big deal anymore 58

Slide 59

Slide 59 text

Easy access? 59

Slide 60

Slide 60 text

@Component public class MyComponentImpl implements TransferService { private List plugins; @Autowired public MyComponentImpl(List plugins) { this.plugins = plugins; } … } public interface MyPlugin { void doSomething(); } 60

Slide 61

Slide 61 text

@Component public class MyComponentImpl implements TransferService { // Constructor omitted public Result myMethod(SomeParameter parameter) { // Select the first one to match to invoke? // Select multiple ones to invoke? // Select and fallback to one if none found? // Select and throw an exception if none found? } } 61

Slide 62

Slide 62 text

62 Spring Plugin

Slide 63

Slide 63 text

63 "The smallest plugin system ever!

Slide 64

Slide 64 text

64 Plugins Selection criterion Callback method Let the implementation decide

Slide 65

Slide 65 text

Registry Equipped with plugins Common access patterns 65

Slide 66

Slide 66 text

public interface Plugin { public boolean supports(T delimiter ); } public interface PluginRegistry, T> { T getPluginFor(S delimiter); T getPluginFor(S delimiter, T default); T getPluginFor(S del, E e) throws E; List getPluginsFor(S delimiter); … } 66

Slide 67

Slide 67 text

@Component public class MyComponentImpl implements TransferService { private PluginRegistry plugins; @Autowired public MyComponentImpl(PluginRegistry plugins) { this.plugins = plugins; } } public interface MyPlugin extends Plugin { void doSomething(); } 67

Slide 68

Slide 68 text

@Component public class MyComponentImpl implements TransferService { private final MyPlugin defaultPlugin = new MyDefaultPlugin(); public Result myMethod(String parameter) { // Select the first one to match to invoke? … = plugins.getPluginFor(parameter); // Select multiple ones to invoke? … = plugins.getPluginsFor(parameter); // Select and fallback to one if none found? … = plugins.getPluginFor(parameter, defaultPlugin); // Select and throw an exception if none found? … = plugins.getPluginsFor(parameter, new RuntimeException()); } } 68

Slide 69

Slide 69 text

69 OrderAware PluginRegistry Respects @Order/Ordered OAPR.reverse()

Slide 70

Slide 70 text

Bells‘n‘whistles FactoryBean Spring namespace Lazy-eval 70

Slide 71

Slide 71 text

Spring Plugin 71

Slide 72

Slide 72 text

Spring Integration2 72

Slide 73

Slide 73 text

73

Slide 74

Slide 74 text

Demo 74

Slide 75

Slide 75 text

Take-aways 75 Know your dependencies On every granularity Start as strict as possible Get lenient where necessary

Slide 76

Slide 76 text

Thanks & credits Eoin Woods - Talk @ InfoQ Uwe Friedrichsen - Slides @ Slideshare 76

Slide 77

Slide 77 text

Resources Spring Data JPA @ GitHub Sonargraph Spring Plugin Whoops sample code 77