SlideShare a Scribd company logo
prepare for…..
Proxy Deep Dive
JavaOne 2015 20151027
1
@SvenRuppert
@SvenRuppert
has been coding java since 1996
Fellow / Senior Manager
reply Group
Germany - Munich
2
@SvenRuppert
has been coding java since 1996
3
@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
prepare for…..
Proxy Deep Dive - the first steps
some words about Adapter, Delegator
and the first Proxy
4
@SvenRuppert
5
@SvenRuppert
5
@SvenRuppert
Why a Proxy ?
6
@SvenRuppert
Proxies you can use them for :
generic parts inside your application
hiding technical stuff
decouple parts of your applications
Why a Proxy ?
7
@SvenRuppert
but it must be easy to use like…
Why a Proxy ?
7
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
but it must be easy to use like…
Why a Proxy ?
7
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
final InnerDemoInterface demoLogic =
but it must be easy to use like…
Why a Proxy ?
7
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
final InnerDemoInterface demoLogic =
ProxyBuilder.createBuilder(InnerDemoInterface.class, original)
but it must be easy to use like…
Why a Proxy ?
7
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
final InnerDemoInterface demoLogic =
ProxyBuilder.createBuilder(InnerDemoInterface.class, original)
.addLogging()
but it must be easy to use like…
Why a Proxy ?
7
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
final InnerDemoInterface demoLogic =
ProxyBuilder.createBuilder(InnerDemoInterface.class, original)
.addLogging()
.addMetrics()
but it must be easy to use like…
Why a Proxy ?
7
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
final InnerDemoInterface demoLogic =
ProxyBuilder.createBuilder(InnerDemoInterface.class, original)
.addLogging()
.addMetrics()
.addSecurityRule(() -> true)
but it must be easy to use like…
Why a Proxy ?
7
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
final InnerDemoInterface demoLogic =
ProxyBuilder.createBuilder(InnerDemoInterface.class, original)
.addLogging()
.addMetrics()
.addSecurityRule(() -> true)
.addSecurityRule(() -> true)
but it must be easy to use like…
Why a Proxy ?
7
@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…
Why a Proxy ?
8
@SvenRuppert
but it must be easy to use like…
Why a Proxy ?
8
@SvenRuppert
@Inject
@Proxy(virtual = true, metrics = true)
Service service;
but it must be easy to use like…
Adapter v Proxy - Pattern Hello World
9
@SvenRuppert
Difference between Proxy and Adapter
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.
10
@SvenRuppert
Adapter v Proxy - Pattern Hello World
11
@SvenRuppert
Adapter v Proxy - Pattern Hello World
public class LegacyWorker {

public void writeTheStrings(String[] strArray){

Arrays.stream(strArray).forEach(System.out::println);

}

}
11
@SvenRuppert
Adapter v Proxy - Pattern Hello World
public class LegacyWorker {

public void writeTheStrings(String[] strArray){

Arrays.stream(strArray).forEach(System.out::println);

}

}
11
public interface WorkerAdapter {

public void workOnSomething(List<String> stringListe);

}
@SvenRuppert
Adapter v Proxy - Pattern Hello World
public class LegacyWorker {

public void writeTheStrings(String[] strArray){

Arrays.stream(strArray).forEach(System.out::println);

}

}
11
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
Adapter v Proxy - Pattern Hello World
public class LegacyWorker {

public void writeTheStrings(String[] strArray){

Arrays.stream(strArray).forEach(System.out::println);

}

}
11
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
Adapter v Proxy - Pattern Hello World
public class LegacyWorker {

public void writeTheStrings(String[] strArray){

Arrays.stream(strArray).forEach(System.out::println);

}

}
11
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
Adapter v Proxy - Pattern Hello World
public class LegacyWorker {

public void writeTheStrings(String[] strArray){

Arrays.stream(strArray).forEach(System.out::println);

}

}
11
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
Adapter v Proxy - Pattern Hello World
public class LegacyWorker {

public void writeTheStrings(String[] strArray){

Arrays.stream(strArray).forEach(System.out::println);

}

}
11
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
Adapter v Proxy - Pattern Hello World
public 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);

}

}
12
@SvenRuppert
Adapter v Proxy - Pattern Hello World
public 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);

}

}
12
@SvenRuppert
Adapter v Proxy - Pattern Hello World
public 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);

}

}
12
@SvenRuppert
Adapter v Proxy - Pattern Hello World
public 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);

}

}
12
• No need to know the LegacyWorker
@SvenRuppert
Adapter v Proxy - Pattern Hello World
public 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);

}

}
12
• No need to know the LegacyWorker
• No inheritance between LegacyWorker and Adapter
@SvenRuppert
Adapter v Proxy - Pattern Hello World
public 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);

}

}
12
• No need to know the LegacyWorker
• No inheritance between LegacyWorker and Adapter
• only a transformation of an interface
@SvenRuppert
Adapter v Proxy - Pattern Hello World
public 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);

}

}
12
• 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
Proxy - the easiest version
13
@SvenRuppert
We need a few steps to come from an Adapter with
Delegator to a Proxy
Proxy - the easiest version
13
• We need to know the LegacyWorker
@SvenRuppert
We need a few steps to come from an Adapter with
Delegator to a Proxy
Proxy - the easiest version
13
• We need to know the LegacyWorker
• Inheritance between LegacyWorker and Adapter
@SvenRuppert
We need a few steps to come from an Adapter with
Delegator to a Proxy
Proxy - the easiest version
13
• 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
Proxy - the easiest version
13
• 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
Proxy - the easiest version - (Delegator)
14
@SvenRuppert
Proxy - the easiest version - (Delegator)
public interface Service {

String work(String txt);

}
14
@SvenRuppert
Proxy - the easiest version - (Delegator)
public interface Service {

String work(String txt);

}
14
@SvenRuppert
public class ServiceImpl implements Service {

public String work(String txt) {

return "ServiceImpl - " + txt;

}

}
Proxy - the easiest version - (Delegator)
public interface Service {

String work(String txt);

}
14
@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); }

}
Security Proxy
15
@SvenRuppert
Security Proxy
15
@SvenRuppert
public class ServiceProxy implements Service {

private Service service = new ServiceImpl();

public String work(String txt) { return service.work(txt); }

}
Security Proxy
15
@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 ?
Security Proxy
15
@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
Security Proxy
15
@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"; }

}

}
Security Proxy
15
@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"; }

}

}
Remote Proxy - JDK only
16
@SvenRuppert
Remote Proxy - JDK only
16
@SvenRuppert
public class ServiceProxy implements Service {

private Service service = new ServiceImpl();

public String work(String txt) { return service.work(txt); }

}
Remote Proxy - JDK only
16
@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 ?
Remote Proxy - JDK only
16
@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
Remote Proxy - JDK only
16
@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");
Remote Proxy - JDK only
16
@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");
Remote Proxy - JDK only
16
@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
Remote Proxy - JDK only
17
@SvenRuppert
Remote Proxy - JDK only
17
@SvenRuppert
Remote Proxy - JDK only
17
@SvenRuppert
Interface
Remote Proxy - JDK only
17
@SvenRuppert
Proxy
Interface
Remote Proxy - JDK only
17
@SvenRuppert
Proxy
Interface
remote communication
Remote Proxy - JDK only
17
@SvenRuppert
Proxy
Interface
remote communication
Remote Proxy - JDK only
17
@SvenRuppert
Proxy
Interface
remote communication
Remote Proxy - JDK only
17
@SvenRuppert
Proxy
Interface
remote communication
Remote Proxy - JDK only
17
@SvenRuppert
Proxy
Interface
remote communication
Remote Proxy - JDK only
17
@SvenRuppert
Proxy
Interface
Interface
remote communication
Remote Proxy - JDK only
17
@SvenRuppert
Proxy
Remote
Service
Interface
Interface
remote communication
Remote Proxy - JDK only
17
@SvenRuppert
Proxy
Remote
Service
Interface
Interface
remote communication
Remote Proxy - JDK only
17
@SvenRuppert
Proxy
Remote
Service
Interface
Interface
remote communication
client
Remote Proxy - JDK only
17
@SvenRuppert
Proxy
Remote
Service
Interface
Interface
remote communication
client server
Remote Proxy - JDK only
17
@SvenRuppert
Proxy
Remote
Service
Interface
Interface
remote communication
client server
Remote Proxy - JDK only
17
@SvenRuppert
Proxy
Remote
Service
Interface
Interface
remote communication
client server
Remote Proxy - JDK only
18
@SvenRuppert
@WebService

@SOAPBinding(style = SOAPBinding.Style.RPC)

public interface Service {

@WebMethod

public String work(String txt);

}
Remote Proxy - JDK only
19
@SvenRuppert
Proxy
Remote
Service
Interface
Interface
remote communication
client server
Remote Proxy - JDK only
19
@SvenRuppert
Proxy
Remote
Service
Interface
Interface
remote communication
client server
Remote Proxy - JDK only
20
@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;

}

}
Remote Proxy - JDK only
21
@SvenRuppert
Proxy
Remote
Service
Interface
Interface
remote communication
client server
Remote Proxy - JDK only
21
@SvenRuppert
Proxy
Remote
Service
Interface
Interface
remote communication
client server
Remote Proxy - JDK only
22
@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());
Remote Proxy - JDK only
22
@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());
Remote Proxy - JDK only
23
@SvenRuppert
Proxy Remote
Service
Interface
Interface
remote communication
client server
Remote Proxy - JDK only
23
@SvenRuppert
Proxy Remote
Service
Interface
Interface
remote communication
client server
Remote Proxy - JDK only
24
@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);

}

}
Remote Proxy - JDK only
24
@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);

}

}
Remote Proxy - JDK only
24
@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);

}

}
Remote Proxy - JDK only
25
@SvenRuppert
Proxy
Remote
Service
Interface
Interface
remote communication
client server
Remote Proxy - JDK only
25
@SvenRuppert
Proxy
Remote
Service
Interface
Interface
remote communication
client server
• remote communication
Remote Proxy - JDK only
25
@SvenRuppert
Proxy
Remote
Service
Interface
Interface
remote communication
client server
• remote communication
• most of this is technology based work
Remote Proxy - JDK only
25
@SvenRuppert
Proxy
Remote
Service
Interface
Interface
remote communication
client server
• remote communication
• most of this is technology based work
• goal: developer will see no remote
communication
Virtual Proxy
26
@SvenRuppert
Virtual Proxy
26
@SvenRuppert
public class ServiceProxy implements Service {

private Service service = new ServiceImpl();

public String work(String txt) { return service.work(txt); }

}
Virtual Proxy
26
@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
26
@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
Virtual Proxy
26
@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);

}

}
Virtual Proxy
26
@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);

}

}
Virtual Proxy
26
@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);

}

}
Virtual Proxy
27
@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);

}

}
Virtual Proxy
27
@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);

}

}
Virtual Proxy
27
@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 ThreadSafe
Virtual Proxy
27
@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 ThreadSafe
Virtual Proxy
27
@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 ThreadSafe
fixed decision for
an implementation
Virtual Proxy
27
@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 ThreadSafe
fixed decision for
an implementation
Virtual Proxy
27
@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 ThreadSafe
fixed decision for
an implementation
how to combine it with
a FactoryPattern ?
Virtual Proxy
28
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

Virtual Proxy
28
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

Virtual Proxy
28
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

public interface ServiceFactory {

Service createInstance();

}
Virtual Proxy
28
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

public interface ServiceFactory {

Service createInstance();

}
Virtual Proxy
28
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

public interface ServiceFactory {

Service createInstance();

}
public interface ServiceStrategyFactory {

Service realSubject(ServiceFactory factory);

}
Virtual Proxy - Not - ThreadSafe
29
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

Virtual Proxy - Not - ThreadSafe
29
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

Virtual Proxy - Not - ThreadSafe
29
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

private ServiceFactory serviceFactory = ServiceImpl::new;
Virtual Proxy - Not - ThreadSafe
29
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

private ServiceFactory serviceFactory = ServiceImpl::new;
Virtual Proxy - Not - ThreadSafe
29
@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;
Virtual Proxy - Not - ThreadSafe
30
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

Virtual Proxy - Not - ThreadSafe
30
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

public class ServiceProxy implements Service {
Virtual Proxy - Not - ThreadSafe
30
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

public class ServiceProxy implements Service {
private ServiceFactory serviceFactory = ServiceImpl::new;
Virtual Proxy - Not - ThreadSafe
30
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

public class ServiceProxy implements Service {
private ServiceFactory serviceFactory = ServiceImpl::new;
private ServiceStrategyFactory strategyFactory = new ServiceStrategyFactoryImpl();
Virtual Proxy - Not - ThreadSafe
30
@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) {
Virtual Proxy - Not - ThreadSafe
30
@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) {
}

}
Virtual Proxy - Not - ThreadSafe
30
@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
}

}
Virtual Proxy - Not - ThreadSafe
30
@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
}

}
Virtual Proxy - Not - ThreadSafe
30
@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(
}

}
Virtual Proxy - Not - ThreadSafe
30
@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
}

}
Virtual Proxy - Not - ThreadSafe
30
@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);
}

}
Virtual Proxy - Synchronized
31
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

Virtual Proxy - Synchronized
31
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

Virtual Proxy - Synchronized
31
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

private ServiceFactory serviceFactory = ServiceImpl::new;
Virtual Proxy - Synchronized
31
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

private ServiceFactory serviceFactory = ServiceImpl::new;
Virtual Proxy - Synchronized
31
@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;
Virtual Proxy - Synchronized
31
@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 ThreadSafe
Virtual Proxy - Method Scoped
32
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

Virtual Proxy - Method Scoped
32
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

Virtual Proxy - Method Scoped
32
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

private ServiceFactory serviceFactory = ServiceImpl::new;
Virtual Proxy - Method Scoped
32
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

private ServiceFactory serviceFactory = ServiceImpl::new;
Virtual Proxy - Method Scoped
32
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

public class ServiceStrategyFactoryMethodScoped implements
ServiceStrategyFactory {

public Service realSubject(final ServiceFactory factory) { 

return factory.createInstance();

}

}
private ServiceFactory serviceFactory = ServiceImpl::new;
Virtual Proxy - Method Scoped
32
@SvenRuppert
if(service == null) { service = new ServiceImpl(); }

public class ServiceStrategyFactoryMethodScoped implements
ServiceStrategyFactory {

public Service realSubject(final ServiceFactory factory) { 

return factory.createInstance();

}

}
private ServiceFactory serviceFactory = ServiceImpl::new;
Combining Proxies
33
@SvenRuppert
Security Proxy Virtual ProxyRemote Proxy
Security ProxyVirtual ProxyRemote Proxy
Security ProxyVirtual Proxy Remote Proxy
VirtualProxies are mostly the last one
combining Proxies is easy
SecurityProxies are mostly the first one ?
Combining Proxies
33
@SvenRuppert
Security Proxy Virtual ProxyRemote Proxy
Security ProxyVirtual ProxyRemote Proxy
Security ProxyVirtual Proxy Remote Proxy
VirtualProxies are mostly the last one
combining Proxies is easy
SecurityProxies are mostly the first one ?
Combining Proxies
33
@SvenRuppert
Security Proxy Virtual ProxyRemote Proxy
Security ProxyVirtual ProxyRemote Proxy
Security ProxyVirtual Proxy Remote Proxy
VirtualProxies are mostly the last one
combining Proxies is easy
SecurityProxies are mostly the first one ?
Combining Proxies
33
@SvenRuppert
Security Proxy Virtual ProxyRemote Proxy
Security ProxyVirtual ProxyRemote Proxy
Security ProxyVirtual Proxy Remote Proxy
VirtualProxies are mostly the last one
combining Proxies is easy
SecurityProxies are mostly the first one ?
Combining Proxies
33
@SvenRuppert
Security Proxy Virtual ProxyRemote Proxy
Security ProxyVirtual ProxyRemote Proxy
Security ProxyVirtual Proxy Remote Proxy
VirtualProxies are mostly the last one
combining Proxies is easy
SecurityProxies are mostly the first one ?
Combining Proxies - SecureVirtualProxy
34
@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"; }

}

}
Combining Proxies - SecureVirtualProxy
34
@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"; }

}

}
Combining Proxies - SecureVirtualProxy
34
@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"; }

}

}
Combining Proxies - SecureVirtualProxy
34
@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"; }

}

}
Combining Proxies - SecureVirtualProxy
34
@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"; }

}

}
Combining Proxies - SecureVirtualProxy
34
@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
Combining Proxies - SecureVirtualProxy
34
@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 ?
Combining Proxies - SecureVirtualProxy
35
@SvenRuppert
Security Proxy Virtual Proxy
hard wired proxies
What could we
change now ?
we need a Generic Proxy
Combining Proxies - SecureVirtualProxy
35
@SvenRuppert
Security Proxy Virtual Proxy
hard wired proxies
What could we
change now ?
we need a Generic Proxy
since JDK1.3 we have it
Combining Proxies - SecureVirtualProxy
35
@SvenRuppert
Security Proxy Virtual Proxy
hard wired proxies
What could we
change now ?
we need a Generic Proxy
since JDK1.3 we have it
the DynamicProxy
prepare for…..
Proxy Deep Dive - DynamicProxies
some words about :
how to use and how to extend….but.. also what is not nice
36
@SvenRuppert
37
@SvenRuppert
37
@SvenRuppert
Dynamic Proxy - Hello World
38
@SvenRuppert
How to use it ?
Dynamic Proxy - Hello World
38
@SvenRuppert
How to use it ?
java.lang.reflect.Proxy
Dynamic Proxy - Hello World
38
@SvenRuppert
How to use it ?
java.lang.reflect.Proxy
we need an interface : here Service
Dynamic Proxy - Hello World
38
@SvenRuppert
How to use it ?
java.lang.reflect.Proxy
we need an interface : here Service
we need an implementation : here ServiceImpl
Dynamic Proxy - Hello World
38
@SvenRuppert
How to use it ?
java.lang.reflect.Proxy
we need an interface : here Service
we 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);

}

}

)

);
Dynamic Proxy - Hello World
38
@SvenRuppert
How to use it ?
java.lang.reflect.Proxy
we need an interface : here Service
we 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
Dynamic Proxy - Hello World
39
@SvenRuppert
Dynamic Proxy - Hello World
39
@SvenRuppert
Service proxyInstance = Service.class.cast (
Dynamic Proxy - Hello World
39
@SvenRuppert
Proxy.newProxyInstance (
Service proxyInstance = Service.class.cast (
Dynamic Proxy - Hello World
39
@SvenRuppert
Proxy.newProxyInstance (
Service.class.getClassLoader(),
Service proxyInstance = Service.class.cast (
Dynamic Proxy - Hello World
39
@SvenRuppert
Proxy.newProxyInstance (
Service.class.getClassLoader(),
new Class<?>[]{Service.class},
Service proxyInstance = Service.class.cast (
Dynamic Proxy - Hello World
39
@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);

}

}
Dynamic Proxy - Hello World
39
@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);

}

}
)

);
Dynamic Proxy - Hello World
39
@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 ?
Dynamic Virtual Proxy
40
@SvenRuppert
Proxy.newProxyInstance (
Service.class.getClassLoader(),
new Class<?>[]{Service.class},
Service proxyInstance = Service.class.cast (
)

);
Dynamic Virtual Proxy
40
@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);

}

}
)

);
Dynamic Virtual Proxy
40
@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);

}

}
)

);
Dynamic Virtual Proxy
40
@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);

}

}
)

);
Dynamic Proxy - make it generic
41
@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);

}

}

)

);
Dynamic Proxy - make it generic
41
@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);

}

}

)

);
Dynamic Proxy - make it generic
41
@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);

}

}

)

);
Dynamic Proxy - make it generic
41
@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);

}

}

)

);
Dynamic Proxy - make it generic
41
@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
Dynamic Proxy - make it generic
41
@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
Dynamic Proxy - make it generic
41
@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
Dynamic Proxy - make it generic
41
@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
Dynamic Proxy - make it generic
41
@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
Dynamic Proxy - make it generic
41
@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
Dynamic Proxy - make it generic
42
@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);

}

}
Dynamic Proxy - make it generic
43
@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);

}

}
Dynamic Proxy - make it generic
44
@SvenRuppert
with DynamicProxies
- we are writing less (more generic) code
- we can create Virtual-/Remote-/Security Proxies
Dynamic Proxy - make it generic
44
@SvenRuppert
with DynamicProxies
- we are writing less (more generic) code
- we can create Virtual-/Remote-/Security Proxies
but how to combine Proxies more generic ?
Dynamic Proxy - make it generic
45
@SvenRuppert
but how to combine Proxies more generic ?
for this we have to switch from
Dynamic Proxy - make it generic
45
@SvenRuppert
but how to combine Proxies more generic ?
for this we have to switch from
Factory-Method-Pattern
Dynamic Proxy - make it generic
45
@SvenRuppert
but how to combine Proxies more generic ?
for this we have to switch from
Factory-Method-Pattern
Dynamic Proxy - make it generic
45
@SvenRuppert
but how to combine Proxies more generic ?
for this we have to switch from
Factory-Method-Pattern
Builder-Pattern
DynamicProxyBuilder
46
@SvenRuppert
but how to combine Proxies more generic ?
Security Proxy Virtual ProxySecurity Proxy
let´s think about Two possible ways:
DynamicProxyBuilder
46
@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
DynamicProxyBuilder
46
@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
DynamicProxyBuilder
46
@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
DynamicProxyBuilder
47
@SvenRuppert
OK, we need a generic CascadedProxy
Proxy n
Proxy n-1
Proxy n-2
Proxy n-3
a child must know his parent
first we only add different DynamicProxies
always the same target interface
DynamicProxyBuilder
47
@SvenRuppert
OK, we need a generic CascadedProxy
Proxy n
Proxy n-1
Proxy n-2
Proxy n-3
a child must know his parent
first we only add different DynamicProxies
always the same target interface
DynamicProxyBuilder
48
@SvenRuppert
for example: add n SecurityRules
DynamicProxyBuilder
48
@SvenRuppert
for example: add n SecurityRules
public interface SecurityRule {

boolean checkRule();

}
DynamicProxyBuilder
48
@SvenRuppert
for example: add n SecurityRules
public interface SecurityRule {

boolean checkRule();

}
DynamicProxyBuilder
48
@SvenRuppert
for example: add n SecurityRules
public interface SecurityRule {

boolean checkRule();

}
functional interface
DynamicProxyBuilder
48
@SvenRuppert
private List<SecurityRule> securityRules = new ArrayList<>();
for example: add n SecurityRules
public interface SecurityRule {

boolean checkRule();

}
functional interface
DynamicProxyBuilder
48
@SvenRuppert
private List<SecurityRule> securityRules = new ArrayList<>();
for example: add n SecurityRules
public interface SecurityRule {

boolean checkRule();

}
functional interface
Collections.reverse(securityRules);

securityRules.forEach(this::build_addSecurityRule);
DynamicProxyBuilder
49
@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;

}
Collections.reverse(securityRules);

securityRules.forEach(this::build_addSecurityRule);
DynamicProxyBuilder
49
@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;

}
Collections.reverse(securityRules);

securityRules.forEach(this::build_addSecurityRule);
DynamicProxyBuilder
49
@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;

}
last child
Collections.reverse(securityRules);

securityRules.forEach(this::build_addSecurityRule);
DynamicProxyBuilder
49
@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;

}
last child
Collections.reverse(securityRules);

securityRules.forEach(this::build_addSecurityRule);
DynamicProxyBuilder
49
@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;

}
last child
work on child
Collections.reverse(securityRules);

securityRules.forEach(this::build_addSecurityRule);
DynamicProxyBuilder
49
@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;

}
last child
work on child
Collections.reverse(securityRules);

securityRules.forEach(this::build_addSecurityRule);
DynamicProxyBuilder
49
@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;

}
last child
work on child
set child for next level
Collections.reverse(securityRules);

securityRules.forEach(this::build_addSecurityRule);
DynamicProxyBuilder
49
@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
Collections.reverse(securityRules);

securityRules.forEach(this::build_addSecurityRule);
DynamicProxyBuilder
50
@SvenRuppert
DynamicProxyBuilder
50
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
DynamicProxyBuilder
50
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
final InnerDemoInterface demoLogic =
DynamicProxyBuilder
50
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
final InnerDemoInterface demoLogic =
ProxyBuilder.createBuilder(InnerDemoInterface.class, original)
DynamicProxyBuilder
50
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
final InnerDemoInterface demoLogic =
ProxyBuilder.createBuilder(InnerDemoInterface.class, original)
.addLogging()
DynamicProxyBuilder
50
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
final InnerDemoInterface demoLogic =
ProxyBuilder.createBuilder(InnerDemoInterface.class, original)
.addLogging()
.addMetrics()
DynamicProxyBuilder
50
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
final InnerDemoInterface demoLogic =
ProxyBuilder.createBuilder(InnerDemoInterface.class, original)
.addLogging()
.addMetrics()
.addSecurityRule(() -> true)
DynamicProxyBuilder
50
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
final InnerDemoInterface demoLogic =
ProxyBuilder.createBuilder(InnerDemoInterface.class, original)
.addLogging()
.addMetrics()
.addSecurityRule(() -> true)
.addSecurityRule(() -> true)
DynamicProxyBuilder
50
@SvenRuppert
final InnerDemoClass original = new InnerDemoClass();
final InnerDemoInterface demoLogic =
ProxyBuilder.createBuilder(InnerDemoInterface.class, original)
.addLogging()
.addMetrics()
.addSecurityRule(() -> true)
.addSecurityRule(() -> true)
.build();
DynamicProxyBuilder
51
@SvenRuppert
DynamicProxyBuilder
51
@SvenRuppert
Until now, we had only a cascade of one interface
DynamicProxyBuilder
51
@SvenRuppert
Until now, we had only a cascade of one interface
how to deal with different interfaces ?
DynamicProxyBuilder
51
@SvenRuppert
Until now, we had only a cascade of one interface
how to deal with different interfaces ?
DynamicProxyBuilder
51
@SvenRuppert
Until now, we had only a cascade of one interface
how to deal with different interfaces ?
we need a generic NestedBuilder
NestedBuilder - The Beginning
52
@SvenRuppert
NestedBuilder - The Beginning
53
@SvenRuppert
NestedBuilder - The Beginning
53
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
NestedBuilder - The Beginning
53
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
NestedBuilder - The Beginning
53
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
NestedBuilder - The Beginning
53
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
NestedBuilder - The Beginning
53
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
List<Wheel> wheels = new ArrayList<>();

wheels.add(wheel1);

wheels.add(wheel2);

wheels.add(wheel3);
NestedBuilder - The Beginning
53
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
List<Wheel> wheels = new ArrayList<>();

wheels.add(wheel1);

wheels.add(wheel2);

wheels.add(wheel3);
}
NestedBuilder - The Beginning
53
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
List<Wheel> wheels = new ArrayList<>();

wheels.add(wheel1);

wheels.add(wheel2);

wheels.add(wheel3);
}
NestedBuilder - The Beginning
53
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 

Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();

Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
List<Wheel> wheels = new ArrayList<>();

wheels.add(wheel1);

wheels.add(wheel2);

wheels.add(wheel3);
}
NestedBuilder - The Beginning
54
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 

Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();

Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
List<Wheel> wheels = new ArrayList<>();

wheels.add(wheel1);

wheels.add(wheel2);

wheels.add(wheel3);
NestedBuilder - The Beginning
55
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 

Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();

Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
List<Wheel> wheels = new ArrayList<>();

wheels.add(wheel1);

wheels.add(wheel2);

wheels.add(wheel3);
NestedBuilder - The Beginning
55
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 

Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();

Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
NestedBuilder - The Beginning
55
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 

Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();

Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
//List<Wheel> wheels = new ArrayList<>();

// wheels.add(wheel1);

// wheels.add(wheel2);

// wheels.add(wheel3);
NestedBuilder - The Beginning
55
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 

Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();

Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
//List<Wheel> wheels = new ArrayList<>();

// wheels.add(wheel1);

// wheels.add(wheel2);

// wheels.add(wheel3);
List<Wheel> wheelList = WheelListBuilder.newBuilder()

.withNewList()

.addWheel(wheel1)

.addWheel(wheel2)

.addWheel(wheel3)

.build();
NestedBuilder - The Beginning
55
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 

Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();

Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
//List<Wheel> wheels = new ArrayList<>();

// wheels.add(wheel1);

// wheels.add(wheel2);

// wheels.add(wheel3);
List<Wheel> wheelList = WheelListBuilder.newBuilder()

.withNewList()

.addWheel(wheel1)

.addWheel(wheel2)

.addWheel(wheel3)

.build(); //more robust if you add tests at build()
NestedBuilder - The Beginning
55
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 

Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();

Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
//List<Wheel> wheels = new ArrayList<>();

// wheels.add(wheel1);

// wheels.add(wheel2);

// wheels.add(wheel3);
List<Wheel> wheelList = WheelListBuilder.newBuilder()

.withNewList()

.addWheel(wheel1)

.addWheel(wheel2)

.addWheel(wheel3)

.build(); //more robust if you add tests at build()
}
}
NestedBuilder - The Beginning
55
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 

Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();

Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
//List<Wheel> wheels = new ArrayList<>();

// wheels.add(wheel1);

// wheels.add(wheel2);

// wheels.add(wheel3);
List<Wheel> wheelList = WheelListBuilder.newBuilder()

.withNewList()

.addWheel(wheel1)

.addWheel(wheel2)

.addWheel(wheel3)

.build(); //more robust if you add tests at build()
}
}
how to combine ?
NestedBuilder - The Beginning
56
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 

Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();

Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
List<Wheel> wheelList = WheelListBuilder.newBuilder()

.withNewList()

.addWheel(wheel1)

.addWheel(wheel2)

.addWheel(wheel3)

.build();
}
}
how to combine ?
NestedBuilder - The Beginning
57
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
// Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 

// Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();

// Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
// List<Wheel> wheelList = WheelListBuilder.newBuilder()

.withNewList()

.addWheel(wheel1)

.addWheel(wheel2)

.addWheel(wheel3)

.build();
NestedBuilder - The Beginning
57
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
// List<Wheel> wheelList = WheelListBuilder.newBuilder()

.withNewList()

.addWheel(wheel1)

.addWheel(wheel2)

.addWheel(wheel3)

.build();
NestedBuilder - The Beginning
57
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
NestedBuilder - The Beginning
57
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
List<Wheel> wheels = wheelListBuilder

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.build();
NestedBuilder - The Beginning
58
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
List<Wheel> wheels = wheelListBuilder

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.build();
NestedBuilder - The Beginning
58
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
List<Wheel> wheels = wheelListBuilder

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.build();
NestedBuilder - The Beginning
58
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
List<Wheel> wheels = wheelListBuilder

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.build();
WheelBuilder
NestedBuilder - The Beginning
58
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
List<Wheel> wheels = wheelListBuilder

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.build();
WheelBuilder
NestedBuilder - The Beginning
58
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
List<Wheel> wheels = wheelListBuilder

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.build();
WheelBuilder
WheelListBuilder
NestedBuilder - The Beginning
59
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
List<Wheel> wheels = wheelListBuilder

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.build();
NestedBuilder - The Beginning
59
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
List<Wheel> wheels = wheelListBuilder

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.build();
now we have to combine all
NestedBuilder - The Beginning
59
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
List<Wheel> wheels = wheelListBuilder

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.build();
now we have to combine all
NestedBuilder - The Beginning
59
@SvenRuppert
Car car = Car.newBuilder()

.withEngine(engine)

.withWheelList(wheels)

.build();
now we have to combine all
NestedBuilder - The Beginning
59
@SvenRuppert
now we have to combine all
NestedBuilder - The Beginning
59
@SvenRuppert
now we have to combine all
NestedBuilder - The Beginning
59
@SvenRuppert
now we have to combine all
Car car = Car.newBuilder()

.addEngine().withPower(100).withType(5).done()

.addWheels()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.done()

.build();
NestedBuilder - The Beginning
59
@SvenRuppert
now we have to combine all
Car car = Car.newBuilder()

.addEngine().withPower(100).withType(5).done()

.addWheels()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.addWheel().withType(1).withSize(2).withColour(2).addWheelToList()

.done()

.build();
NestedBuilder - The Pattern
60
@SvenRuppert
public abstract class NestedBuilder<T, V> {
protected T parent;
public abstract V build()
public <P extends NestedBuilder<T, V>> P 

withParentBuilder(T parent) {

this.parent = parent;

return (P) this;

}
NestedBuilder - The Pattern
60
@SvenRuppert
public abstract class NestedBuilder<T, V> {
protected T parent;
public abstract V build()
public <P extends NestedBuilder<T, V>> P 

withParentBuilder(T parent) {

this.parent = parent;

return (P) this;

}
NestedBuilder - The Pattern
60
@SvenRuppert
public abstract class NestedBuilder<T, V> {
protected T parent;
public abstract V build()
public <P extends NestedBuilder<T, V>> P 

withParentBuilder(T parent) {

this.parent = parent;

return (P) this;

}
parent will connect itself…
NestedBuilder - The Pattern
61
@SvenRuppert
NestedBuilder - The Pattern
61
@SvenRuppert
public abstract class NestedBuilder<T, V> {
NestedBuilder - The Pattern
61
@SvenRuppert
public abstract class NestedBuilder<T, V> {
public T done() {
NestedBuilder - The Pattern
61
@SvenRuppert
public abstract class NestedBuilder<T, V> {
public T done() {
Class<?> parentClass = parent.getClass();
NestedBuilder - The Pattern
61
@SvenRuppert
public abstract class NestedBuilder<T, V> {
public T done() {
Class<?> parentClass = parent.getClass();
try {

V build = this.build();

String methodname = "with" + build.getClass().getSimpleName();

Method method = parentClass.getDeclaredMethod(

methodname, build.getClass());

method.invoke(parent, build);

} catch (NoSuchMethodException 

| IllegalAccessException | InvocationTargetException e) {

e.printStackTrace();

}
NestedBuilder - The Pattern
61
@SvenRuppert
public abstract class NestedBuilder<T, V> {
public T done() {
Class<?> parentClass = parent.getClass();
try {

V build = this.build();

String methodname = "with" + build.getClass().getSimpleName();

Method method = parentClass.getDeclaredMethod(

methodname, build.getClass());

method.invoke(parent, build);

} catch (NoSuchMethodException 

| IllegalAccessException | InvocationTargetException e) {

e.printStackTrace();

}
}
NestedBuilder - The Pattern
61
@SvenRuppert
public abstract class NestedBuilder<T, V> {
public T done() {
Class<?> parentClass = parent.getClass();
try {

V build = this.build();

String methodname = "with" + build.getClass().getSimpleName();

Method method = parentClass.getDeclaredMethod(

methodname, build.getClass());

method.invoke(parent, build);

} catch (NoSuchMethodException 

| IllegalAccessException | InvocationTargetException e) {

e.printStackTrace();

}
}
NestedBuilder - The Pattern
61
@SvenRuppert
public abstract class NestedBuilder<T, V> {
public T done() {
Class<?> parentClass = parent.getClass();
try {

V build = this.build();

String methodname = "with" + build.getClass().getSimpleName();

Method method = parentClass.getDeclaredMethod(

methodname, build.getClass());

method.invoke(parent, build);

} catch (NoSuchMethodException 

| IllegalAccessException | InvocationTargetException e) {

e.printStackTrace();

}
}
connect itself with parent
NestedBuilder - The Pattern
62
@SvenRuppert
NestedBuilder - The Pattern
62
@SvenRuppert
the basic steps in short words
NestedBuilder - The Pattern
62
@SvenRuppert
the basic steps in short words
the Parent-Builder will hold the Child-Builder
NestedBuilder - The Pattern
62
@SvenRuppert
the basic steps in short words
the Parent-Builder will hold the Child-Builder
the Parent-Builder will have a addChild - Method
NestedBuilder - The Pattern
62
@SvenRuppert
the basic steps in short words
the Parent-Builder will hold the Child-Builder
the Parent-Builder will have a addChild - Method
the Child-Builder will extend the NestedBuilder
NestedBuilder - The Pattern
62
@SvenRuppert
the basic steps in short words
the Parent-Builder will hold the Child-Builder
the Parent-Builder will have a addChild - Method
the Child-Builder will extend the NestedBuilder
the rest could be generated with a 

default Builder-Generator
NestedBuilder - The Pattern
63
@SvenRuppert
public class Parent {

private KidA kidA;

private KidB kidB;

//snipp.....

public static final class Builder {

private KidA kidA;

private KidB kidB;

// to add manually

private KidA.Builder builderKidA = KidA.newBuilder().withParentBuilder(this);

private KidB.Builder builderKidB = KidB.newBuilder().withParentBuilder(this);



public KidA.Builder addKidA() {

return this.builderKidA;

}

public KidB.Builder addKidB() {

return this.builderKidB;

}

//---------
NestedBuilder - The Pattern
63
@SvenRuppert
public class Parent {

private KidA kidA;

private KidB kidB;

//snipp.....

public static final class Builder {

private KidA kidA;

private KidB kidB;

// to add manually

private KidA.Builder builderKidA = KidA.newBuilder().withParentBuilder(this);

private KidB.Builder builderKidB = KidB.newBuilder().withParentBuilder(this);



public KidA.Builder addKidA() {

return this.builderKidA;

}

public KidB.Builder addKidB() {

return this.builderKidB;

}

//---------
NestedBuilder - The Pattern
63
@SvenRuppert
public class Parent {

private KidA kidA;

private KidB kidB;

//snipp.....

public static final class Builder {

private KidA kidA;

private KidB kidB;

// to add manually

private KidA.Builder builderKidA = KidA.newBuilder().withParentBuilder(this);

private KidB.Builder builderKidB = KidB.newBuilder().withParentBuilder(this);



public KidA.Builder addKidA() {

return this.builderKidA;

}

public KidB.Builder addKidB() {

return this.builderKidB;

}

//---------
connect itself with child
NestedBuilder - The Pattern
63
@SvenRuppert
public class Parent {

private KidA kidA;

private KidB kidB;

//snipp.....

public static final class Builder {

private KidA kidA;

private KidB kidB;

// to add manually

private KidA.Builder builderKidA = KidA.newBuilder().withParentBuilder(this);

private KidB.Builder builderKidB = KidB.newBuilder().withParentBuilder(this);



public KidA.Builder addKidA() {

return this.builderKidA;

}

public KidB.Builder addKidB() {

return this.builderKidB;

}

//---------
connect itself with child
NestedBuilder - The Pattern
63
@SvenRuppert
public class Parent {

private KidA kidA;

private KidB kidB;

//snipp.....

public static final class Builder {

private KidA kidA;

private KidB kidB;

// to add manually

private KidA.Builder builderKidA = KidA.newBuilder().withParentBuilder(this);

private KidB.Builder builderKidB = KidB.newBuilder().withParentBuilder(this);



public KidA.Builder addKidA() {

return this.builderKidA;

}

public KidB.Builder addKidB() {

return this.builderKidB;

}

//---------
connect itself with child
switch to Child-Builder
NestedBuilder - The Pattern
64
@SvenRuppert
public static final class Builder 

extends NestedBuilder<Parent.Builder, KidA> {
NestedBuilder - The Pattern
64
@SvenRuppert
public static final class Builder 

extends NestedBuilder<Parent.Builder, KidA> {
NestedBuilder - The Pattern
64
@SvenRuppert
only extends on Child-Builder
public static final class Builder 

extends NestedBuilder<Parent.Builder, KidA> {
NestedBuilder - The Pattern
65
@SvenRuppert
NestedBuilder - The Pattern
65
@SvenRuppert
Parent build = Parent.newBuilder()



.addKidA().withNote("A").done()

.addKidB().withNote("B").done()



.build();

System.out.println("build = " + build);
NestedBuilder - The Pattern
65
@SvenRuppert
Parent build = Parent.newBuilder()



.addKidA().withNote("A").done()

.addKidB().withNote("B").done()



.build();

System.out.println("build = " + build);
and a child could be a parent in the same time
NestedBuilder - The Pattern
65
@SvenRuppert
Parent build = Parent.newBuilder()



.addKidA().withNote("A").done()

.addKidB().withNote("B").done()



.build();

System.out.println("build = " + build);
and a child could be a parent in the same time
Parent build = Parent.newBuilder()

.addKidA().withNote("A")
.addKidB().withNote("B").done()
.done()

.build();
System.out.println("build = " + build);

NestedProxyBuilder - The Goal
66
@SvenRuppert
handwritten , params for diff Proxies
Combining Proxies
67
@SvenRuppert
Security Proxy Virtual ProxyRemote Proxy
Security ProxyVirtual ProxyRemote Proxy
Security ProxyVirtual Proxy Remote Proxy
VirtualProxies are mostly the last one
combining Proxies is easy
SecurityProxies are mostly the first one ?
Combining Proxies
67
@SvenRuppert
Security Proxy Virtual ProxyRemote Proxy
Security ProxyVirtual ProxyRemote Proxy
Security ProxyVirtual Proxy Remote Proxy
VirtualProxies are mostly the last one
combining Proxies is easy
SecurityProxies are mostly the first one ?
Combining Proxies
67
@SvenRuppert
Security Proxy Virtual ProxyRemote Proxy
Security ProxyVirtual ProxyRemote Proxy
Security ProxyVirtual Proxy Remote Proxy
VirtualProxies are mostly the last one
combining Proxies is easy
SecurityProxies are mostly the first one ?
Combining Proxies
67
@SvenRuppert
Security Proxy Virtual ProxyRemote Proxy
Security ProxyVirtual ProxyRemote Proxy
Security ProxyVirtual Proxy Remote Proxy
VirtualProxies are mostly the last one
combining Proxies is easy
SecurityProxies are mostly the first one ?
Combining Proxies
67
@SvenRuppert
Security Proxy Virtual ProxyRemote Proxy
Security ProxyVirtual ProxyRemote Proxy
Security ProxyVirtual Proxy Remote Proxy
VirtualProxies are mostly the last one
combining Proxies is easy
SecurityProxies are mostly the first one ?
DynamicProxyBuilder
68
@SvenRuppert
One functionality leads to one Proxy Instance
runtime overhead for every Proxy - but
make the first design simple.. optimize later
DynamicObjectAdapter - orig Version
69
@SvenRuppert
the original Version of the DynamicObjectAdapter
was written by Dr. Heinz Kabutz
DynamicObjectAdapter - orig Version
70
@SvenRuppert
DynamicObjectAdapter - orig Version
70
@SvenRuppert
DynamicObjectAdapter - orig Version
70
@SvenRuppert
Proxy
DynamicObjectAdapter - orig Version
70
@SvenRuppert
Proxy
orig /
adapter
DynamicObjectAdapter - orig Version
70
@SvenRuppert
Proxy
orig /
adapter
DynamicObjectAdapter - orig Version
70
@SvenRuppert
Proxy
orig /
adapter
invoke orig
DynamicObjectAdapter - orig Version
70
@SvenRuppert
Proxy
orig /
adapter
invoke orig
DynamicObjectAdapter - orig Version
70
@SvenRuppert
Proxy
orig /
adapter
invoke orig
invoke adapter
DynamicObjectAdapter - orig Version
70
@SvenRuppert
Proxy
orig /
adapter
invoke orig
invoke adapter
Goal: do not need to write an
Adapter with Delegator
DynamicObjectAdapter - orig Version
71
@SvenRuppert
core concept:
switching between method implementations
DynamicObjectAdapter - orig Version
71
@SvenRuppert
core concept:
switching between method implementations
how to identify a method?
DynamicObjectAdapter - orig. Version
72
@SvenRuppert
public interface Service {

String doWork_A();

}



public static class ServiceImpl implements Service {

public String doWork_A() {

return ServiceImpl.class.getSimpleName();

}

}
DynamicObjectAdapter - orig Version
73
@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(); }

}
DynamicObjectAdapter - orig Version
73
@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(); }

}
DynamicObjectAdapter - orig Version
73
@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(); }

}
DynamicObjectAdapter - orig. Version
74
@SvenRuppert
DynamicObjectAdapter - orig. Version
74
@SvenRuppert
private static class DOAInvocationHandler<T extends I, I> implements InvocationHandler {
DynamicObjectAdapter - orig. Version
74
@SvenRuppert
private static class DOAInvocationHandler<T extends I, I> implements InvocationHandler {
private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();
DynamicObjectAdapter - orig. Version
74
@SvenRuppert
private static class DOAInvocationHandler<T extends I, I> implements InvocationHandler {
private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();
private T original;
DynamicObjectAdapter - orig. Version
74
@SvenRuppert
private static class DOAInvocationHandler<T extends I, I> implements InvocationHandler {
private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();
private T original; private Object adapter;
DynamicObjectAdapter - orig. Version
74
@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) {
DynamicObjectAdapter - orig. Version
74
@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;
DynamicObjectAdapter - orig. Version
74
@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();
DynamicObjectAdapter - orig. Version
74
@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();
DynamicObjectAdapter - orig. Version
74
@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) {
DynamicObjectAdapter - orig. Version
74
@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);
DynamicObjectAdapter - orig. Version
74
@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);
DynamicObjectAdapter - orig. Version
74
@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);
}

}
DynamicObjectAdapter - orig. Version
74
@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 {
DynamicObjectAdapter - orig. Version
74
@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
DynamicObjectAdapter - orig. Version
74
@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
DynamicObjectAdapter - orig. Version
75
@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) {
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
}

}
//SNIPP
DynamicObjectAdapter - orig. Version
75
@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) {
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
try {

final MethodIdentifier key = new MethodIdentifier(m);
}

}
//SNIPP
DynamicObjectAdapter - orig. Version
75
@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) {
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Method other = adaptedMethods.get(key);
try {

final MethodIdentifier key = new MethodIdentifier(m);
}

}
//SNIPP
DynamicObjectAdapter - orig. Version
75
@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) {
}
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); }
}

}
//SNIPP
DynamicObjectAdapter - orig. Version
75
@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) {
}
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
DynamicObjectAdapter - orig. Version
75
@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
DynamicObjectAdapter - orig. Version
75
@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 ?
DynamicObjectAdapter - orig. Version
75
@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 ?
DynamicObjectAdapter - orig. Version
76
@SvenRuppert
private 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 ?
DynamicObjectAdapter - orig. Version
76
@SvenRuppert
private 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();

}
DynamicObjectAdapter - orig. Version
76
@SvenRuppert
private 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() { .. }

}
DynamicObjectAdapter - orig. Version
76
@SvenRuppert
private 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() { .. }

}
DynamicObjectAdapter - orig. Version
76
@SvenRuppert
private 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() { .. }

}
DynamicObjectAdapter - orig. Version
76
@SvenRuppert
private 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() { .. }

}
DynamicObjectAdapter - orig Version
77
@SvenRuppert
Proxy
orig /
adapter
invoke orig
invoke adapter
DynamicObjectAdapter - ext. Version
78
@SvenRuppert
first extension !
DynamicObjectAdapter - ext. Version
79
@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";

}

}
DynamicObjectAdapter - ext. Version
80
@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);

}
DynamicObjectAdapter - ext. Version
80
@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);

}
DynamicObjectAdapter - ext. Version
80
@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
DynamicObjectAdapter - ext. Version
80
@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
DynamicObjectAdapter - ext. Version
80
@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
DynamicObjectAdapter - ext. Version
81
@SvenRuppert
private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();

private Map<MethodIdentifier, Object> adapters = new HashMap<>();



private T original;

private Class<T> target;
DynamicObjectAdapter - ext. Version
81
@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) {
DynamicObjectAdapter - ext. Version
81
@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();
DynamicObjectAdapter - ext. Version
81
@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();
DynamicObjectAdapter - ext. Version
81
@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) {
DynamicObjectAdapter - ext. Version
81
@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);
DynamicObjectAdapter - ext. Version
81
@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);
DynamicObjectAdapter - ext. Version
81
@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);
DynamicObjectAdapter - ext. Version
81
@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);
DynamicObjectAdapter - ext. Version
82
@SvenRuppert
private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();

private Map<MethodIdentifier, Object> adapters = new HashMap<>();



private T original;

private Class<T> target;
DynamicObjectAdapter - ext. Version
82
@SvenRuppert
private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();

private Map<MethodIdentifier, Object> adapters = new HashMap<>();



private T original;

private Class<T> target;
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
DynamicObjectAdapter - ext. Version
82
@SvenRuppert
private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();

private Map<MethodIdentifier, Object> adapters = new HashMap<>();



private T original;

private Class<T> target;
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {

final MethodIdentifier key = new MethodIdentifier(method);

Method other = adaptedMethods.get(key);
DynamicObjectAdapter - ext. Version
82
@SvenRuppert
private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();

private Map<MethodIdentifier, Object> adapters = new HashMap<>();



private T original;

private Class<T> target;
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);

}

DynamicObjectAdapter - ext. Version
82
@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);

}

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 !!
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 !!
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
DynamicObjectAdapter - orig Version @SvenRuppert
Add some typed with-Methods
public AdapterBuilder<T> withDoWork_A(ServiceAdapter_A adapter) {

addAdapter(adapter);

return this;

}
DynamicObjectAdapter - orig Version @SvenRuppert
Add some typed with-Methods
public AdapterBuilder<T> withDoWork_A(ServiceAdapter_A adapter) {

addAdapter(adapter);

return this;

}
remember
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);

}
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);

}

DynamicObjectAdapter - orig Version @SvenRuppert
How to use this?
DynamicObjectAdapter - orig Version @SvenRuppert
How to use this?
Service service = AdapterBuilder.<Service>newBuilder()
DynamicObjectAdapter - orig Version @SvenRuppert
How to use this?
Service service = AdapterBuilder.<Service>newBuilder()
.withTarget(Service.class)
DynamicObjectAdapter - orig Version @SvenRuppert
How to use this?
Service service = AdapterBuilder.<Service>newBuilder()
.withTarget(Service.class)
.withOriginal(new ServiceImpl())
DynamicObjectAdapter - orig Version @SvenRuppert
How to use this?
Service service = AdapterBuilder.<Service>newBuilder()
.withTarget(Service.class)
.withOriginal(new ServiceImpl())
.withDoWork_A((txt) -> txt + "_part")
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")
DynamicObjectAdapter - orig Version @SvenRuppert
How to use this like a mock ?
DynamicObjectAdapter - orig Version @SvenRuppert
How to use this like a mock ?
Service service = AdapterBuilder.<Service>newBuilder()
DynamicObjectAdapter - orig Version @SvenRuppert
How to use this like a mock ?
Service service = AdapterBuilder.<Service>newBuilder()
.withTarget(Service.class)
DynamicObjectAdapter - orig Version @SvenRuppert
How to use this like a mock ?
Service service = AdapterBuilder.<Service>newBuilder()
.withTarget(Service.class)
.withOriginal(null)
DynamicObjectAdapter - orig Version @SvenRuppert
How to use this like a mock ?
Service service = AdapterBuilder.<Service>newBuilder()
.withTarget(Service.class)
.withOriginal(null)
.withDoWork_A((txt) -> txt + "_part")
DynamicObjectAdapter - orig Version @SvenRuppert
.build();
How to use this like a mock ?
Service service = AdapterBuilder.<Service>newBuilder()
.withTarget(Service.class)
.withOriginal(null)
.withDoWork_A((txt) -> txt + "_part")
generated DynamicObjectAdapterBuilder @SvenRuppert
To much boring code to write
but we want to have a type-safe version
if wrong… compile must break
generated DynamicObjectAdapterBuilder @SvenRuppert
To much boring code to write
but we want to have a type-safe version
What could we
change now ?
if wrong… compile must break
generated DynamicObjectAdapterBuilder @SvenRuppert
remember
generated DynamicObjectAdapterBuilder @SvenRuppert
remember
public interface Service {

String doWork_A(String txt);

String doWork_B(String txt);

}
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);

}
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);

}
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
generated DynamicObjectAdapterBuilder @SvenRuppert
use Annotation Processing
generated DynamicObjectAdapterBuilder @SvenRuppert
use Annotation Processing
create a marker like
@DynamicObjectAdapterBuilder
generated DynamicObjectAdapterBuilder @SvenRuppert
use Annotation Processing
create a marker like
@DynamicObjectAdapterBuilder
@Retention(RetentionPolicy.SOURCE)

@Target(ElementType.TYPE)

public @interface DynamicObjectAdapterBuilder {

}
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
generated DynamicObjectAdapterBuilder @SvenRuppert
use Annotation Processing
with every compile you will get actual
generated DynamicObjectAdapterBuilder @SvenRuppert
use Annotation Processing
with every compile you will get actual
Functional-Interfaces for the Adapters
generated DynamicObjectAdapterBuilder @SvenRuppert
use Annotation Processing
with every compile you will get actual
Functional-Interfaces for the Adapters
generated AdapterBuilder
StaticObjectAdapter @SvenRuppert
to avoid the latency of the dynamic Proxy
we could implement static ObjectAdapter
the basic idea is the same as we had 

with the DynamicObjectAdapter
StaticObjectAdapter @SvenRuppert
split the interface into Functional Interfaces
create for every Functional Interface an attribute
at runtime: if an attribute 

is available invoke the method …..
otherwise use the delegator
StaticObjectAdapter @SvenRuppert
public interface Service {

String doWorkA(String txt);

String doWorkB(String txt);

}
StaticObjectAdapter @SvenRuppert
public interface Service {

String doWorkA(String txt);

String doWorkB(String txt);

}
public interface Service_DoWorkA_Adapter{ 

String doWorkA(final String txt); 

}

public interface Service_DoWorkB_Adapter{ 

String doWorkB(final String txt); 

}
StaticObjectAdapter @SvenRuppert
public interface Service {

String doWorkA(String txt);

String doWorkB(String txt);

}
public interface Service_DoWorkA_Adapter{ 

String doWorkA(final String txt); 

}

public interface Service_DoWorkB_Adapter{ 

String doWorkB(final String txt); 

}
StaticObjectAdapter @SvenRuppert
public interface Service {

String doWorkA(String txt);

String doWorkB(String txt);

}
public interface Service_DoWorkA_Adapter{ 

String doWorkA(final String txt); 

}

public interface Service_DoWorkB_Adapter{ 

String doWorkB(final String txt); 

}
functional interface
StaticObjectAdapter @SvenRuppert
StaticObjectAdapter @SvenRuppert
public class ServiceStaticObjectAdapter implements Service {
StaticObjectAdapter @SvenRuppert
public class ServiceStaticObjectAdapter implements Service {
private Service service;
StaticObjectAdapter @SvenRuppert
public class ServiceStaticObjectAdapter implements Service {
private Service service;
private Service_DoWorkA_Adapter doWorkAAdapter;
StaticObjectAdapter @SvenRuppert
public class ServiceStaticObjectAdapter implements Service {
private Service service;
private Service_DoWorkA_Adapter doWorkAAdapter;
private Service_DoWorkB_Adapter doWorkBAdapter;
StaticObjectAdapter @SvenRuppert
public class ServiceStaticObjectAdapter implements Service {
private Service service;
private Service_DoWorkA_Adapter doWorkAAdapter;
private Service_DoWorkB_Adapter doWorkBAdapter;
public String doWorkA(final String txt) {
}
StaticObjectAdapter @SvenRuppert
public class ServiceStaticObjectAdapter implements Service {
private Service service;
private Service_DoWorkA_Adapter doWorkAAdapter;
private Service_DoWorkB_Adapter doWorkBAdapter;
public String doWorkA(final String txt) {
if (this.doWorkAAdapter != null)
}
StaticObjectAdapter @SvenRuppert
public class ServiceStaticObjectAdapter implements Service {
private Service service;
private Service_DoWorkA_Adapter doWorkAAdapter;
private Service_DoWorkB_Adapter doWorkBAdapter;
public String doWorkA(final String txt) {
if (this.doWorkAAdapter != null) return this.doWorkAAdapter.doWorkA(txt);
}
StaticObjectAdapter @SvenRuppert
public class ServiceStaticObjectAdapter implements Service {
private Service service;
private Service_DoWorkA_Adapter doWorkAAdapter;
private Service_DoWorkB_Adapter doWorkBAdapter;
public String doWorkA(final String txt) {
if (this.doWorkAAdapter != null) return this.doWorkAAdapter.doWorkA(txt);
return service.doWorkA(txt)
}
StaticObjectAdapter @SvenRuppert
public class ServiceStaticObjectAdapter implements Service {
private Service service;
private Service_DoWorkA_Adapter doWorkAAdapter;
private Service_DoWorkB_Adapter doWorkBAdapter;
public String doWorkA(final String txt) {
if (this.doWorkAAdapter != null) return this.doWorkAAdapter.doWorkA(txt);
return service.doWorkA(txt)
}
We can generate
this !
generated StaticObjectAdapter @SvenRuppert
with AnnotationProcessing
split the interface with @StaticObjectAdapter
write functional interfaces
generate the StaticObjectAdapter
mark the Adapter with @IsObjectAdapter
prepare for…..
Proxy Deep Dive -
StaticVirtualProxy - at Runtime
some words about :
how it works..and what you can do with this..
96
@SvenRuppert
97
@SvenRuppert
97
@SvenRuppert
generate Static Proxies at Runtime @SvenRuppert
this is based on the
Newsletter Nr 180 and Nr 181
from Dr. Heinz Kabutz
http://www.javaspecialists.eu/archive/Issue181.html
http://www.javaspecialists.eu/archive/Issue180.html
generate Static Proxies at Runtime @SvenRuppert
questions are:
generate Static Proxies at Runtime @SvenRuppert
questions are:
How to compile In-Memory ?
generate Static Proxies at Runtime @SvenRuppert
questions are:
How to compile In-Memory ?
What is the right ClassLoader ?
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
you will need the JavaCompiler from tools.jar
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
you will need the JavaCompiler from tools.jar
a holder for the SourceCode
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
you will need the JavaCompiler from tools.jar
a holder for the SourceCode
public class GeneratedJavaSourceFile extends SimpleJavaFileObject {



private CharSequence javaSource;







public GeneratedJavaSourceFile(String className, CharSequence javaSource) {

super(URI.create(className + ".java"), Kind.SOURCE);

this.javaSource = javaSource;

}



public CharSequence getCharContent(boolean ignoreEncodeErrors)

throws IOException {

return javaSource;

}

}
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
you will need the JavaCompiler from tools.jar
a holder for the SourceCode
public class GeneratedJavaSourceFile extends SimpleJavaFileObject {



private CharSequence javaSource;







public GeneratedJavaSourceFile(String className, CharSequence javaSource) {

super(URI.create(className + ".java"), Kind.SOURCE);

this.javaSource = javaSource;

}



public CharSequence getCharContent(boolean ignoreEncodeErrors)

throws IOException {

return javaSource;

}

}
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
you will need the JavaCompiler from tools.jar
a holder for the SourceCode
public class GeneratedJavaSourceFile extends SimpleJavaFileObject {



private CharSequence javaSource;







public GeneratedJavaSourceFile(String className, CharSequence javaSource) {

super(URI.create(className + ".java"), Kind.SOURCE);

this.javaSource = javaSource;

}



public CharSequence getCharContent(boolean ignoreEncodeErrors)

throws IOException {

return javaSource;

}

}
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
you will need the JavaCompiler from tools.jar
a holder for the SourceCode
public class GeneratedJavaSourceFile extends SimpleJavaFileObject {



private CharSequence javaSource;







public GeneratedJavaSourceFile(String className, CharSequence javaSource) {

super(URI.create(className + ".java"), Kind.SOURCE);

this.javaSource = javaSource;

}



public CharSequence getCharContent(boolean ignoreEncodeErrors)

throws IOException {

return javaSource;

}

}
the generated source code
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
a holder for the ByteCode
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
a holder for the ByteCode
public class GeneratedClassFile extends SimpleJavaFileObject {

private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();



public GeneratedClassFile() {

super(URI.create("generated.class"), Kind.CLASS);

}



public OutputStream openOutputStream() {

return outputStream;

}



public byte[] getClassAsBytes() {

return outputStream.toByteArray();

}

}
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
a holder for the ByteCode
public class GeneratedClassFile extends SimpleJavaFileObject {

private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();



public GeneratedClassFile() {

super(URI.create("generated.class"), Kind.CLASS);

}



public OutputStream openOutputStream() {

return outputStream;

}



public byte[] getClassAsBytes() {

return outputStream.toByteArray();

}

}
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
a holder for the ByteCode
public class GeneratedClassFile extends SimpleJavaFileObject {

private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();



public GeneratedClassFile() {

super(URI.create("generated.class"), Kind.CLASS);

}



public OutputStream openOutputStream() {

return outputStream;

}



public byte[] getClassAsBytes() {

return outputStream.toByteArray();

}

}
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
a holder for the ByteCode
public class GeneratedClassFile extends SimpleJavaFileObject {

private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();



public GeneratedClassFile() {

super(URI.create("generated.class"), Kind.CLASS);

}



public OutputStream openOutputStream() {

return outputStream;

}



public byte[] getClassAsBytes() {

return outputStream.toByteArray();

}

}
the generated ByteCode
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
a ForwardingJavaFileManager
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
a ForwardingJavaFileManager
public class GeneratingJavaFileManager 

extends ForwardingJavaFileManager<JavaFileManager> {



private final GeneratedClassFile gcf;





public GeneratingJavaFileManager( 

StandardJavaFileManager sjfm, 

GeneratedClassFile gcf) {

super(sjfm);

this.gcf = gcf;

}

public JavaFileObject getJavaFileForOutput(

Location location, String className,

JavaFileObject.Kind kind, FileObject sibling)

throws IOException {

return gcf;

}

}
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
a ForwardingJavaFileManager
public class GeneratingJavaFileManager 

extends ForwardingJavaFileManager<JavaFileManager> {



private final GeneratedClassFile gcf;





public GeneratingJavaFileManager( 

StandardJavaFileManager sjfm, 

GeneratedClassFile gcf) {

super(sjfm);

this.gcf = gcf;

}

public JavaFileObject getJavaFileForOutput(

Location location, String className,

JavaFileObject.Kind kind, FileObject sibling)

throws IOException {

return gcf;

}

}
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
a ForwardingJavaFileManager
public class GeneratingJavaFileManager 

extends ForwardingJavaFileManager<JavaFileManager> {



private final GeneratedClassFile gcf;





public GeneratingJavaFileManager( 

StandardJavaFileManager sjfm, 

GeneratedClassFile gcf) {

super(sjfm);

this.gcf = gcf;

}

public JavaFileObject getJavaFileForOutput(

Location location, String className,

JavaFileObject.Kind kind, FileObject sibling)

throws IOException {

return gcf;

}

}
will force the 

JavaCompiler to write 

to this instance
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
a ForwardingJavaFileManager
public class GeneratingJavaFileManager 

extends ForwardingJavaFileManager<JavaFileManager> {



private final GeneratedClassFile gcf;





public GeneratingJavaFileManager( 

StandardJavaFileManager sjfm, 

GeneratedClassFile gcf) {

super(sjfm);

this.gcf = gcf;

}

public JavaFileObject getJavaFileForOutput(

Location location, String className,

JavaFileObject.Kind kind, FileObject sibling)

throws IOException {

return gcf;

}

}
will force the 

JavaCompiler to write 

to this instance
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
a ForwardingJavaFileManager
public class GeneratingJavaFileManager 

extends ForwardingJavaFileManager<JavaFileManager> {



private final GeneratedClassFile gcf;





public GeneratingJavaFileManager( 

StandardJavaFileManager sjfm, 

GeneratedClassFile gcf) {

super(sjfm);

this.gcf = gcf;

}

public JavaFileObject getJavaFileForOutput(

Location location, String className,

JavaFileObject.Kind kind, FileObject sibling)

throws IOException {

return gcf;

}

}
the generated ByteCode
will force the 

JavaCompiler to write 

to this instance
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
the compile task itself
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
the compile task itself
GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource);
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
the compile task itself
GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource);
DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>();
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
the compile task itself
GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource);
DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>();
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
the compile task itself
GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource);
StandardJavaFileManager stdFileManager = jc.getStandardFileManager(dc, null, null);
DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>();
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
the compile task itself
GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource);
StandardJavaFileManager stdFileManager = jc.getStandardFileManager(dc, null, null);
DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>();
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
GeneratedClassFile gcf = new GeneratedClassFile();
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
the compile task itself
GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource);
StandardJavaFileManager stdFileManager = jc.getStandardFileManager(dc, null, null);
GeneratingJavaFileManager fileManager 

= new GeneratingJavaFileManager(stdFileManager, gcf);
DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>();
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
GeneratedClassFile gcf = new GeneratedClassFile();
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
the compile task itself
GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource);
StandardJavaFileManager stdFileManager = jc.getStandardFileManager(dc, null, null);
GeneratingJavaFileManager fileManager 

= new GeneratingJavaFileManager(stdFileManager, gcf);
JavaCompiler.CompilationTask task 

= jc.getTask(null, fileManager, dc, null, null, singletonList(gjsf));
DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>();
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
GeneratedClassFile gcf = new GeneratedClassFile();
generate Static Proxies at Runtime @SvenRuppert
How to compile In-Memory ?
the compile task itself
return task.call();
GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource);
StandardJavaFileManager stdFileManager = jc.getStandardFileManager(dc, null, null);
GeneratingJavaFileManager fileManager 

= new GeneratingJavaFileManager(stdFileManager, gcf);
JavaCompiler.CompilationTask task 

= jc.getTask(null, fileManager, dc, null, null, singletonList(gjsf));
DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>();
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
GeneratedClassFile gcf = new GeneratedClassFile();
generate Static Proxies at Runtime @SvenRuppert
What is the right ClassLoader ?
generate Static Proxies at Runtime @SvenRuppert
could be: public Unsafe.defineClass()
What is the right ClassLoader ?
generate Static Proxies at Runtime @SvenRuppert
could be: public Unsafe.defineClass()
What is the right ClassLoader ?
or: private static Proxy.defineClass0()
generate Static Proxies at Runtime @SvenRuppert
could be: public Unsafe.defineClass()
What is the right ClassLoader ?
or: private static Proxy.defineClass0()
both versions are
depending on the
selected JVM
generate Static Proxies at Runtime @SvenRuppert
could be: public Unsafe.defineClass()
What is the right ClassLoader ?
or: private static Proxy.defineClass0()
both versions are
depending on the
selected JVM
but this solution will have 

no roundtrip over the hard disc
generate Static Proxies at Runtime @SvenRuppert
could be: public Unsafe.defineClass()
What is the right ClassLoader ?
or: private static Proxy.defineClass0()
both versions are
depending on the
selected JVM
but this solution will have 

no roundtrip over the hard disc
will create and compile 

Proxies at runtime
prepare for…..
Proxy Deep Dive - Summary
what we reached, what we could do now
105
@SvenRuppert
106
@SvenRuppert
106
@SvenRuppert
Summary
107
@SvenRuppert
we got type-safe ProxyBuilder
..type-safe generated DynamicObjectAdapter
..at runtime we could change the chain of Proxies
..could be used for
(Dynamic)
Dependency Injection Implementations
Summary
108
@SvenRuppert
If you are interested…
have a look at RapidPM on github
rapidpm-proxybuilder
rapidpm-dynamic-cdi
rapidpm-microservice
or contact me ;-) @SvenRuppert
Summary
108
@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 !!!

More Related Content

What's hot (19)

PDF
Sailing with Java 8 Streams
Ganesh Samarthyam
 
PDF
Productive Programming in Java 8 - with Lambdas and Streams
Ganesh Samarthyam
 
PDF
Java Class Design
Ganesh Samarthyam
 
PDF
Creating Lazy stream in CSharp
Dhaval Dalal
 
PDF
Functional Programming in Java 8 - Exploiting Lambdas
Ganesh Samarthyam
 
PDF
Java SE 8 for Java EE developers
José Paumard
 
PDF
Completable future
Srinivasan Raghvan
 
PDF
Java 5 and 6 New Features
Jussi Pohjolainen
 
PDF
Java 8: the good parts!
Andrzej Grzesik
 
PDF
Currying and Partial Function Application (PFA)
Dhaval Dalal
 
PDF
Refactoring to Java 8 (Devoxx BE)
Trisha Gee
 
PDF
Java 7 New Features
Jussi Pohjolainen
 
PDF
Building Maintainable Applications in Apex
Jeffrey Kemp
 
PDF
Free your lambdas
José Paumard
 
ODP
Porting Applications From Oracle To PostgreSQL
Peter Eisentraut
 
PDF
Java(8) The Good, The Bad and the Ugly
Brian Vermeer
 
PPTX
Introduction to nsubstitute
Suresh Loganatha
 
PDF
PHP 8: What's New and Changed
Ayesh Karunaratne
 
PDF
Refactoring for Software Design Smells - Tech Talk
CodeOps Technologies LLP
 
Sailing with Java 8 Streams
Ganesh Samarthyam
 
Productive Programming in Java 8 - with Lambdas and Streams
Ganesh Samarthyam
 
Java Class Design
Ganesh Samarthyam
 
Creating Lazy stream in CSharp
Dhaval Dalal
 
Functional Programming in Java 8 - Exploiting Lambdas
Ganesh Samarthyam
 
Java SE 8 for Java EE developers
José Paumard
 
Completable future
Srinivasan Raghvan
 
Java 5 and 6 New Features
Jussi Pohjolainen
 
Java 8: the good parts!
Andrzej Grzesik
 
Currying and Partial Function Application (PFA)
Dhaval Dalal
 
Refactoring to Java 8 (Devoxx BE)
Trisha Gee
 
Java 7 New Features
Jussi Pohjolainen
 
Building Maintainable Applications in Apex
Jeffrey Kemp
 
Free your lambdas
José Paumard
 
Porting Applications From Oracle To PostgreSQL
Peter Eisentraut
 
Java(8) The Good, The Bad and the Ugly
Brian Vermeer
 
Introduction to nsubstitute
Suresh Loganatha
 
PHP 8: What's New and Changed
Ayesh Karunaratne
 
Refactoring for Software Design Smells - Tech Talk
CodeOps Technologies LLP
 

Viewers also liked (9)

PDF
Proxy & CGLIB
beom kyun choi
 
DOCX
Object relationship mapping and hibernate
Joe Jacob
 
PDF
Dynamic Proxy by Java
Kan-Han (John) Lu
 
PDF
Classloading and Type Visibility in OSGi
martinlippert
 
PPT
hibernate with JPA
Mohammad Faizan
 
PDF
Understanding Java Dynamic Proxies
OSOCO
 
PDF
AWS CloudFormation en 5 Minutos
OSOCO
 
PPTX
Hibernate in Action
Akshay Ballarpure
 
PDF
Hibernate Presentation
guest11106b
 
Proxy & CGLIB
beom kyun choi
 
Object relationship mapping and hibernate
Joe Jacob
 
Dynamic Proxy by Java
Kan-Han (John) Lu
 
Classloading and Type Visibility in OSGi
martinlippert
 
hibernate with JPA
Mohammad Faizan
 
Understanding Java Dynamic Proxies
OSOCO
 
AWS CloudFormation en 5 Minutos
OSOCO
 
Hibernate in Action
Akshay Ballarpure
 
Hibernate Presentation
guest11106b
 
Ad

Similar to Proxy deep-dive java-one_20151027_001 (20)

PDF
Proxy Deep Dive Voxxed Belgrad 2015
Sven Ruppert
 
PDF
Proxy Deep Dive JUG Saxony Day 2015-10-02
Sven Ruppert
 
PPT
Adapter Poxy Pattern
Philip Zhong
 
PPTX
Design patterns
Alok Guha
 
PPTX
Proxy & adapter pattern
babak danyal
 
PPT
Proxy pattern
Chester Hartin
 
PDF
Gang of four Proxy Design Pattern
Mainak Goswami
 
PDF
Adapter Pattern Abhijit Hiremagalur 200603
melbournepatterns
 
PPTX
Proxy Design Patterns
Zafer Genc
 
PPTX
Structural pattern 3
Naga Muruga
 
PPSX
Proxy design pattern
Sase Kleckovski
 
PPTX
Proxy Design Pattern
Anjan Kumar Bollam
 
PPTX
Factory method, strategy pattern & chain of responsibilities
babak danyal
 
PDF
Software and architecture design pattern
sanjanakorawar
 
PDF
Design Patterns
Ahmad Hussein
 
DOCX
Static binding
vishal choudhary
 
PPTX
L04 base patterns
Ólafur Andri Ragnarsson
 
PDF
DesignPatternScard.pdf
JTLai1
 
PDF
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Ahmed Mohamed
 
PPTX
Proxy Pattern
Hüseyin Ergin
 
Proxy Deep Dive Voxxed Belgrad 2015
Sven Ruppert
 
Proxy Deep Dive JUG Saxony Day 2015-10-02
Sven Ruppert
 
Adapter Poxy Pattern
Philip Zhong
 
Design patterns
Alok Guha
 
Proxy & adapter pattern
babak danyal
 
Proxy pattern
Chester Hartin
 
Gang of four Proxy Design Pattern
Mainak Goswami
 
Adapter Pattern Abhijit Hiremagalur 200603
melbournepatterns
 
Proxy Design Patterns
Zafer Genc
 
Structural pattern 3
Naga Muruga
 
Proxy design pattern
Sase Kleckovski
 
Proxy Design Pattern
Anjan Kumar Bollam
 
Factory method, strategy pattern & chain of responsibilities
babak danyal
 
Software and architecture design pattern
sanjanakorawar
 
Design Patterns
Ahmad Hussein
 
Static binding
vishal choudhary
 
L04 base patterns
Ólafur Andri Ragnarsson
 
DesignPatternScard.pdf
JTLai1
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Ahmed Mohamed
 
Proxy Pattern
Hüseyin Ergin
 
Ad

More from Sven Ruppert (13)

PDF
JUnit5 Custom TestEngines intro - version 2020-06
Sven Ruppert
 
PDF
Hidden pearls for High-Performance-Persistence
Sven Ruppert
 
PDF
Vaadin Flow - How to start - a short intro for Java Devs
Sven Ruppert
 
PDF
Functional Reactive With Core Java - Voxxed Melbourne
Sven Ruppert
 
PDF
Functional Reactive with Core Java - Workshop - Slides
Sven Ruppert
 
PDF
Functional reactive-talk 20170301-001
Sven Ruppert
 
PDF
From Mess To Masterpiece - JFokus 2017
Sven Ruppert
 
PDF
From Jurassic Park to Microservices
Sven Ruppert
 
PDF
From jUnit to Mutationtesting
Sven Ruppert
 
PDF
Warum ich so auf das c von cdi stehe
Sven Ruppert
 
PDF
Java8 ready for the future
Sven Ruppert
 
PDF
JavaFX8 TestFX - CDI
Sven Ruppert
 
PDF
Java FX8 JumpStart - JUG ch - zürich
Sven Ruppert
 
JUnit5 Custom TestEngines intro - version 2020-06
Sven Ruppert
 
Hidden pearls for High-Performance-Persistence
Sven Ruppert
 
Vaadin Flow - How to start - a short intro for Java Devs
Sven Ruppert
 
Functional Reactive With Core Java - Voxxed Melbourne
Sven Ruppert
 
Functional Reactive with Core Java - Workshop - Slides
Sven Ruppert
 
Functional reactive-talk 20170301-001
Sven Ruppert
 
From Mess To Masterpiece - JFokus 2017
Sven Ruppert
 
From Jurassic Park to Microservices
Sven Ruppert
 
From jUnit to Mutationtesting
Sven Ruppert
 
Warum ich so auf das c von cdi stehe
Sven Ruppert
 
Java8 ready for the future
Sven Ruppert
 
JavaFX8 TestFX - CDI
Sven Ruppert
 
Java FX8 JumpStart - JUG ch - zürich
Sven Ruppert
 

Recently uploaded (20)

PPTX
Transforming Mining & Engineering Operations with Odoo ERP | Streamline Proje...
SatishKumar2651
 
PDF
Generic or Specific? Making sensible software design decisions
Bert Jan Schrijver
 
PPTX
Empowering Asian Contributions: The Rise of Regional User Groups in Open Sour...
Shane Coughlan
 
PDF
HiHelloHR – Simplify HR Operations for Modern Workplaces
HiHelloHR
 
PPTX
Help for Correlations in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PDF
Alexander Marshalov - How to use AI Assistants with your Monitoring system Q2...
VictoriaMetrics
 
PDF
How to Hire AI Developers_ Step-by-Step Guide in 2025.pdf
DianApps Technologies
 
PDF
TheFutureIsDynamic-BoxLang witch Luis Majano.pdf
Ortus Solutions, Corp
 
PPTX
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
PPTX
In From the Cold: Open Source as Part of Mainstream Software Asset Management
Shane Coughlan
 
PPTX
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
PPTX
Tally software_Introduction_Presentation
AditiBansal54083
 
PPTX
Milwaukee Marketo User Group - Summer Road Trip: Mapping and Personalizing Yo...
bbedford2
 
PDF
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
PPTX
OpenChain @ OSS NA - In From the Cold: Open Source as Part of Mainstream Soft...
Shane Coughlan
 
PDF
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
PDF
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
PDF
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pdf
Varsha Nayak
 
PPTX
Agentic Automation Journey Series Day 2 – Prompt Engineering for UiPath Agents
klpathrudu
 
Transforming Mining & Engineering Operations with Odoo ERP | Streamline Proje...
SatishKumar2651
 
Generic or Specific? Making sensible software design decisions
Bert Jan Schrijver
 
Empowering Asian Contributions: The Rise of Regional User Groups in Open Sour...
Shane Coughlan
 
HiHelloHR – Simplify HR Operations for Modern Workplaces
HiHelloHR
 
Help for Correlations in IBM SPSS Statistics.pptx
Version 1 Analytics
 
Alexander Marshalov - How to use AI Assistants with your Monitoring system Q2...
VictoriaMetrics
 
How to Hire AI Developers_ Step-by-Step Guide in 2025.pdf
DianApps Technologies
 
TheFutureIsDynamic-BoxLang witch Luis Majano.pdf
Ortus Solutions, Corp
 
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
In From the Cold: Open Source as Part of Mainstream Software Asset Management
Shane Coughlan
 
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
Tally software_Introduction_Presentation
AditiBansal54083
 
Milwaukee Marketo User Group - Summer Road Trip: Mapping and Personalizing Yo...
bbedford2
 
4K Video Downloader Plus Pro Crack for MacOS New Download 2025
bashirkhan333g
 
OpenChain @ OSS NA - In From the Cold: Open Source as Part of Mainstream Soft...
Shane Coughlan
 
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pdf
Varsha Nayak
 
Agentic Automation Journey Series Day 2 – Prompt Engineering for UiPath Agents
klpathrudu
 

Proxy deep-dive java-one_20151027_001

  • 1. prepare for….. Proxy Deep Dive JavaOne 2015 20151027 1 @SvenRuppert
  • 2. @SvenRuppert has been coding java since 1996 Fellow / Senior Manager reply Group Germany - Munich 2
  • 3. @SvenRuppert has been coding java since 1996 3
  • 4. @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
  • 5. prepare for….. Proxy Deep Dive - the first steps some words about Adapter, Delegator and the first Proxy 4 @SvenRuppert
  • 8. Why a Proxy ? 6 @SvenRuppert Proxies you can use them for : generic parts inside your application hiding technical stuff decouple parts of your applications
  • 9. Why a Proxy ? 7 @SvenRuppert but it must be easy to use like…
  • 10. Why a Proxy ? 7 @SvenRuppert final InnerDemoClass original = new InnerDemoClass(); but it must be easy to use like…
  • 11. Why a Proxy ? 7 @SvenRuppert final InnerDemoClass original = new InnerDemoClass(); final InnerDemoInterface demoLogic = but it must be easy to use like…
  • 12. Why a Proxy ? 7 @SvenRuppert final InnerDemoClass original = new InnerDemoClass(); final InnerDemoInterface demoLogic = ProxyBuilder.createBuilder(InnerDemoInterface.class, original) but it must be easy to use like…
  • 13. Why a Proxy ? 7 @SvenRuppert final InnerDemoClass original = new InnerDemoClass(); final InnerDemoInterface demoLogic = ProxyBuilder.createBuilder(InnerDemoInterface.class, original) .addLogging() but it must be easy to use like…
  • 14. Why a Proxy ? 7 @SvenRuppert final InnerDemoClass original = new InnerDemoClass(); final InnerDemoInterface demoLogic = ProxyBuilder.createBuilder(InnerDemoInterface.class, original) .addLogging() .addMetrics() but it must be easy to use like…
  • 15. Why a Proxy ? 7 @SvenRuppert final InnerDemoClass original = new InnerDemoClass(); final InnerDemoInterface demoLogic = ProxyBuilder.createBuilder(InnerDemoInterface.class, original) .addLogging() .addMetrics() .addSecurityRule(() -> true) but it must be easy to use like…
  • 16. Why a Proxy ? 7 @SvenRuppert final InnerDemoClass original = new InnerDemoClass(); final InnerDemoInterface demoLogic = ProxyBuilder.createBuilder(InnerDemoInterface.class, original) .addLogging() .addMetrics() .addSecurityRule(() -> true) .addSecurityRule(() -> true) but it must be easy to use like…
  • 17. Why a Proxy ? 7 @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…
  • 18. Why a Proxy ? 8 @SvenRuppert but it must be easy to use like…
  • 19. Why a Proxy ? 8 @SvenRuppert @Inject @Proxy(virtual = true, metrics = true) Service service; but it must be easy to use like…
  • 20. Adapter v Proxy - Pattern Hello World 9 @SvenRuppert Difference between Proxy and Adapter
  • 21. 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. 10 @SvenRuppert
  • 22. Adapter v Proxy - Pattern Hello World 11 @SvenRuppert
  • 23. Adapter v Proxy - Pattern Hello World public class LegacyWorker {
 public void writeTheStrings(String[] strArray){
 Arrays.stream(strArray).forEach(System.out::println);
 }
 } 11 @SvenRuppert
  • 24. Adapter v Proxy - Pattern Hello World public class LegacyWorker {
 public void writeTheStrings(String[] strArray){
 Arrays.stream(strArray).forEach(System.out::println);
 }
 } 11 public interface WorkerAdapter {
 public void workOnSomething(List<String> stringListe);
 } @SvenRuppert
  • 25. Adapter v Proxy - Pattern Hello World public class LegacyWorker {
 public void writeTheStrings(String[] strArray){
 Arrays.stream(strArray).forEach(System.out::println);
 }
 } 11 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
  • 26. Adapter v Proxy - Pattern Hello World public class LegacyWorker {
 public void writeTheStrings(String[] strArray){
 Arrays.stream(strArray).forEach(System.out::println);
 }
 } 11 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
  • 27. Adapter v Proxy - Pattern Hello World public class LegacyWorker {
 public void writeTheStrings(String[] strArray){
 Arrays.stream(strArray).forEach(System.out::println);
 }
 } 11 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
  • 28. Adapter v Proxy - Pattern Hello World public class LegacyWorker {
 public void writeTheStrings(String[] strArray){
 Arrays.stream(strArray).forEach(System.out::println);
 }
 } 11 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
  • 29. Adapter v Proxy - Pattern Hello World public class LegacyWorker {
 public void writeTheStrings(String[] strArray){
 Arrays.stream(strArray).forEach(System.out::println);
 }
 } 11 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
  • 30. Adapter v Proxy - Pattern Hello World public 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);
 }
 } 12 @SvenRuppert
  • 31. Adapter v Proxy - Pattern Hello World public 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);
 }
 } 12 @SvenRuppert
  • 32. Adapter v Proxy - Pattern Hello World public 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);
 }
 } 12 @SvenRuppert
  • 33. Adapter v Proxy - Pattern Hello World public 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);
 }
 } 12 • No need to know the LegacyWorker @SvenRuppert
  • 34. Adapter v Proxy - Pattern Hello World public 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);
 }
 } 12 • No need to know the LegacyWorker • No inheritance between LegacyWorker and Adapter @SvenRuppert
  • 35. Adapter v Proxy - Pattern Hello World public 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);
 }
 } 12 • No need to know the LegacyWorker • No inheritance between LegacyWorker and Adapter • only a transformation of an interface @SvenRuppert
  • 36. Adapter v Proxy - Pattern Hello World public 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);
 }
 } 12 • 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
  • 37. Proxy - the easiest version 13 @SvenRuppert We need a few steps to come from an Adapter with Delegator to a Proxy
  • 38. Proxy - the easiest version 13 • We need to know the LegacyWorker @SvenRuppert We need a few steps to come from an Adapter with Delegator to a Proxy
  • 39. Proxy - the easiest version 13 • We need to know the LegacyWorker • Inheritance between LegacyWorker and Adapter @SvenRuppert We need a few steps to come from an Adapter with Delegator to a Proxy
  • 40. Proxy - the easiest version 13 • 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
  • 41. Proxy - the easiest version 13 • 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
  • 42. Proxy - the easiest version - (Delegator) 14 @SvenRuppert
  • 43. Proxy - the easiest version - (Delegator) public interface Service {
 String work(String txt);
 } 14 @SvenRuppert
  • 44. Proxy - the easiest version - (Delegator) public interface Service {
 String work(String txt);
 } 14 @SvenRuppert public class ServiceImpl implements Service {
 public String work(String txt) {
 return "ServiceImpl - " + txt;
 }
 }
  • 45. Proxy - the easiest version - (Delegator) public interface Service {
 String work(String txt);
 } 14 @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); }
 }
  • 47. Security Proxy 15 @SvenRuppert public class ServiceProxy implements Service {
 private Service service = new ServiceImpl();
 public String work(String txt) { return service.work(txt); }
 }
  • 48. Security Proxy 15 @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 ?
  • 49. Security Proxy 15 @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
  • 50. Security Proxy 15 @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"; }
 }
 }
  • 51. Security Proxy 15 @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"; }
 }
 }
  • 52. Remote Proxy - JDK only 16 @SvenRuppert
  • 53. Remote Proxy - JDK only 16 @SvenRuppert public class ServiceProxy implements Service {
 private Service service = new ServiceImpl();
 public String work(String txt) { return service.work(txt); }
 }
  • 54. Remote Proxy - JDK only 16 @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 ?
  • 55. Remote Proxy - JDK only 16 @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
  • 56. Remote Proxy - JDK only 16 @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");
  • 57. Remote Proxy - JDK only 16 @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");
  • 58. Remote Proxy - JDK only 16 @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
  • 59. Remote Proxy - JDK only 17 @SvenRuppert
  • 60. Remote Proxy - JDK only 17 @SvenRuppert
  • 61. Remote Proxy - JDK only 17 @SvenRuppert Interface
  • 62. Remote Proxy - JDK only 17 @SvenRuppert Proxy Interface
  • 63. Remote Proxy - JDK only 17 @SvenRuppert Proxy Interface remote communication
  • 64. Remote Proxy - JDK only 17 @SvenRuppert Proxy Interface remote communication
  • 65. Remote Proxy - JDK only 17 @SvenRuppert Proxy Interface remote communication
  • 66. Remote Proxy - JDK only 17 @SvenRuppert Proxy Interface remote communication
  • 67. Remote Proxy - JDK only 17 @SvenRuppert Proxy Interface remote communication
  • 68. Remote Proxy - JDK only 17 @SvenRuppert Proxy Interface Interface remote communication
  • 69. Remote Proxy - JDK only 17 @SvenRuppert Proxy Remote Service Interface Interface remote communication
  • 70. Remote Proxy - JDK only 17 @SvenRuppert Proxy Remote Service Interface Interface remote communication
  • 71. Remote Proxy - JDK only 17 @SvenRuppert Proxy Remote Service Interface Interface remote communication client
  • 72. Remote Proxy - JDK only 17 @SvenRuppert Proxy Remote Service Interface Interface remote communication client server
  • 73. Remote Proxy - JDK only 17 @SvenRuppert Proxy Remote Service Interface Interface remote communication client server
  • 74. Remote Proxy - JDK only 17 @SvenRuppert Proxy Remote Service Interface Interface remote communication client server
  • 75. Remote Proxy - JDK only 18 @SvenRuppert @WebService
 @SOAPBinding(style = SOAPBinding.Style.RPC)
 public interface Service {
 @WebMethod
 public String work(String txt);
 }
  • 76. Remote Proxy - JDK only 19 @SvenRuppert Proxy Remote Service Interface Interface remote communication client server
  • 77. Remote Proxy - JDK only 19 @SvenRuppert Proxy Remote Service Interface Interface remote communication client server
  • 78. Remote Proxy - JDK only 20 @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;
 }
 }
  • 79. Remote Proxy - JDK only 21 @SvenRuppert Proxy Remote Service Interface Interface remote communication client server
  • 80. Remote Proxy - JDK only 21 @SvenRuppert Proxy Remote Service Interface Interface remote communication client server
  • 81. Remote Proxy - JDK only 22 @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());
  • 82. Remote Proxy - JDK only 22 @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());
  • 83. Remote Proxy - JDK only 23 @SvenRuppert Proxy Remote Service Interface Interface remote communication client server
  • 84. Remote Proxy - JDK only 23 @SvenRuppert Proxy Remote Service Interface Interface remote communication client server
  • 85. Remote Proxy - JDK only 24 @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);
 }
 }
  • 86. Remote Proxy - JDK only 24 @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);
 }
 }
  • 87. Remote Proxy - JDK only 24 @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);
 }
 }
  • 88. Remote Proxy - JDK only 25 @SvenRuppert Proxy Remote Service Interface Interface remote communication client server
  • 89. Remote Proxy - JDK only 25 @SvenRuppert Proxy Remote Service Interface Interface remote communication client server • remote communication
  • 90. Remote Proxy - JDK only 25 @SvenRuppert Proxy Remote Service Interface Interface remote communication client server • remote communication • most of this is technology based work
  • 91. Remote Proxy - JDK only 25 @SvenRuppert Proxy Remote Service Interface Interface remote communication client server • remote communication • most of this is technology based work • goal: developer will see no remote communication
  • 93. Virtual Proxy 26 @SvenRuppert public class ServiceProxy implements Service {
 private Service service = new ServiceImpl();
 public String work(String txt) { return service.work(txt); }
 }
  • 94. Virtual Proxy 26 @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 ?
  • 95. Virtual Proxy 26 @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
  • 96. Virtual Proxy 26 @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);
 }
 }
  • 97. Virtual Proxy 26 @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);
 }
 }
  • 98. Virtual Proxy 26 @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);
 }
 }
  • 99. Virtual Proxy 27 @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);
 }
 }
  • 100. Virtual Proxy 27 @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);
 }
 }
  • 101. Virtual Proxy 27 @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 ThreadSafe
  • 102. Virtual Proxy 27 @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 ThreadSafe
  • 103. Virtual Proxy 27 @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 ThreadSafe fixed decision for an implementation
  • 104. Virtual Proxy 27 @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 ThreadSafe fixed decision for an implementation
  • 105. Virtual Proxy 27 @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 ThreadSafe fixed decision for an implementation how to combine it with a FactoryPattern ?
  • 106. Virtual Proxy 28 @SvenRuppert if(service == null) { service = new ServiceImpl(); }

  • 107. Virtual Proxy 28 @SvenRuppert if(service == null) { service = new ServiceImpl(); }

  • 108. Virtual Proxy 28 @SvenRuppert if(service == null) { service = new ServiceImpl(); }
 public interface ServiceFactory {
 Service createInstance();
 }
  • 109. Virtual Proxy 28 @SvenRuppert if(service == null) { service = new ServiceImpl(); }
 public interface ServiceFactory {
 Service createInstance();
 }
  • 110. Virtual Proxy 28 @SvenRuppert if(service == null) { service = new ServiceImpl(); }
 public interface ServiceFactory {
 Service createInstance();
 } public interface ServiceStrategyFactory {
 Service realSubject(ServiceFactory factory);
 }
  • 111. Virtual Proxy - Not - ThreadSafe 29 @SvenRuppert if(service == null) { service = new ServiceImpl(); }

  • 112. Virtual Proxy - Not - ThreadSafe 29 @SvenRuppert if(service == null) { service = new ServiceImpl(); }

  • 113. Virtual Proxy - Not - ThreadSafe 29 @SvenRuppert if(service == null) { service = new ServiceImpl(); }
 private ServiceFactory serviceFactory = ServiceImpl::new;
  • 114. Virtual Proxy - Not - ThreadSafe 29 @SvenRuppert if(service == null) { service = new ServiceImpl(); }
 private ServiceFactory serviceFactory = ServiceImpl::new;
  • 115. Virtual Proxy - Not - ThreadSafe 29 @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;
  • 116. Virtual Proxy - Not - ThreadSafe 30 @SvenRuppert if(service == null) { service = new ServiceImpl(); }

  • 117. Virtual Proxy - Not - ThreadSafe 30 @SvenRuppert if(service == null) { service = new ServiceImpl(); }
 public class ServiceProxy implements Service {
  • 118. Virtual Proxy - Not - ThreadSafe 30 @SvenRuppert if(service == null) { service = new ServiceImpl(); }
 public class ServiceProxy implements Service { private ServiceFactory serviceFactory = ServiceImpl::new;
  • 119. Virtual Proxy - Not - ThreadSafe 30 @SvenRuppert if(service == null) { service = new ServiceImpl(); }
 public class ServiceProxy implements Service { private ServiceFactory serviceFactory = ServiceImpl::new; private ServiceStrategyFactory strategyFactory = new ServiceStrategyFactoryImpl();
  • 120. Virtual Proxy - Not - ThreadSafe 30 @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) {
  • 121. Virtual Proxy - Not - ThreadSafe 30 @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) { }
 }
  • 122. Virtual Proxy - Not - ThreadSafe 30 @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 }
 }
  • 123. Virtual Proxy - Not - ThreadSafe 30 @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 }
 }
  • 124. Virtual Proxy - Not - ThreadSafe 30 @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( }
 }
  • 125. Virtual Proxy - Not - ThreadSafe 30 @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 }
 }
  • 126. Virtual Proxy - Not - ThreadSafe 30 @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); }
 }
  • 127. Virtual Proxy - Synchronized 31 @SvenRuppert if(service == null) { service = new ServiceImpl(); }

  • 128. Virtual Proxy - Synchronized 31 @SvenRuppert if(service == null) { service = new ServiceImpl(); }

  • 129. Virtual Proxy - Synchronized 31 @SvenRuppert if(service == null) { service = new ServiceImpl(); }
 private ServiceFactory serviceFactory = ServiceImpl::new;
  • 130. Virtual Proxy - Synchronized 31 @SvenRuppert if(service == null) { service = new ServiceImpl(); }
 private ServiceFactory serviceFactory = ServiceImpl::new;
  • 131. Virtual Proxy - Synchronized 31 @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;
  • 132. Virtual Proxy - Synchronized 31 @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 ThreadSafe
  • 133. Virtual Proxy - Method Scoped 32 @SvenRuppert if(service == null) { service = new ServiceImpl(); }

  • 134. Virtual Proxy - Method Scoped 32 @SvenRuppert if(service == null) { service = new ServiceImpl(); }

  • 135. Virtual Proxy - Method Scoped 32 @SvenRuppert if(service == null) { service = new ServiceImpl(); }
 private ServiceFactory serviceFactory = ServiceImpl::new;
  • 136. Virtual Proxy - Method Scoped 32 @SvenRuppert if(service == null) { service = new ServiceImpl(); }
 private ServiceFactory serviceFactory = ServiceImpl::new;
  • 137. Virtual Proxy - Method Scoped 32 @SvenRuppert if(service == null) { service = new ServiceImpl(); }
 public class ServiceStrategyFactoryMethodScoped implements ServiceStrategyFactory {
 public Service realSubject(final ServiceFactory factory) { 
 return factory.createInstance();
 }
 } private ServiceFactory serviceFactory = ServiceImpl::new;
  • 138. Virtual Proxy - Method Scoped 32 @SvenRuppert if(service == null) { service = new ServiceImpl(); }
 public class ServiceStrategyFactoryMethodScoped implements ServiceStrategyFactory {
 public Service realSubject(final ServiceFactory factory) { 
 return factory.createInstance();
 }
 } private ServiceFactory serviceFactory = ServiceImpl::new;
  • 139. Combining Proxies 33 @SvenRuppert Security Proxy Virtual ProxyRemote Proxy Security ProxyVirtual ProxyRemote Proxy Security ProxyVirtual Proxy Remote Proxy VirtualProxies are mostly the last one combining Proxies is easy SecurityProxies are mostly the first one ?
  • 140. Combining Proxies 33 @SvenRuppert Security Proxy Virtual ProxyRemote Proxy Security ProxyVirtual ProxyRemote Proxy Security ProxyVirtual Proxy Remote Proxy VirtualProxies are mostly the last one combining Proxies is easy SecurityProxies are mostly the first one ?
  • 141. Combining Proxies 33 @SvenRuppert Security Proxy Virtual ProxyRemote Proxy Security ProxyVirtual ProxyRemote Proxy Security ProxyVirtual Proxy Remote Proxy VirtualProxies are mostly the last one combining Proxies is easy SecurityProxies are mostly the first one ?
  • 142. Combining Proxies 33 @SvenRuppert Security Proxy Virtual ProxyRemote Proxy Security ProxyVirtual ProxyRemote Proxy Security ProxyVirtual Proxy Remote Proxy VirtualProxies are mostly the last one combining Proxies is easy SecurityProxies are mostly the first one ?
  • 143. Combining Proxies 33 @SvenRuppert Security Proxy Virtual ProxyRemote Proxy Security ProxyVirtual ProxyRemote Proxy Security ProxyVirtual Proxy Remote Proxy VirtualProxies are mostly the last one combining Proxies is easy SecurityProxies are mostly the first one ?
  • 144. Combining Proxies - SecureVirtualProxy 34 @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"; }
 }
 }
  • 145. Combining Proxies - SecureVirtualProxy 34 @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"; }
 }
 }
  • 146. Combining Proxies - SecureVirtualProxy 34 @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"; }
 }
 }
  • 147. Combining Proxies - SecureVirtualProxy 34 @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"; }
 }
 }
  • 148. Combining Proxies - SecureVirtualProxy 34 @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"; }
 }
 }
  • 149. Combining Proxies - SecureVirtualProxy 34 @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
  • 150. Combining Proxies - SecureVirtualProxy 34 @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 ?
  • 151. Combining Proxies - SecureVirtualProxy 35 @SvenRuppert Security Proxy Virtual Proxy hard wired proxies What could we change now ? we need a Generic Proxy
  • 152. Combining Proxies - SecureVirtualProxy 35 @SvenRuppert Security Proxy Virtual Proxy hard wired proxies What could we change now ? we need a Generic Proxy since JDK1.3 we have it
  • 153. Combining Proxies - SecureVirtualProxy 35 @SvenRuppert Security Proxy Virtual Proxy hard wired proxies What could we change now ? we need a Generic Proxy since JDK1.3 we have it the DynamicProxy
  • 154. prepare for….. Proxy Deep Dive - DynamicProxies some words about : how to use and how to extend….but.. also what is not nice 36 @SvenRuppert
  • 157. Dynamic Proxy - Hello World 38 @SvenRuppert How to use it ?
  • 158. Dynamic Proxy - Hello World 38 @SvenRuppert How to use it ? java.lang.reflect.Proxy
  • 159. Dynamic Proxy - Hello World 38 @SvenRuppert How to use it ? java.lang.reflect.Proxy we need an interface : here Service
  • 160. Dynamic Proxy - Hello World 38 @SvenRuppert How to use it ? java.lang.reflect.Proxy we need an interface : here Service we need an implementation : here ServiceImpl
  • 161. Dynamic Proxy - Hello World 38 @SvenRuppert How to use it ? java.lang.reflect.Proxy we need an interface : here Service we 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);
 }
 }
 )
 );
  • 162. Dynamic Proxy - Hello World 38 @SvenRuppert How to use it ? java.lang.reflect.Proxy we need an interface : here Service we 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
  • 163. Dynamic Proxy - Hello World 39 @SvenRuppert
  • 164. Dynamic Proxy - Hello World 39 @SvenRuppert Service proxyInstance = Service.class.cast (
  • 165. Dynamic Proxy - Hello World 39 @SvenRuppert Proxy.newProxyInstance ( Service proxyInstance = Service.class.cast (
  • 166. Dynamic Proxy - Hello World 39 @SvenRuppert Proxy.newProxyInstance ( Service.class.getClassLoader(), Service proxyInstance = Service.class.cast (
  • 167. Dynamic Proxy - Hello World 39 @SvenRuppert Proxy.newProxyInstance ( Service.class.getClassLoader(), new Class<?>[]{Service.class}, Service proxyInstance = Service.class.cast (
  • 168. Dynamic Proxy - Hello World 39 @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);
 }
 }
  • 169. Dynamic Proxy - Hello World 39 @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);
 }
 } )
 );
  • 170. Dynamic Proxy - Hello World 39 @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 ?
  • 171. Dynamic Virtual Proxy 40 @SvenRuppert Proxy.newProxyInstance ( Service.class.getClassLoader(), new Class<?>[]{Service.class}, Service proxyInstance = Service.class.cast ( )
 );
  • 172. Dynamic Virtual Proxy 40 @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);
 }
 } )
 );
  • 173. Dynamic Virtual Proxy 40 @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);
 }
 } )
 );
  • 174. Dynamic Virtual Proxy 40 @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);
 }
 } )
 );
  • 175. Dynamic Proxy - make it generic 41 @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);
 }
 }
 )
 );
  • 176. Dynamic Proxy - make it generic 41 @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);
 }
 }
 )
 );
  • 177. Dynamic Proxy - make it generic 41 @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);
 }
 }
 )
 );
  • 178. Dynamic Proxy - make it generic 41 @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);
 }
 }
 )
 );
  • 179. Dynamic Proxy - make it generic 41 @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
  • 180. Dynamic Proxy - make it generic 41 @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
  • 181. Dynamic Proxy - make it generic 41 @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
  • 182. Dynamic Proxy - make it generic 41 @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
  • 183. Dynamic Proxy - make it generic 41 @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
  • 184. Dynamic Proxy - make it generic 41 @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
  • 185. Dynamic Proxy - make it generic 42 @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);
 }
 }
  • 186. Dynamic Proxy - make it generic 43 @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);
 }
 }
  • 187. Dynamic Proxy - make it generic 44 @SvenRuppert with DynamicProxies - we are writing less (more generic) code - we can create Virtual-/Remote-/Security Proxies
  • 188. Dynamic Proxy - make it generic 44 @SvenRuppert with DynamicProxies - we are writing less (more generic) code - we can create Virtual-/Remote-/Security Proxies but how to combine Proxies more generic ?
  • 189. Dynamic Proxy - make it generic 45 @SvenRuppert but how to combine Proxies more generic ? for this we have to switch from
  • 190. Dynamic Proxy - make it generic 45 @SvenRuppert but how to combine Proxies more generic ? for this we have to switch from Factory-Method-Pattern
  • 191. Dynamic Proxy - make it generic 45 @SvenRuppert but how to combine Proxies more generic ? for this we have to switch from Factory-Method-Pattern
  • 192. Dynamic Proxy - make it generic 45 @SvenRuppert but how to combine Proxies more generic ? for this we have to switch from Factory-Method-Pattern Builder-Pattern
  • 193. DynamicProxyBuilder 46 @SvenRuppert but how to combine Proxies more generic ? Security Proxy Virtual ProxySecurity Proxy let´s think about Two possible ways:
  • 194. DynamicProxyBuilder 46 @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
  • 195. DynamicProxyBuilder 46 @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
  • 196. DynamicProxyBuilder 46 @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
  • 197. DynamicProxyBuilder 47 @SvenRuppert OK, we need a generic CascadedProxy Proxy n Proxy n-1 Proxy n-2 Proxy n-3 a child must know his parent first we only add different DynamicProxies always the same target interface
  • 198. DynamicProxyBuilder 47 @SvenRuppert OK, we need a generic CascadedProxy Proxy n Proxy n-1 Proxy n-2 Proxy n-3 a child must know his parent first we only add different DynamicProxies always the same target interface
  • 200. DynamicProxyBuilder 48 @SvenRuppert for example: add n SecurityRules public interface SecurityRule {
 boolean checkRule();
 }
  • 201. DynamicProxyBuilder 48 @SvenRuppert for example: add n SecurityRules public interface SecurityRule {
 boolean checkRule();
 }
  • 202. DynamicProxyBuilder 48 @SvenRuppert for example: add n SecurityRules public interface SecurityRule {
 boolean checkRule();
 } functional interface
  • 203. DynamicProxyBuilder 48 @SvenRuppert private List<SecurityRule> securityRules = new ArrayList<>(); for example: add n SecurityRules public interface SecurityRule {
 boolean checkRule();
 } functional interface
  • 204. DynamicProxyBuilder 48 @SvenRuppert private List<SecurityRule> securityRules = new ArrayList<>(); for example: add n SecurityRules public interface SecurityRule {
 boolean checkRule();
 } functional interface Collections.reverse(securityRules);
 securityRules.forEach(this::build_addSecurityRule);
  • 205. DynamicProxyBuilder 49 @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;
 } Collections.reverse(securityRules);
 securityRules.forEach(this::build_addSecurityRule);
  • 206. DynamicProxyBuilder 49 @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;
 } Collections.reverse(securityRules);
 securityRules.forEach(this::build_addSecurityRule);
  • 207. DynamicProxyBuilder 49 @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;
 } last child Collections.reverse(securityRules);
 securityRules.forEach(this::build_addSecurityRule);
  • 208. DynamicProxyBuilder 49 @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;
 } last child Collections.reverse(securityRules);
 securityRules.forEach(this::build_addSecurityRule);
  • 209. DynamicProxyBuilder 49 @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;
 } last child work on child Collections.reverse(securityRules);
 securityRules.forEach(this::build_addSecurityRule);
  • 210. DynamicProxyBuilder 49 @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;
 } last child work on child Collections.reverse(securityRules);
 securityRules.forEach(this::build_addSecurityRule);
  • 211. DynamicProxyBuilder 49 @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;
 } last child work on child set child for next level Collections.reverse(securityRules);
 securityRules.forEach(this::build_addSecurityRule);
  • 212. DynamicProxyBuilder 49 @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 Collections.reverse(securityRules);
 securityRules.forEach(this::build_addSecurityRule);
  • 215. DynamicProxyBuilder 50 @SvenRuppert final InnerDemoClass original = new InnerDemoClass(); final InnerDemoInterface demoLogic =
  • 216. DynamicProxyBuilder 50 @SvenRuppert final InnerDemoClass original = new InnerDemoClass(); final InnerDemoInterface demoLogic = ProxyBuilder.createBuilder(InnerDemoInterface.class, original)
  • 217. DynamicProxyBuilder 50 @SvenRuppert final InnerDemoClass original = new InnerDemoClass(); final InnerDemoInterface demoLogic = ProxyBuilder.createBuilder(InnerDemoInterface.class, original) .addLogging()
  • 218. DynamicProxyBuilder 50 @SvenRuppert final InnerDemoClass original = new InnerDemoClass(); final InnerDemoInterface demoLogic = ProxyBuilder.createBuilder(InnerDemoInterface.class, original) .addLogging() .addMetrics()
  • 219. DynamicProxyBuilder 50 @SvenRuppert final InnerDemoClass original = new InnerDemoClass(); final InnerDemoInterface demoLogic = ProxyBuilder.createBuilder(InnerDemoInterface.class, original) .addLogging() .addMetrics() .addSecurityRule(() -> true)
  • 220. DynamicProxyBuilder 50 @SvenRuppert final InnerDemoClass original = new InnerDemoClass(); final InnerDemoInterface demoLogic = ProxyBuilder.createBuilder(InnerDemoInterface.class, original) .addLogging() .addMetrics() .addSecurityRule(() -> true) .addSecurityRule(() -> true)
  • 221. DynamicProxyBuilder 50 @SvenRuppert final InnerDemoClass original = new InnerDemoClass(); final InnerDemoInterface demoLogic = ProxyBuilder.createBuilder(InnerDemoInterface.class, original) .addLogging() .addMetrics() .addSecurityRule(() -> true) .addSecurityRule(() -> true) .build();
  • 223. DynamicProxyBuilder 51 @SvenRuppert Until now, we had only a cascade of one interface
  • 224. DynamicProxyBuilder 51 @SvenRuppert Until now, we had only a cascade of one interface how to deal with different interfaces ?
  • 225. DynamicProxyBuilder 51 @SvenRuppert Until now, we had only a cascade of one interface how to deal with different interfaces ?
  • 226. DynamicProxyBuilder 51 @SvenRuppert Until now, we had only a cascade of one interface how to deal with different interfaces ? we need a generic NestedBuilder
  • 227. NestedBuilder - The Beginning 52 @SvenRuppert
  • 228. NestedBuilder - The Beginning 53 @SvenRuppert
  • 229. NestedBuilder - The Beginning 53 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build();
  • 230. NestedBuilder - The Beginning 53 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build();
  • 231. NestedBuilder - The Beginning 53 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
  • 232. NestedBuilder - The Beginning 53 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
  • 233. NestedBuilder - The Beginning 53 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); List<Wheel> wheels = new ArrayList<>();
 wheels.add(wheel1);
 wheels.add(wheel2);
 wheels.add(wheel3);
  • 234. NestedBuilder - The Beginning 53 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); List<Wheel> wheels = new ArrayList<>();
 wheels.add(wheel1);
 wheels.add(wheel2);
 wheels.add(wheel3); }
  • 235. NestedBuilder - The Beginning 53 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); List<Wheel> wheels = new ArrayList<>();
 wheels.add(wheel1);
 wheels.add(wheel2);
 wheels.add(wheel3); }
  • 236. NestedBuilder - The Beginning 53 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 
 Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
 Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); List<Wheel> wheels = new ArrayList<>();
 wheels.add(wheel1);
 wheels.add(wheel2);
 wheels.add(wheel3); }
  • 237. NestedBuilder - The Beginning 54 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 
 Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
 Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); List<Wheel> wheels = new ArrayList<>();
 wheels.add(wheel1);
 wheels.add(wheel2);
 wheels.add(wheel3);
  • 238. NestedBuilder - The Beginning 55 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 
 Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
 Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); List<Wheel> wheels = new ArrayList<>();
 wheels.add(wheel1);
 wheels.add(wheel2);
 wheels.add(wheel3);
  • 239. NestedBuilder - The Beginning 55 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 
 Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
 Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
  • 240. NestedBuilder - The Beginning 55 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 
 Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
 Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); //List<Wheel> wheels = new ArrayList<>();
 // wheels.add(wheel1);
 // wheels.add(wheel2);
 // wheels.add(wheel3);
  • 241. NestedBuilder - The Beginning 55 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 
 Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
 Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); //List<Wheel> wheels = new ArrayList<>();
 // wheels.add(wheel1);
 // wheels.add(wheel2);
 // wheels.add(wheel3); List<Wheel> wheelList = WheelListBuilder.newBuilder()
 .withNewList()
 .addWheel(wheel1)
 .addWheel(wheel2)
 .addWheel(wheel3)
 .build();
  • 242. NestedBuilder - The Beginning 55 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 
 Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
 Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); //List<Wheel> wheels = new ArrayList<>();
 // wheels.add(wheel1);
 // wheels.add(wheel2);
 // wheels.add(wheel3); List<Wheel> wheelList = WheelListBuilder.newBuilder()
 .withNewList()
 .addWheel(wheel1)
 .addWheel(wheel2)
 .addWheel(wheel3)
 .build(); //more robust if you add tests at build()
  • 243. NestedBuilder - The Beginning 55 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 
 Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
 Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); //List<Wheel> wheels = new ArrayList<>();
 // wheels.add(wheel1);
 // wheels.add(wheel2);
 // wheels.add(wheel3); List<Wheel> wheelList = WheelListBuilder.newBuilder()
 .withNewList()
 .addWheel(wheel1)
 .addWheel(wheel2)
 .addWheel(wheel3)
 .build(); //more robust if you add tests at build() } }
  • 244. NestedBuilder - The Beginning 55 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 
 Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
 Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); //List<Wheel> wheels = new ArrayList<>();
 // wheels.add(wheel1);
 // wheels.add(wheel2);
 // wheels.add(wheel3); List<Wheel> wheelList = WheelListBuilder.newBuilder()
 .withNewList()
 .addWheel(wheel1)
 .addWheel(wheel2)
 .addWheel(wheel3)
 .build(); //more robust if you add tests at build() } } how to combine ?
  • 245. NestedBuilder - The Beginning 56 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 
 Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
 Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); List<Wheel> wheelList = WheelListBuilder.newBuilder()
 .withNewList()
 .addWheel(wheel1)
 .addWheel(wheel2)
 .addWheel(wheel3)
 .build(); } } how to combine ?
  • 246. NestedBuilder - The Beginning 57 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); // Wheel wheel1 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); 
 // Wheel wheel2 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build();
 // Wheel wheel3 = Wheel.newBuilder().withType(2).withColour(3).withSize(4).build(); // List<Wheel> wheelList = WheelListBuilder.newBuilder()
 .withNewList()
 .addWheel(wheel1)
 .addWheel(wheel2)
 .addWheel(wheel3)
 .build();
  • 247. NestedBuilder - The Beginning 57 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); // List<Wheel> wheelList = WheelListBuilder.newBuilder()
 .withNewList()
 .addWheel(wheel1)
 .addWheel(wheel2)
 .addWheel(wheel3)
 .build();
  • 248. NestedBuilder - The Beginning 57 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build();
  • 249. NestedBuilder - The Beginning 57 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); List<Wheel> wheels = wheelListBuilder
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .build();
  • 250. NestedBuilder - The Beginning 58 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); List<Wheel> wheels = wheelListBuilder
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .build();
  • 251. NestedBuilder - The Beginning 58 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); List<Wheel> wheels = wheelListBuilder
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .build();
  • 252. NestedBuilder - The Beginning 58 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); List<Wheel> wheels = wheelListBuilder
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .build(); WheelBuilder
  • 253. NestedBuilder - The Beginning 58 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); List<Wheel> wheels = wheelListBuilder
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .build(); WheelBuilder
  • 254. NestedBuilder - The Beginning 58 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); List<Wheel> wheels = wheelListBuilder
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .build(); WheelBuilder WheelListBuilder
  • 255. NestedBuilder - The Beginning 59 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); List<Wheel> wheels = wheelListBuilder
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .build();
  • 256. NestedBuilder - The Beginning 59 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); Engine engine = Engine.newBuilder().withPower(100).withType(5).build(); List<Wheel> wheels = wheelListBuilder
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .build(); now we have to combine all
  • 257. NestedBuilder - The Beginning 59 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); List<Wheel> wheels = wheelListBuilder
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .build(); now we have to combine all
  • 258. NestedBuilder - The Beginning 59 @SvenRuppert Car car = Car.newBuilder()
 .withEngine(engine)
 .withWheelList(wheels)
 .build(); now we have to combine all
  • 259. NestedBuilder - The Beginning 59 @SvenRuppert now we have to combine all
  • 260. NestedBuilder - The Beginning 59 @SvenRuppert now we have to combine all
  • 261. NestedBuilder - The Beginning 59 @SvenRuppert now we have to combine all Car car = Car.newBuilder()
 .addEngine().withPower(100).withType(5).done()
 .addWheels()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .done()
 .build();
  • 262. NestedBuilder - The Beginning 59 @SvenRuppert now we have to combine all Car car = Car.newBuilder()
 .addEngine().withPower(100).withType(5).done()
 .addWheels()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .addWheel().withType(1).withSize(2).withColour(2).addWheelToList()
 .done()
 .build();
  • 263. NestedBuilder - The Pattern 60 @SvenRuppert public abstract class NestedBuilder<T, V> { protected T parent; public abstract V build() public <P extends NestedBuilder<T, V>> P 
 withParentBuilder(T parent) {
 this.parent = parent;
 return (P) this;
 }
  • 264. NestedBuilder - The Pattern 60 @SvenRuppert public abstract class NestedBuilder<T, V> { protected T parent; public abstract V build() public <P extends NestedBuilder<T, V>> P 
 withParentBuilder(T parent) {
 this.parent = parent;
 return (P) this;
 }
  • 265. NestedBuilder - The Pattern 60 @SvenRuppert public abstract class NestedBuilder<T, V> { protected T parent; public abstract V build() public <P extends NestedBuilder<T, V>> P 
 withParentBuilder(T parent) {
 this.parent = parent;
 return (P) this;
 } parent will connect itself…
  • 266. NestedBuilder - The Pattern 61 @SvenRuppert
  • 267. NestedBuilder - The Pattern 61 @SvenRuppert public abstract class NestedBuilder<T, V> {
  • 268. NestedBuilder - The Pattern 61 @SvenRuppert public abstract class NestedBuilder<T, V> { public T done() {
  • 269. NestedBuilder - The Pattern 61 @SvenRuppert public abstract class NestedBuilder<T, V> { public T done() { Class<?> parentClass = parent.getClass();
  • 270. NestedBuilder - The Pattern 61 @SvenRuppert public abstract class NestedBuilder<T, V> { public T done() { Class<?> parentClass = parent.getClass(); try {
 V build = this.build();
 String methodname = "with" + build.getClass().getSimpleName();
 Method method = parentClass.getDeclaredMethod(
 methodname, build.getClass());
 method.invoke(parent, build);
 } catch (NoSuchMethodException 
 | IllegalAccessException | InvocationTargetException e) {
 e.printStackTrace();
 }
  • 271. NestedBuilder - The Pattern 61 @SvenRuppert public abstract class NestedBuilder<T, V> { public T done() { Class<?> parentClass = parent.getClass(); try {
 V build = this.build();
 String methodname = "with" + build.getClass().getSimpleName();
 Method method = parentClass.getDeclaredMethod(
 methodname, build.getClass());
 method.invoke(parent, build);
 } catch (NoSuchMethodException 
 | IllegalAccessException | InvocationTargetException e) {
 e.printStackTrace();
 } }
  • 272. NestedBuilder - The Pattern 61 @SvenRuppert public abstract class NestedBuilder<T, V> { public T done() { Class<?> parentClass = parent.getClass(); try {
 V build = this.build();
 String methodname = "with" + build.getClass().getSimpleName();
 Method method = parentClass.getDeclaredMethod(
 methodname, build.getClass());
 method.invoke(parent, build);
 } catch (NoSuchMethodException 
 | IllegalAccessException | InvocationTargetException e) {
 e.printStackTrace();
 } }
  • 273. NestedBuilder - The Pattern 61 @SvenRuppert public abstract class NestedBuilder<T, V> { public T done() { Class<?> parentClass = parent.getClass(); try {
 V build = this.build();
 String methodname = "with" + build.getClass().getSimpleName();
 Method method = parentClass.getDeclaredMethod(
 methodname, build.getClass());
 method.invoke(parent, build);
 } catch (NoSuchMethodException 
 | IllegalAccessException | InvocationTargetException e) {
 e.printStackTrace();
 } } connect itself with parent
  • 274. NestedBuilder - The Pattern 62 @SvenRuppert
  • 275. NestedBuilder - The Pattern 62 @SvenRuppert the basic steps in short words
  • 276. NestedBuilder - The Pattern 62 @SvenRuppert the basic steps in short words the Parent-Builder will hold the Child-Builder
  • 277. NestedBuilder - The Pattern 62 @SvenRuppert the basic steps in short words the Parent-Builder will hold the Child-Builder the Parent-Builder will have a addChild - Method
  • 278. NestedBuilder - The Pattern 62 @SvenRuppert the basic steps in short words the Parent-Builder will hold the Child-Builder the Parent-Builder will have a addChild - Method the Child-Builder will extend the NestedBuilder
  • 279. NestedBuilder - The Pattern 62 @SvenRuppert the basic steps in short words the Parent-Builder will hold the Child-Builder the Parent-Builder will have a addChild - Method the Child-Builder will extend the NestedBuilder the rest could be generated with a 
 default Builder-Generator
  • 280. NestedBuilder - The Pattern 63 @SvenRuppert public class Parent {
 private KidA kidA;
 private KidB kidB;
 //snipp.....
 public static final class Builder {
 private KidA kidA;
 private KidB kidB;
 // to add manually
 private KidA.Builder builderKidA = KidA.newBuilder().withParentBuilder(this);
 private KidB.Builder builderKidB = KidB.newBuilder().withParentBuilder(this);
 
 public KidA.Builder addKidA() {
 return this.builderKidA;
 }
 public KidB.Builder addKidB() {
 return this.builderKidB;
 }
 //---------
  • 281. NestedBuilder - The Pattern 63 @SvenRuppert public class Parent {
 private KidA kidA;
 private KidB kidB;
 //snipp.....
 public static final class Builder {
 private KidA kidA;
 private KidB kidB;
 // to add manually
 private KidA.Builder builderKidA = KidA.newBuilder().withParentBuilder(this);
 private KidB.Builder builderKidB = KidB.newBuilder().withParentBuilder(this);
 
 public KidA.Builder addKidA() {
 return this.builderKidA;
 }
 public KidB.Builder addKidB() {
 return this.builderKidB;
 }
 //---------
  • 282. NestedBuilder - The Pattern 63 @SvenRuppert public class Parent {
 private KidA kidA;
 private KidB kidB;
 //snipp.....
 public static final class Builder {
 private KidA kidA;
 private KidB kidB;
 // to add manually
 private KidA.Builder builderKidA = KidA.newBuilder().withParentBuilder(this);
 private KidB.Builder builderKidB = KidB.newBuilder().withParentBuilder(this);
 
 public KidA.Builder addKidA() {
 return this.builderKidA;
 }
 public KidB.Builder addKidB() {
 return this.builderKidB;
 }
 //--------- connect itself with child
  • 283. NestedBuilder - The Pattern 63 @SvenRuppert public class Parent {
 private KidA kidA;
 private KidB kidB;
 //snipp.....
 public static final class Builder {
 private KidA kidA;
 private KidB kidB;
 // to add manually
 private KidA.Builder builderKidA = KidA.newBuilder().withParentBuilder(this);
 private KidB.Builder builderKidB = KidB.newBuilder().withParentBuilder(this);
 
 public KidA.Builder addKidA() {
 return this.builderKidA;
 }
 public KidB.Builder addKidB() {
 return this.builderKidB;
 }
 //--------- connect itself with child
  • 284. NestedBuilder - The Pattern 63 @SvenRuppert public class Parent {
 private KidA kidA;
 private KidB kidB;
 //snipp.....
 public static final class Builder {
 private KidA kidA;
 private KidB kidB;
 // to add manually
 private KidA.Builder builderKidA = KidA.newBuilder().withParentBuilder(this);
 private KidB.Builder builderKidB = KidB.newBuilder().withParentBuilder(this);
 
 public KidA.Builder addKidA() {
 return this.builderKidA;
 }
 public KidB.Builder addKidB() {
 return this.builderKidB;
 }
 //--------- connect itself with child switch to Child-Builder
  • 285. NestedBuilder - The Pattern 64 @SvenRuppert public static final class Builder 
 extends NestedBuilder<Parent.Builder, KidA> {
  • 286. NestedBuilder - The Pattern 64 @SvenRuppert public static final class Builder 
 extends NestedBuilder<Parent.Builder, KidA> {
  • 287. NestedBuilder - The Pattern 64 @SvenRuppert only extends on Child-Builder public static final class Builder 
 extends NestedBuilder<Parent.Builder, KidA> {
  • 288. NestedBuilder - The Pattern 65 @SvenRuppert
  • 289. NestedBuilder - The Pattern 65 @SvenRuppert Parent build = Parent.newBuilder()
 
 .addKidA().withNote("A").done()
 .addKidB().withNote("B").done()
 
 .build();
 System.out.println("build = " + build);
  • 290. NestedBuilder - The Pattern 65 @SvenRuppert Parent build = Parent.newBuilder()
 
 .addKidA().withNote("A").done()
 .addKidB().withNote("B").done()
 
 .build();
 System.out.println("build = " + build); and a child could be a parent in the same time
  • 291. NestedBuilder - The Pattern 65 @SvenRuppert Parent build = Parent.newBuilder()
 
 .addKidA().withNote("A").done()
 .addKidB().withNote("B").done()
 
 .build();
 System.out.println("build = " + build); and a child could be a parent in the same time Parent build = Parent.newBuilder()
 .addKidA().withNote("A") .addKidB().withNote("B").done() .done()
 .build(); System.out.println("build = " + build);

  • 292. NestedProxyBuilder - The Goal 66 @SvenRuppert handwritten , params for diff Proxies
  • 293. Combining Proxies 67 @SvenRuppert Security Proxy Virtual ProxyRemote Proxy Security ProxyVirtual ProxyRemote Proxy Security ProxyVirtual Proxy Remote Proxy VirtualProxies are mostly the last one combining Proxies is easy SecurityProxies are mostly the first one ?
  • 294. Combining Proxies 67 @SvenRuppert Security Proxy Virtual ProxyRemote Proxy Security ProxyVirtual ProxyRemote Proxy Security ProxyVirtual Proxy Remote Proxy VirtualProxies are mostly the last one combining Proxies is easy SecurityProxies are mostly the first one ?
  • 295. Combining Proxies 67 @SvenRuppert Security Proxy Virtual ProxyRemote Proxy Security ProxyVirtual ProxyRemote Proxy Security ProxyVirtual Proxy Remote Proxy VirtualProxies are mostly the last one combining Proxies is easy SecurityProxies are mostly the first one ?
  • 296. Combining Proxies 67 @SvenRuppert Security Proxy Virtual ProxyRemote Proxy Security ProxyVirtual ProxyRemote Proxy Security ProxyVirtual Proxy Remote Proxy VirtualProxies are mostly the last one combining Proxies is easy SecurityProxies are mostly the first one ?
  • 297. Combining Proxies 67 @SvenRuppert Security Proxy Virtual ProxyRemote Proxy Security ProxyVirtual ProxyRemote Proxy Security ProxyVirtual Proxy Remote Proxy VirtualProxies are mostly the last one combining Proxies is easy SecurityProxies are mostly the first one ?
  • 298. DynamicProxyBuilder 68 @SvenRuppert One functionality leads to one Proxy Instance runtime overhead for every Proxy - but make the first design simple.. optimize later
  • 299. DynamicObjectAdapter - orig Version 69 @SvenRuppert the original Version of the DynamicObjectAdapter was written by Dr. Heinz Kabutz
  • 300. DynamicObjectAdapter - orig Version 70 @SvenRuppert
  • 301. DynamicObjectAdapter - orig Version 70 @SvenRuppert
  • 302. DynamicObjectAdapter - orig Version 70 @SvenRuppert Proxy
  • 303. DynamicObjectAdapter - orig Version 70 @SvenRuppert Proxy orig / adapter
  • 304. DynamicObjectAdapter - orig Version 70 @SvenRuppert Proxy orig / adapter
  • 305. DynamicObjectAdapter - orig Version 70 @SvenRuppert Proxy orig / adapter invoke orig
  • 306. DynamicObjectAdapter - orig Version 70 @SvenRuppert Proxy orig / adapter invoke orig
  • 307. DynamicObjectAdapter - orig Version 70 @SvenRuppert Proxy orig / adapter invoke orig invoke adapter
  • 308. DynamicObjectAdapter - orig Version 70 @SvenRuppert Proxy orig / adapter invoke orig invoke adapter Goal: do not need to write an Adapter with Delegator
  • 309. DynamicObjectAdapter - orig Version 71 @SvenRuppert core concept: switching between method implementations
  • 310. DynamicObjectAdapter - orig Version 71 @SvenRuppert core concept: switching between method implementations how to identify a method?
  • 311. DynamicObjectAdapter - orig. Version 72 @SvenRuppert public interface Service {
 String doWork_A();
 }
 
 public static class ServiceImpl implements Service {
 public String doWork_A() {
 return ServiceImpl.class.getSimpleName();
 }
 }
  • 312. DynamicObjectAdapter - orig Version 73 @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(); }
 }
  • 313. DynamicObjectAdapter - orig Version 73 @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(); }
 }
  • 314. DynamicObjectAdapter - orig Version 73 @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(); }
 }
  • 315. DynamicObjectAdapter - orig. Version 74 @SvenRuppert
  • 316. DynamicObjectAdapter - orig. Version 74 @SvenRuppert private static class DOAInvocationHandler<T extends I, I> implements InvocationHandler {
  • 317. DynamicObjectAdapter - orig. Version 74 @SvenRuppert private static class DOAInvocationHandler<T extends I, I> implements InvocationHandler { private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();
  • 318. DynamicObjectAdapter - orig. Version 74 @SvenRuppert private static class DOAInvocationHandler<T extends I, I> implements InvocationHandler { private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>(); private T original;
  • 319. DynamicObjectAdapter - orig. Version 74 @SvenRuppert private static class DOAInvocationHandler<T extends I, I> implements InvocationHandler { private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>(); private T original; private Object adapter;
  • 320. DynamicObjectAdapter - orig. Version 74 @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) {
  • 321. DynamicObjectAdapter - orig. Version 74 @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;
  • 322. DynamicObjectAdapter - orig. Version 74 @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();
  • 323. DynamicObjectAdapter - orig. Version 74 @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();
  • 324. DynamicObjectAdapter - orig. Version 74 @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) {
  • 325. DynamicObjectAdapter - orig. Version 74 @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);
  • 326. DynamicObjectAdapter - orig. Version 74 @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);
  • 327. DynamicObjectAdapter - orig. Version 74 @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); }
 }
  • 328. DynamicObjectAdapter - orig. Version 74 @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 {
  • 329. DynamicObjectAdapter - orig. Version 74 @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
  • 330. DynamicObjectAdapter - orig. Version 74 @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
  • 331. DynamicObjectAdapter - orig. Version 75 @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) { } public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { }
 } //SNIPP
  • 332. DynamicObjectAdapter - orig. Version 75 @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) { } public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { try {
 final MethodIdentifier key = new MethodIdentifier(m); }
 } //SNIPP
  • 333. DynamicObjectAdapter - orig. Version 75 @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) { } public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { Method other = adaptedMethods.get(key); try {
 final MethodIdentifier key = new MethodIdentifier(m); }
 } //SNIPP
  • 334. DynamicObjectAdapter - orig. Version 75 @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) { } 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); } }
 } //SNIPP
  • 335. DynamicObjectAdapter - orig. Version 75 @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) { } 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
  • 336. DynamicObjectAdapter - orig. Version 75 @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
  • 337. DynamicObjectAdapter - orig. Version 75 @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 ?
  • 338. DynamicObjectAdapter - orig. Version 75 @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 ?
  • 339. DynamicObjectAdapter - orig. Version 76 @SvenRuppert private 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 ?
  • 340. DynamicObjectAdapter - orig. Version 76 @SvenRuppert private 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();
 }
  • 341. DynamicObjectAdapter - orig. Version 76 @SvenRuppert private 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() { .. }
 }
  • 342. DynamicObjectAdapter - orig. Version 76 @SvenRuppert private 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() { .. }
 }
  • 343. DynamicObjectAdapter - orig. Version 76 @SvenRuppert private 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() { .. }
 }
  • 344. DynamicObjectAdapter - orig. Version 76 @SvenRuppert private 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() { .. }
 }
  • 345. DynamicObjectAdapter - orig Version 77 @SvenRuppert Proxy orig / adapter invoke orig invoke adapter
  • 346. DynamicObjectAdapter - ext. Version 78 @SvenRuppert first extension !
  • 347. DynamicObjectAdapter - ext. Version 79 @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";
 }
 }
  • 348. DynamicObjectAdapter - ext. Version 80 @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);
 }
  • 349. DynamicObjectAdapter - ext. Version 80 @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);
 }
  • 350. DynamicObjectAdapter - ext. Version 80 @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
  • 351. DynamicObjectAdapter - ext. Version 80 @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
  • 352. DynamicObjectAdapter - ext. Version 80 @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
  • 353. DynamicObjectAdapter - ext. Version 81 @SvenRuppert private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();
 private Map<MethodIdentifier, Object> adapters = new HashMap<>();
 
 private T original;
 private Class<T> target;
  • 354. DynamicObjectAdapter - ext. Version 81 @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) {
  • 355. DynamicObjectAdapter - ext. Version 81 @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();
  • 356. DynamicObjectAdapter - ext. Version 81 @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();
  • 357. DynamicObjectAdapter - ext. Version 81 @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) {
  • 358. DynamicObjectAdapter - ext. Version 81 @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);
  • 359. DynamicObjectAdapter - ext. Version 81 @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);
  • 360. DynamicObjectAdapter - ext. Version 81 @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);
  • 361. DynamicObjectAdapter - ext. Version 81 @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);
  • 362. DynamicObjectAdapter - ext. Version 82 @SvenRuppert private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();
 private Map<MethodIdentifier, Object> adapters = new HashMap<>();
 
 private T original;
 private Class<T> target;
  • 363. DynamicObjectAdapter - ext. Version 82 @SvenRuppert private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();
 private Map<MethodIdentifier, Object> adapters = new HashMap<>();
 
 private T original;
 private Class<T> target; public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  • 364. DynamicObjectAdapter - ext. Version 82 @SvenRuppert private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();
 private Map<MethodIdentifier, Object> adapters = new HashMap<>();
 
 private T original;
 private Class<T> target; public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try {
 final MethodIdentifier key = new MethodIdentifier(method);
 Method other = adaptedMethods.get(key);
  • 365. DynamicObjectAdapter - ext. Version 82 @SvenRuppert private Map<MethodIdentifier, Method> adaptedMethods = new HashMap<>();
 private Map<MethodIdentifier, Object> adapters = new HashMap<>();
 
 private T original;
 private Class<T> target; 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);
 }

  • 366. DynamicObjectAdapter - ext. Version 82 @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);
 }

  • 367. 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 !!
  • 368. 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 !!
  • 369. 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
  • 370. DynamicObjectAdapter - orig Version @SvenRuppert Add some typed with-Methods public AdapterBuilder<T> withDoWork_A(ServiceAdapter_A adapter) {
 addAdapter(adapter);
 return this;
 }
  • 371. DynamicObjectAdapter - orig Version @SvenRuppert Add some typed with-Methods public AdapterBuilder<T> withDoWork_A(ServiceAdapter_A adapter) {
 addAdapter(adapter);
 return this;
 } remember
  • 372. 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);
 }
  • 373. 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);
 }

  • 374. DynamicObjectAdapter - orig Version @SvenRuppert How to use this?
  • 375. DynamicObjectAdapter - orig Version @SvenRuppert How to use this? Service service = AdapterBuilder.<Service>newBuilder()
  • 376. DynamicObjectAdapter - orig Version @SvenRuppert How to use this? Service service = AdapterBuilder.<Service>newBuilder() .withTarget(Service.class)
  • 377. DynamicObjectAdapter - orig Version @SvenRuppert How to use this? Service service = AdapterBuilder.<Service>newBuilder() .withTarget(Service.class) .withOriginal(new ServiceImpl())
  • 378. DynamicObjectAdapter - orig Version @SvenRuppert How to use this? Service service = AdapterBuilder.<Service>newBuilder() .withTarget(Service.class) .withOriginal(new ServiceImpl()) .withDoWork_A((txt) -> txt + "_part")
  • 379. 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")
  • 380. DynamicObjectAdapter - orig Version @SvenRuppert How to use this like a mock ?
  • 381. DynamicObjectAdapter - orig Version @SvenRuppert How to use this like a mock ? Service service = AdapterBuilder.<Service>newBuilder()
  • 382. DynamicObjectAdapter - orig Version @SvenRuppert How to use this like a mock ? Service service = AdapterBuilder.<Service>newBuilder() .withTarget(Service.class)
  • 383. DynamicObjectAdapter - orig Version @SvenRuppert How to use this like a mock ? Service service = AdapterBuilder.<Service>newBuilder() .withTarget(Service.class) .withOriginal(null)
  • 384. DynamicObjectAdapter - orig Version @SvenRuppert How to use this like a mock ? Service service = AdapterBuilder.<Service>newBuilder() .withTarget(Service.class) .withOriginal(null) .withDoWork_A((txt) -> txt + "_part")
  • 385. DynamicObjectAdapter - orig Version @SvenRuppert .build(); How to use this like a mock ? Service service = AdapterBuilder.<Service>newBuilder() .withTarget(Service.class) .withOriginal(null) .withDoWork_A((txt) -> txt + "_part")
  • 386. generated DynamicObjectAdapterBuilder @SvenRuppert To much boring code to write but we want to have a type-safe version if wrong… compile must break
  • 387. generated DynamicObjectAdapterBuilder @SvenRuppert To much boring code to write but we want to have a type-safe version What could we change now ? if wrong… compile must break
  • 389. generated DynamicObjectAdapterBuilder @SvenRuppert remember public interface Service {
 String doWork_A(String txt);
 String doWork_B(String txt);
 }
  • 390. 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);
 }
  • 391. 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);
 }
  • 392. 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
  • 394. generated DynamicObjectAdapterBuilder @SvenRuppert use Annotation Processing create a marker like @DynamicObjectAdapterBuilder
  • 395. generated DynamicObjectAdapterBuilder @SvenRuppert use Annotation Processing create a marker like @DynamicObjectAdapterBuilder @Retention(RetentionPolicy.SOURCE)
 @Target(ElementType.TYPE)
 public @interface DynamicObjectAdapterBuilder {
 }
  • 396. 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
  • 397. generated DynamicObjectAdapterBuilder @SvenRuppert use Annotation Processing with every compile you will get actual
  • 398. generated DynamicObjectAdapterBuilder @SvenRuppert use Annotation Processing with every compile you will get actual Functional-Interfaces for the Adapters
  • 399. generated DynamicObjectAdapterBuilder @SvenRuppert use Annotation Processing with every compile you will get actual Functional-Interfaces for the Adapters generated AdapterBuilder
  • 400. StaticObjectAdapter @SvenRuppert to avoid the latency of the dynamic Proxy we could implement static ObjectAdapter the basic idea is the same as we had 
 with the DynamicObjectAdapter
  • 401. StaticObjectAdapter @SvenRuppert split the interface into Functional Interfaces create for every Functional Interface an attribute at runtime: if an attribute 
 is available invoke the method ….. otherwise use the delegator
  • 402. StaticObjectAdapter @SvenRuppert public interface Service {
 String doWorkA(String txt);
 String doWorkB(String txt);
 }
  • 403. StaticObjectAdapter @SvenRuppert public interface Service {
 String doWorkA(String txt);
 String doWorkB(String txt);
 } public interface Service_DoWorkA_Adapter{ 
 String doWorkA(final String txt); 
 }
 public interface Service_DoWorkB_Adapter{ 
 String doWorkB(final String txt); 
 }
  • 404. StaticObjectAdapter @SvenRuppert public interface Service {
 String doWorkA(String txt);
 String doWorkB(String txt);
 } public interface Service_DoWorkA_Adapter{ 
 String doWorkA(final String txt); 
 }
 public interface Service_DoWorkB_Adapter{ 
 String doWorkB(final String txt); 
 }
  • 405. StaticObjectAdapter @SvenRuppert public interface Service {
 String doWorkA(String txt);
 String doWorkB(String txt);
 } public interface Service_DoWorkA_Adapter{ 
 String doWorkA(final String txt); 
 }
 public interface Service_DoWorkB_Adapter{ 
 String doWorkB(final String txt); 
 } functional interface
  • 407. StaticObjectAdapter @SvenRuppert public class ServiceStaticObjectAdapter implements Service {
  • 408. StaticObjectAdapter @SvenRuppert public class ServiceStaticObjectAdapter implements Service { private Service service;
  • 409. StaticObjectAdapter @SvenRuppert public class ServiceStaticObjectAdapter implements Service { private Service service; private Service_DoWorkA_Adapter doWorkAAdapter;
  • 410. StaticObjectAdapter @SvenRuppert public class ServiceStaticObjectAdapter implements Service { private Service service; private Service_DoWorkA_Adapter doWorkAAdapter; private Service_DoWorkB_Adapter doWorkBAdapter;
  • 411. StaticObjectAdapter @SvenRuppert public class ServiceStaticObjectAdapter implements Service { private Service service; private Service_DoWorkA_Adapter doWorkAAdapter; private Service_DoWorkB_Adapter doWorkBAdapter; public String doWorkA(final String txt) { }
  • 412. StaticObjectAdapter @SvenRuppert public class ServiceStaticObjectAdapter implements Service { private Service service; private Service_DoWorkA_Adapter doWorkAAdapter; private Service_DoWorkB_Adapter doWorkBAdapter; public String doWorkA(final String txt) { if (this.doWorkAAdapter != null) }
  • 413. StaticObjectAdapter @SvenRuppert public class ServiceStaticObjectAdapter implements Service { private Service service; private Service_DoWorkA_Adapter doWorkAAdapter; private Service_DoWorkB_Adapter doWorkBAdapter; public String doWorkA(final String txt) { if (this.doWorkAAdapter != null) return this.doWorkAAdapter.doWorkA(txt); }
  • 414. StaticObjectAdapter @SvenRuppert public class ServiceStaticObjectAdapter implements Service { private Service service; private Service_DoWorkA_Adapter doWorkAAdapter; private Service_DoWorkB_Adapter doWorkBAdapter; public String doWorkA(final String txt) { if (this.doWorkAAdapter != null) return this.doWorkAAdapter.doWorkA(txt); return service.doWorkA(txt) }
  • 415. StaticObjectAdapter @SvenRuppert public class ServiceStaticObjectAdapter implements Service { private Service service; private Service_DoWorkA_Adapter doWorkAAdapter; private Service_DoWorkB_Adapter doWorkBAdapter; public String doWorkA(final String txt) { if (this.doWorkAAdapter != null) return this.doWorkAAdapter.doWorkA(txt); return service.doWorkA(txt) } We can generate this !
  • 416. generated StaticObjectAdapter @SvenRuppert with AnnotationProcessing split the interface with @StaticObjectAdapter write functional interfaces generate the StaticObjectAdapter mark the Adapter with @IsObjectAdapter
  • 417. prepare for….. Proxy Deep Dive - StaticVirtualProxy - at Runtime some words about : how it works..and what you can do with this.. 96 @SvenRuppert
  • 420. generate Static Proxies at Runtime @SvenRuppert this is based on the Newsletter Nr 180 and Nr 181 from Dr. Heinz Kabutz http://www.javaspecialists.eu/archive/Issue181.html http://www.javaspecialists.eu/archive/Issue180.html
  • 421. generate Static Proxies at Runtime @SvenRuppert questions are:
  • 422. generate Static Proxies at Runtime @SvenRuppert questions are: How to compile In-Memory ?
  • 423. generate Static Proxies at Runtime @SvenRuppert questions are: How to compile In-Memory ? What is the right ClassLoader ?
  • 424. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ?
  • 425. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? you will need the JavaCompiler from tools.jar
  • 426. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? you will need the JavaCompiler from tools.jar a holder for the SourceCode
  • 427. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? you will need the JavaCompiler from tools.jar a holder for the SourceCode public class GeneratedJavaSourceFile extends SimpleJavaFileObject {
 
 private CharSequence javaSource;
 
 
 
 public GeneratedJavaSourceFile(String className, CharSequence javaSource) {
 super(URI.create(className + ".java"), Kind.SOURCE);
 this.javaSource = javaSource;
 }
 
 public CharSequence getCharContent(boolean ignoreEncodeErrors)
 throws IOException {
 return javaSource;
 }
 }
  • 428. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? you will need the JavaCompiler from tools.jar a holder for the SourceCode public class GeneratedJavaSourceFile extends SimpleJavaFileObject {
 
 private CharSequence javaSource;
 
 
 
 public GeneratedJavaSourceFile(String className, CharSequence javaSource) {
 super(URI.create(className + ".java"), Kind.SOURCE);
 this.javaSource = javaSource;
 }
 
 public CharSequence getCharContent(boolean ignoreEncodeErrors)
 throws IOException {
 return javaSource;
 }
 }
  • 429. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? you will need the JavaCompiler from tools.jar a holder for the SourceCode public class GeneratedJavaSourceFile extends SimpleJavaFileObject {
 
 private CharSequence javaSource;
 
 
 
 public GeneratedJavaSourceFile(String className, CharSequence javaSource) {
 super(URI.create(className + ".java"), Kind.SOURCE);
 this.javaSource = javaSource;
 }
 
 public CharSequence getCharContent(boolean ignoreEncodeErrors)
 throws IOException {
 return javaSource;
 }
 }
  • 430. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? you will need the JavaCompiler from tools.jar a holder for the SourceCode public class GeneratedJavaSourceFile extends SimpleJavaFileObject {
 
 private CharSequence javaSource;
 
 
 
 public GeneratedJavaSourceFile(String className, CharSequence javaSource) {
 super(URI.create(className + ".java"), Kind.SOURCE);
 this.javaSource = javaSource;
 }
 
 public CharSequence getCharContent(boolean ignoreEncodeErrors)
 throws IOException {
 return javaSource;
 }
 } the generated source code
  • 431. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ?
  • 432. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? a holder for the ByteCode
  • 433. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? a holder for the ByteCode public class GeneratedClassFile extends SimpleJavaFileObject {
 private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
 
 public GeneratedClassFile() {
 super(URI.create("generated.class"), Kind.CLASS);
 }
 
 public OutputStream openOutputStream() {
 return outputStream;
 }
 
 public byte[] getClassAsBytes() {
 return outputStream.toByteArray();
 }
 }
  • 434. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? a holder for the ByteCode public class GeneratedClassFile extends SimpleJavaFileObject {
 private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
 
 public GeneratedClassFile() {
 super(URI.create("generated.class"), Kind.CLASS);
 }
 
 public OutputStream openOutputStream() {
 return outputStream;
 }
 
 public byte[] getClassAsBytes() {
 return outputStream.toByteArray();
 }
 }
  • 435. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? a holder for the ByteCode public class GeneratedClassFile extends SimpleJavaFileObject {
 private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
 
 public GeneratedClassFile() {
 super(URI.create("generated.class"), Kind.CLASS);
 }
 
 public OutputStream openOutputStream() {
 return outputStream;
 }
 
 public byte[] getClassAsBytes() {
 return outputStream.toByteArray();
 }
 }
  • 436. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? a holder for the ByteCode public class GeneratedClassFile extends SimpleJavaFileObject {
 private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
 
 public GeneratedClassFile() {
 super(URI.create("generated.class"), Kind.CLASS);
 }
 
 public OutputStream openOutputStream() {
 return outputStream;
 }
 
 public byte[] getClassAsBytes() {
 return outputStream.toByteArray();
 }
 } the generated ByteCode
  • 437. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ?
  • 438. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? a ForwardingJavaFileManager
  • 439. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? a ForwardingJavaFileManager public class GeneratingJavaFileManager 
 extends ForwardingJavaFileManager<JavaFileManager> {
 
 private final GeneratedClassFile gcf;
 
 
 public GeneratingJavaFileManager( 
 StandardJavaFileManager sjfm, 
 GeneratedClassFile gcf) {
 super(sjfm);
 this.gcf = gcf;
 }
 public JavaFileObject getJavaFileForOutput(
 Location location, String className,
 JavaFileObject.Kind kind, FileObject sibling)
 throws IOException {
 return gcf;
 }
 }
  • 440. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? a ForwardingJavaFileManager public class GeneratingJavaFileManager 
 extends ForwardingJavaFileManager<JavaFileManager> {
 
 private final GeneratedClassFile gcf;
 
 
 public GeneratingJavaFileManager( 
 StandardJavaFileManager sjfm, 
 GeneratedClassFile gcf) {
 super(sjfm);
 this.gcf = gcf;
 }
 public JavaFileObject getJavaFileForOutput(
 Location location, String className,
 JavaFileObject.Kind kind, FileObject sibling)
 throws IOException {
 return gcf;
 }
 }
  • 441. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? a ForwardingJavaFileManager public class GeneratingJavaFileManager 
 extends ForwardingJavaFileManager<JavaFileManager> {
 
 private final GeneratedClassFile gcf;
 
 
 public GeneratingJavaFileManager( 
 StandardJavaFileManager sjfm, 
 GeneratedClassFile gcf) {
 super(sjfm);
 this.gcf = gcf;
 }
 public JavaFileObject getJavaFileForOutput(
 Location location, String className,
 JavaFileObject.Kind kind, FileObject sibling)
 throws IOException {
 return gcf;
 }
 } will force the 
 JavaCompiler to write 
 to this instance
  • 442. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? a ForwardingJavaFileManager public class GeneratingJavaFileManager 
 extends ForwardingJavaFileManager<JavaFileManager> {
 
 private final GeneratedClassFile gcf;
 
 
 public GeneratingJavaFileManager( 
 StandardJavaFileManager sjfm, 
 GeneratedClassFile gcf) {
 super(sjfm);
 this.gcf = gcf;
 }
 public JavaFileObject getJavaFileForOutput(
 Location location, String className,
 JavaFileObject.Kind kind, FileObject sibling)
 throws IOException {
 return gcf;
 }
 } will force the 
 JavaCompiler to write 
 to this instance
  • 443. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? a ForwardingJavaFileManager public class GeneratingJavaFileManager 
 extends ForwardingJavaFileManager<JavaFileManager> {
 
 private final GeneratedClassFile gcf;
 
 
 public GeneratingJavaFileManager( 
 StandardJavaFileManager sjfm, 
 GeneratedClassFile gcf) {
 super(sjfm);
 this.gcf = gcf;
 }
 public JavaFileObject getJavaFileForOutput(
 Location location, String className,
 JavaFileObject.Kind kind, FileObject sibling)
 throws IOException {
 return gcf;
 }
 } the generated ByteCode will force the 
 JavaCompiler to write 
 to this instance
  • 444. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? the compile task itself
  • 445. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? the compile task itself GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource);
  • 446. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? the compile task itself GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource); DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>();
  • 447. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? the compile task itself GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource); DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>(); JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
  • 448. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? the compile task itself GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource); StandardJavaFileManager stdFileManager = jc.getStandardFileManager(dc, null, null); DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>(); JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
  • 449. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? the compile task itself GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource); StandardJavaFileManager stdFileManager = jc.getStandardFileManager(dc, null, null); DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>(); JavaCompiler jc = ToolProvider.getSystemJavaCompiler(); GeneratedClassFile gcf = new GeneratedClassFile();
  • 450. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? the compile task itself GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource); StandardJavaFileManager stdFileManager = jc.getStandardFileManager(dc, null, null); GeneratingJavaFileManager fileManager 
 = new GeneratingJavaFileManager(stdFileManager, gcf); DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>(); JavaCompiler jc = ToolProvider.getSystemJavaCompiler(); GeneratedClassFile gcf = new GeneratedClassFile();
  • 451. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? the compile task itself GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource); StandardJavaFileManager stdFileManager = jc.getStandardFileManager(dc, null, null); GeneratingJavaFileManager fileManager 
 = new GeneratingJavaFileManager(stdFileManager, gcf); JavaCompiler.CompilationTask task 
 = jc.getTask(null, fileManager, dc, null, null, singletonList(gjsf)); DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>(); JavaCompiler jc = ToolProvider.getSystemJavaCompiler(); GeneratedClassFile gcf = new GeneratedClassFile();
  • 452. generate Static Proxies at Runtime @SvenRuppert How to compile In-Memory ? the compile task itself return task.call(); GeneratedJavaSourceFile gjsf = new GeneratedJavaSourceFile(className, javaSource); StandardJavaFileManager stdFileManager = jc.getStandardFileManager(dc, null, null); GeneratingJavaFileManager fileManager 
 = new GeneratingJavaFileManager(stdFileManager, gcf); JavaCompiler.CompilationTask task 
 = jc.getTask(null, fileManager, dc, null, null, singletonList(gjsf)); DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>(); JavaCompiler jc = ToolProvider.getSystemJavaCompiler(); GeneratedClassFile gcf = new GeneratedClassFile();
  • 453. generate Static Proxies at Runtime @SvenRuppert What is the right ClassLoader ?
  • 454. generate Static Proxies at Runtime @SvenRuppert could be: public Unsafe.defineClass() What is the right ClassLoader ?
  • 455. generate Static Proxies at Runtime @SvenRuppert could be: public Unsafe.defineClass() What is the right ClassLoader ? or: private static Proxy.defineClass0()
  • 456. generate Static Proxies at Runtime @SvenRuppert could be: public Unsafe.defineClass() What is the right ClassLoader ? or: private static Proxy.defineClass0() both versions are depending on the selected JVM
  • 457. generate Static Proxies at Runtime @SvenRuppert could be: public Unsafe.defineClass() What is the right ClassLoader ? or: private static Proxy.defineClass0() both versions are depending on the selected JVM but this solution will have 
 no roundtrip over the hard disc
  • 458. generate Static Proxies at Runtime @SvenRuppert could be: public Unsafe.defineClass() What is the right ClassLoader ? or: private static Proxy.defineClass0() both versions are depending on the selected JVM but this solution will have 
 no roundtrip over the hard disc will create and compile 
 Proxies at runtime
  • 459. prepare for….. Proxy Deep Dive - Summary what we reached, what we could do now 105 @SvenRuppert
  • 462. Summary 107 @SvenRuppert we got type-safe ProxyBuilder ..type-safe generated DynamicObjectAdapter ..at runtime we could change the chain of Proxies ..could be used for (Dynamic) Dependency Injection Implementations
  • 463. Summary 108 @SvenRuppert If you are interested… have a look at RapidPM on github rapidpm-proxybuilder rapidpm-dynamic-cdi rapidpm-microservice or contact me ;-) @SvenRuppert
  • 464. Summary 108 @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 !!!