Everybody knows the pattern proxy, but how can you use it effectively?
What kind of proxy patterns are available, and how can you
build patterns more effectively with it? Why is reflection needed for this?
Importantly, we need only the core JDK in most cases.
This tutorial starts from the basics and continues on to
DynamicProxies, DynamicObjectAdapter and DynamicStaticProxies at runtime, StaticObjectAdapters, and more.
The session, based on the German book Dynamic Proxies,
by Heinz Kabutz and the session’s presenter, takes a deep dive into this pattern group.
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
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"; }
}
}
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
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 ?
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(); }
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
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 ?
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
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
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
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…
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
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> {
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);
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 ?
308. DynamicObjectAdapter - orig Version
70
@SvenRuppert
Proxy
orig /
adapter
invoke orig
invoke adapter
Goal: do not need to write an
Adapter with Delegator
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(); }
}