68
prepare for….. Proxy Deep Dive JUG Saxony Day 2015 1 @SvenRuppert

Proxy Deep Dive JUG Saxony Day 2015-10-02

Embed Size (px)

Citation preview

Page 1: Proxy Deep Dive JUG Saxony Day 2015-10-02

prepare for…..

Proxy Deep DiveJUG Saxony Day 2015

1

@SvenRuppert

Page 2: Proxy Deep Dive JUG Saxony Day 2015-10-02

@SvenRuppert has been coding java since 1996

Fellow / Senior Manager

reply Group

Germany - Munich

2

Page 3: Proxy Deep Dive JUG Saxony Day 2015-10-02

@SvenRuppert has been coding java since 1996

Projects in the field of: •Automobile-industry •Energy •Finance / Leasing •Space- Satellit- •Government / UN / World-bank

Where?

•Europe •Asia - from India up to Malaysia

3

Page 4: Proxy Deep Dive JUG Saxony Day 2015-10-02

Why a Proxy ?

4

@SvenRuppert

Proxies you can use them for :

generic parts inside your application

hiding technical stuff

decouple parts of your applications

Page 5: Proxy Deep Dive JUG Saxony Day 2015-10-02

Why a Proxy ?

5

@SvenRuppert

final InnerDemoClass original = new InnerDemoClass();

final InnerDemoInterface demoLogic =ProxyBuilder.createBuilder(InnerDemoInterface.class, original)

.addLogging().addMetrics()

.addSecurityRule(() -> true).addSecurityRule(() -> true)

.build();

but it must be easy to use like…

Page 6: Proxy Deep Dive JUG Saxony Day 2015-10-02

Why a Proxy ?

6

@SvenRuppert

@Inject

@Proxy(virtual = true, metrics = true)

Service service;

Page 7: Proxy Deep Dive JUG Saxony Day 2015-10-02

Adapter v Proxy - Pattern Hello World

7

@SvenRuppert

Difference between Proxy and Adapter

Page 8: Proxy Deep Dive JUG Saxony Day 2015-10-02

Adapter v Proxy - Pattern Hello World

Adapter - or called Wrapper

maybe : Use an Adapter if you have to use an incompatible interface between two systems.

In detail I am using/talking about an Adapter with Delegator.

8

@SvenRuppert

Page 9: Proxy Deep Dive JUG Saxony Day 2015-10-02

Adapter v Proxy - Pattern Hello Worldpublic class LegacyWorker { public void writeTheStrings(String[] strArray){ Arrays.stream(strArray).forEach(System.out::println); }}

9

public interface WorkerAdapter { public void workOnSomething(List<String> stringListe); }

public class Adapter implements WorkerAdapter { private LegacyWorker worker = new LegacyWorker(); @Override public void workOnSomething(List<String> stringListe) { final String[] strings = stringListe.toArray(new String[0]); worker.writeTheStrings(strings); }}

@SvenRuppert

Page 10: Proxy Deep Dive JUG Saxony Day 2015-10-02

Adapter v Proxy - Pattern Hello Worldpublic class Main { public static void main(String[] args) { final ArrayList<String> strings = new ArrayList<>(); Collections.addAll(strings, „A","B","C","D");

new Adapter().workOnSomething(strings); } }

10

• No need to know the LegacyWorker • No inheritance between LegacyWorker and Adapter • only a transformation of an interface • same creation time for Delegator and Adapter

@SvenRuppert

Page 11: Proxy Deep Dive JUG Saxony Day 2015-10-02

Proxy - the easiest version

11

• We need to know the LegacyWorker • Inheritance between LegacyWorker and Adapter • do not use it like an Adapter !

@SvenRuppert

We need a few steps to come from an Adapter with Delegator to a Proxy

please show the code

Page 12: Proxy Deep Dive JUG Saxony Day 2015-10-02

Proxy - the easiest version - (Delegator)public interface Service { String work(String txt);}

12

@SvenRuppert

public class ServiceImpl implements Service { public String work(String txt) { return "ServiceImpl - " + txt; } }

public class ServiceProxy implements Service { private Service service = new ServiceImpl(); public String work(String txt) { return service.work(txt); }}

Page 13: Proxy Deep Dive JUG Saxony Day 2015-10-02

Security Proxy

13

@SvenRuppert

public class ServiceProxy implements Service { private Service service = new ServiceImpl(); public String work(String txt) { return service.work(txt); }}

What could we

change now ? SecurityProxy: execute only if it is allowed

public class ServiceSecurityProxy implements Service { private Service service = new ServiceImpl(); private String code; //who will set this ? public String work(String txt) { if(code.equals(„hoppel")) { return service.work(txt); } else { return "nooooop"; } }}

Page 14: Proxy Deep Dive JUG Saxony Day 2015-10-02

Remote Proxy - JDK only

14

@SvenRuppert

public class ServiceProxy implements Service { private Service service = new ServiceImpl(); public String work(String txt) { return service.work(txt); }}

What could we

change now ? RemoteProxy: execute outside of my process

Service proxy = new ServiceRemoteProxy();String hello = proxy.work(„Hello");

some work needed

Page 15: Proxy Deep Dive JUG Saxony Day 2015-10-02

Remote Proxy - JDK only

15

@SvenRuppert

Proxy RemoteServiceIn

terfa

ce

Inte

rface

remote communication

client server

Page 16: Proxy Deep Dive JUG Saxony Day 2015-10-02

Remote Proxy - JDK only

16

@SvenRuppert

@WebService @SOAPBinding(style = SOAPBinding.Style.RPC)public interface Service { @WebMethod public String work(String txt);}

Page 17: Proxy Deep Dive JUG Saxony Day 2015-10-02

Remote Proxy - JDK only

17

@SvenRuppert

Proxy RemoteService

Inte

rface

Inte

rface

remote communication

client server

Page 18: Proxy Deep Dive JUG Saxony Day 2015-10-02

Remote Proxy - JDK only

18

@SvenRuppert

@SOAPBinding(style = SOAPBinding.Style.RPC)@WebService(endpointInterface = "org.rapidpm.Service")public class ServiceImpl implements Service { @Override public String work(String txt) { return "ServiceImpl - " + txt; }}

Page 19: Proxy Deep Dive JUG Saxony Day 2015-10-02

Remote Proxy - JDK only

19

@SvenRuppert

Proxy RemoteService

Inte

rface

Inte

rface

remote communication

client server

Page 20: Proxy Deep Dive JUG Saxony Day 2015-10-02

Remote Proxy - JDK only

20

@SvenRuppert

final String address = "http://localhost:9999/ws/service";final ExecutorService threadPool = Executors.newFixedThreadPool(10);

final Endpoint endpoint = Endpoint.create(new ServiceImpl());endpoint.setExecutor(threadPool);endpoint.publish(address);

System.out.println("endpoint = " + endpoint.isPublished());

Page 21: Proxy Deep Dive JUG Saxony Day 2015-10-02

Remote Proxy - JDK only

21

@SvenRuppert

Proxy RemoteService

Inte

rface

Inte

rface

remote communication

client server

Page 22: Proxy Deep Dive JUG Saxony Day 2015-10-02

Remote Proxy - JDK only

22

@SvenRuppert

public class ServiceRemoteProxy implements Service { private URL url; private Service realSubject; final String namespaceURI = "http://rapidpm.org/"; final String localPart = "ServiceImplService"; public ServiceRemoteProxy() { try { url = new URL("http://localhost:9999/ws/service?wsdl"); QName qname = new QName(namespaceURI, localPart); javax.xml.ws.Service service = javax.xml.ws.Service.create(url, qname); realSubject = service.getPort(Service.class); } catch (MalformedURLException e) { e.printStackTrace(); } } public String work(String txt){ return realSubject.work(txt); }}

Page 23: Proxy Deep Dive JUG Saxony Day 2015-10-02

Remote Proxy - JDK only

23

@SvenRuppert

Proxy RemoteService

Inte

rface

Inte

rface

remote communication

client server

• remote communication • most of this is technology based work • goal: developer will see no remote

communication

Page 24: Proxy Deep Dive JUG Saxony Day 2015-10-02

Virtual Proxy

24

@SvenRuppert

public class ServiceProxy implements Service { private Service service = new ServiceImpl(); public String work(String txt) { return service.work(txt); }}

What could we

change now ? Virtual Proxy: create the Delegator later

public class VirtualService implements Service { private Service service = null; public String work(String txt) { if(service == null) { service = new ServiceImpl(); } return service.work(txt); }}

Page 25: Proxy Deep Dive JUG Saxony Day 2015-10-02

Virtual Proxy

25

@SvenRuppert

public class VirtualService implements Service { private Service service = null; public String work(String txt) { if(service == null) { service = new ServiceImpl(); }

return service.work(txt); }}

This is NOT ThreadSavefixed decision for

an implementation

how to combine it with a FactoryPattern ?

Page 26: Proxy Deep Dive JUG Saxony Day 2015-10-02

Virtual Proxy

26

@SvenRuppert

if(service == null) { service = new ServiceImpl(); }

public interface ServiceFactory { Service createInstance();}

public interface ServiceStrategyFactory { Service realSubject(ServiceFactory factory);}

Page 27: Proxy Deep Dive JUG Saxony Day 2015-10-02

Virtual Proxy - Not - ThreadSave

27

@SvenRuppert

if(service == null) { service = new ServiceImpl(); }

public class ServiceStrategyFactoryImpl implements ServiceStrategyFactory { Service realSubject; public Service realSubject(final ServiceFactory factory) { if (realSubject == null) { realSubject = factory.createInstance(); } return realSubject; }}

private ServiceFactory serviceFactory = ServiceImpl::new;

Page 28: Proxy Deep Dive JUG Saxony Day 2015-10-02

Virtual Proxy - Not - ThreadSave

28

@SvenRuppert

if(service == null) { service = new ServiceImpl(); }

public class ServiceProxy implements Service {private ServiceFactory serviceFactory = ServiceImpl::new;private ServiceStrategyFactory strategyFactory = new ServiceStrategyFactoryImpl();

public String work(String txt) {return strategyFactory .realSubject(serviceFactory).work(txt);

}}

Page 29: Proxy Deep Dive JUG Saxony Day 2015-10-02

Virtual Proxy - Synchronized

29

@SvenRuppert

if(service == null) { service = new ServiceImpl(); }

public class ServiceStrategyFactorySynchronized implements ServiceStrategyFactory { Service realSubject; public synchronized Service realSubject(final ServiceFactory factory) { if (realSubject == null) { realSubject = factory.createInstance(); } return realSubject; }}

private ServiceFactory serviceFactory = ServiceImpl::new;

This is ThreadSave

Page 30: Proxy Deep Dive JUG Saxony Day 2015-10-02

Combining Proxies

30

@SvenRuppert

Security Proxy Virtual ProxyRemote Proxy

Security ProxyVirtual ProxyRemote Proxy

Security ProxyVirtual Proxy Remote Proxy

VirtualProxies are mostly the last onecombining Proxies is easy

SecurityProxies are mostly the first one ?

Page 31: Proxy Deep Dive JUG Saxony Day 2015-10-02

Combining Proxies - SecureVirtualProxy

31

@SvenRuppert

Security Proxy Virtual Proxy

public class VirtualProxy implements Service { public VirtualProxy() { out.println("VirtualProxy " + now()); } private Service service = null; public String work(String txt) { if(service == null) { service = new ServiceImpl(); } return service.work(txt); }}

public class SecureVirtualProxy implements Service { public SecureProxy() { out.println("SecureProxy " + now()); } private Service service = new VirtualProxy(); //SNIPP…. public String work(String txt) { if(code.equals("hoppel")) { return service.work(txt); } return { return "nooooop"; } }}

hard wired proxies

What could we

change now ?

Page 32: Proxy Deep Dive JUG Saxony Day 2015-10-02

Combining Proxies - SecureVirtualProxy

32

@SvenRuppert

Security Proxy Virtual Proxy

hard wired proxies

What could we

change now ?

we need a Generic Proxysince JDK1.3 we have it

the DynamicProxy

Page 33: Proxy Deep Dive JUG Saxony Day 2015-10-02

Dynamic Proxy - Hello World

33

@SvenRuppert

How to use it ? java.lang.reflect.Proxy

we need an interface : here Servicewe need an implementation : here ServiceImpl

Service proxyInstance = Service.class.cast( Proxy.newProxyInstance( Service.class.getClassLoader(), new Class<?>[]{Service.class}, new InvocationHandler() { private final ServiceImpl service = new ServiceImpl(); @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(service, args); } } )); OK, step by step , please

Page 34: Proxy Deep Dive JUG Saxony Day 2015-10-02

Dynamic Proxy - Hello World

34

@SvenRuppert

Proxy.newProxyInstance (

Service.class.getClassLoader(),

new Class<?>[]{Service.class},

Service proxyInstance = Service.class.cast (

new InvocationHandler() { private final ServiceImpl service = new ServiceImpl(); @Override public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { return m.invoke(service, args); }}

));

how to make a VirtualProxy ?

Page 35: Proxy Deep Dive JUG Saxony Day 2015-10-02

Dynamic Virtual Proxy

35

@SvenRuppert

Proxy.newProxyInstance (

Service.class.getClassLoader(),

new Class<?>[]{Service.class},

Service proxyInstance = Service.class.cast (

new InvocationHandler() { private final ServiceImpl service; @Override public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {

if(service == null) { service = new ServiceImpl(); }

return m.invoke(service, args); }}

));

Page 36: Proxy Deep Dive JUG Saxony Day 2015-10-02

Dynamic Proxy - make it generic

36

@SvenRuppert

Proxy.newProxyInstance (

Service.class.getClassLoader(),

new Class<?>[]{Service.class},

Service proxyInstance = Service.class.cast (

new InvocationHandler() { private final ServiceImpl service = new ServiceImpl(); @Override public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { return m.invoke(service, args); }}

));

get it from outside

we will remove it

we will get it from outside

and finally we will call it ProxyGenerator

Page 37: Proxy Deep Dive JUG Saxony Day 2015-10-02

Dynamic Proxy - make it generic

37

@SvenRuppert

public class ProxyGenerator { public static <P> P makeProxy(Class<P> subject, P realSubject) { Object proxyInstance = Proxy.newProxyInstance( subject.getClassLoader(), new Class<?>[]{subject}, new InvocationHandler() { @Override public Object invoke(final Object proxy, final Method m, final Object[] args) throws Throwable { return m.invoke(realSubject, args); } } ); return subject.cast(proxyInstance); }}

Page 38: Proxy Deep Dive JUG Saxony Day 2015-10-02

Dynamic Proxy - make it generic

38

@SvenRuppert

public class ProxyGenerator { public static <P> P makeProxy(Class<P> subject, P realSubject) { Object proxyInstance = Proxy.newProxyInstance( subject.getClassLoader(), new Class<?>[]{subject}, (proxy, m, args) -> m.invoke(realSubject, args) ); return subject.cast(proxyInstance); }}

Page 39: Proxy Deep Dive JUG Saxony Day 2015-10-02

Dynamic Proxy - make it generic

39

@SvenRuppert

with DynamicProxies- we are writing less (more generic) code- we can create Virtual-/Remote-/Security Proxies

but how to combine Proxies more generic ?

Page 40: Proxy Deep Dive JUG Saxony Day 2015-10-02

Dynamic Proxy - make it generic

40

@SvenRuppert

but how to combine Proxies more generic ?

for this we have to switch from

Factory-Method-Pattern

Builder-Pattern

Page 41: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicProxyBuilder

41

@SvenRuppert

but how to combine Proxies more generic ?

Security Proxy Virtual ProxySecurity Proxy

let´s think about Two possible ways:

1 Security Proxy with 2 Rules and 1 VirtualProxy

2 Security Proxies with 1 Rule and 1 VirtualProxy

OK, we need a generic CascadedProxy

Page 42: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicProxyBuilder

42

@SvenRuppert

OK, we need a generic CascadedProxy

Proxy n

Proxy n-1

Proxy n-2

Proxy n-3

a child must know his parentfirst we only add different DynamicProxies

always the same target interface

Page 43: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicProxyBuilder

43

@SvenRuppert

private List<SecurityRule> securityRules = new ArrayList<>();

for example: add n SecurityRulespublic interface SecurityRule { boolean checkRule();} functional interface

Collections.reverse(securityRules);securityRules.forEach(this::build_addSecurityRule);

Page 44: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicProxyBuilder

44

@SvenRuppert

private ProxyBuilder<I, T> build_addSecurityRule(SecurityRule rule) { final ClassLoader classLoader = original.getClass().getClassLoader(); final Class<?>[] interfaces = {clazz}; final Object nextProxy = Proxy.newProxyInstance( classLoader, interfaces, new InvocationHandler() { private T original = ProxyBuilder.this.original; public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { final boolean checkRule = rule.checkRule(); if (checkRule) { return method.invoke(original, args); } else { return null; } } }); original = (T) clazz.cast(nextProxy); return this;}

how this will be used ?

last child

work on child

set child for next level

Page 45: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicProxyBuilder

45

@SvenRuppert

final InnerDemoClass original = new InnerDemoClass();

final InnerDemoInterface demoLogic =ProxyBuilder.createBuilder(InnerDemoInterface.class, original)

.addLogging().addMetrics()

.addSecurityRule(() -> true).addSecurityRule(() -> true)

.build();

Page 46: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - orig Version

46

@SvenRuppert

the original Version of the DynamicObjectAdapterwas written by Dr. Heinz Kabutz

Page 47: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - orig Version

47

@SvenRuppert

Proxy orig / adapter

invoke orig

invoke adapter

Goal: do not need to write an Adapter with Delegator

Page 48: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - orig Version

48

@SvenRuppert

core concept: switching between method implementations

how to identify a method?

Page 49: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - orig. Version

49

@SvenRuppert

public interface Service { String doWork_A();}public static class ServiceImpl implements Service { public String doWork_A() { return ServiceImpl.class.getSimpleName(); }}

Page 50: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - orig Version

50

@SvenRuppert

how to identify a method?public class MethodIdentifier { private final String name; private final Class[] parameters; public MethodIdentifier(Method m) { name = m.getName(); parameters = m.getParameterTypes(); } // we can save time by assuming that we only compare against // other MethodIdentifier objects public boolean equals(Object o) { MethodIdentifier mid = (MethodIdentifier) o; return name.equals(mid.name) && Arrays.equals(parameters, mid.parameters); } public int hashCode() { return name.hashCode(); }}

Page 51: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - orig. Version

51

@SvenRuppert

private static class DOAInvocationHandler<T extends I, I> implements InvocationHandler {private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();

private T original; private Object adapter;

private void addAdapter(Object adapter) {this.adapter = adapter;final Class<?> adapterClass = adapter.getClass();Method[] methods = adapterClass.getDeclaredMethods();for (Method m : methods) {

final MethodIdentifier key = new MethodIdentifier(m);adaptedMethods.put(key, m);

} }

public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {

}}

//SNIPP

Page 52: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - orig. Version

52

@SvenRuppert

} catch (InvocationTargetException e) { throw e.getTargetException(); }

private static class DOAInvocationHandler<T extends I, I> implements InvocationHandler {private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();

private T original; private Object adapter;

private void addAdapter(Object adapter) {

}

public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {

Method other = adaptedMethods.get(key);

try { final MethodIdentifier key = new MethodIdentifier(m);

if (other != null) { return other.invoke(adapter, args); }else { return m.invoke(original, args); }

}}

//SNIPP

what could be a problem ?what could be improved ?

Page 53: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - orig. Version

53

@SvenRuppertprivate Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();

private T original; private Object adapter;

private void addAdapter(Object adapter) {what could be a problem ?what could be improved ?

public interface Service { String doWork_A();}

public class Adapter_A { public String doWork_A() { .. }}

public class Adapter_B { public String doWork_B() { .. }}

Page 54: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - orig Version

54

@SvenRuppert

Proxy orig / adapter

invoke orig

invoke adapter

Page 55: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - ext. Version

55

@SvenRuppert

first extension !

Page 56: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - ext. Version

56

@SvenRuppert

public interface Service { String doWork_A(String txt); String doWork_B(String txt);}

public static class ServiceImpl implements Service { public String doWork_A(String txt) { return "doWorkd_A_Original"; } public String doWork_B(String txt) { return "doWorkd_B_Original"; }}

Page 57: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - ext. Version

57

@SvenRuppert

public interface Service { String doWork_A(String txt); String doWork_B(String txt);}

public interface ServiceAdapter_A { String doWork_A(String txt);}public interface ServiceAdapter_B { String doWork_B(String txt);}

functional interface

functional interface

Page 58: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - ext. Version

58

@SvenRuppert

private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();private Map<MethodIdentifier, Object> adapters = new HashMap<>();private T original;private Class<T> target;

}}

private void addAdapter(Object adapter) { final Class<?> adapterClass = adapter.getClass(); Method[] methods = adapterClass.getDeclaredMethods();for (Method m : methods) {

final MethodIdentifier key = new MethodIdentifier(m);

adaptedMethods.put(key, m);adapters.put(key, adapter);

Page 59: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - ext. Version

59

@SvenRuppert

private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();private Map<MethodIdentifier, Object> adapters = new HashMap<>();private T original;private Class<T> target;

} catch (InvocationTargetException e) { throw e.getTargetException(); }}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { final MethodIdentifier key = new MethodIdentifier(method); Method other = adaptedMethods.get(key);

if (other != null) { return other.invoke(adapters.get(key), args); } else { return method.invoke(original, args); }

Page 60: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - ext. Version @SvenRuppert

private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();private Map<MethodIdentifier, Object> adapters = new HashMap<>();private T original;private Class<T> target;

if you will use this without a Builder you can add useless Adapter !!

Add some typed with-Methods

Page 61: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - orig Version @SvenRuppert

Add some typed with-Methods

public AdapterBuilder<T> withDoWork_A(ServiceAdapter_A adapter) { addAdapter(adapter); return this;}

remember public interface Service { String doWork_A(String txt); String doWork_B(String txt);}public interface ServiceAdapter_A { String doWork_A(String txt);}

Page 62: Proxy Deep Dive JUG Saxony Day 2015-10-02

DynamicObjectAdapter - orig Version @SvenRuppert

.build();

How to use this?

Service service = AdapterBuilder.<Service>newBuilder()

.withTarget(Service.class)

.withOriginal(new ServiceImpl())

.withDoWork_A((txt) -> txt + "_part")

Page 63: Proxy Deep Dive JUG Saxony Day 2015-10-02

generated DynamicObjectAdapterBuilder @SvenRuppert

To much boring code to write

but we want to have a type-save version

What could we

change now ?

if wrong… compile must break

Page 64: Proxy Deep Dive JUG Saxony Day 2015-10-02

generated DynamicObjectAdapterBuilder @SvenRuppert

remember

public interface Service { String doWork_A(String txt); String doWork_B(String txt);}public interface ServiceAdapter_A { String doWork_A(String txt);}public interface ServiceAdapter_B { String doWork_B(String txt);}

functional interface

Page 65: Proxy Deep Dive JUG Saxony Day 2015-10-02

generated DynamicObjectAdapterBuilder @SvenRuppert

use Annotation Processing

create a marker like @DynamicObjectAdapterBuilder

@Retention(RetentionPolicy.SOURCE)@Target(ElementType.TYPE)public @interface DynamicObjectAdapterBuilder {}

public class AnnotationProcessor extends AbstractProcessor

Page 66: Proxy Deep Dive JUG Saxony Day 2015-10-02

generated DynamicObjectAdapterBuilder @SvenRuppert

use Annotation Processing

with every compile you will get actual

Functional-Interfaces for the Adapters

generated AdapterBuilder

Page 67: Proxy Deep Dive JUG Saxony Day 2015-10-02

Summary

67

@SvenRuppert

we got type-save ProxyBuilder..type-save generated DynamicObjectAdapter

..at runtime we could change the chain of Proxies

..could be used for (Dynamic)

Dependency Injection Implementations

Page 68: Proxy Deep Dive JUG Saxony Day 2015-10-02

Summary

68

@SvenRuppert

If you are interested…

have a look at RapidPM on github

rapidpm-proxybuilder

rapidpm-dynamic-cdi

rapidpm-microservice

or contact me ;-) @SvenRuppert

Thank You !!!