When to use "Dynamic Proxy class" or "standard proxy" pattern? - java

Why should one use a "Dynamic Proxy class" instead of the "standard proxy" pattern?
What are the disadvantages or advantages of both?
It seems like they both have the same end result, except that they are implemented differently.
Dynamic proxy class
https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/proxy.html
A dynamic proxy class is a class that implements a list of interfaces
specified at runtime such that a method invocation through one of the
interfaces on an instance of the class will be encoded and dispatched
to another object through a uniform interface. Thus, a dynamic proxy
class can be used to create a type-safe proxy object for a list of
interfaces without requiring pre-generation of the proxy class, such
as with compile-time tools. Method invocations on an instance of a
dynamic proxy class are dispatched to a single method in the
instance's invocation handler, and they are encoded with a
java.lang.reflect.Method object identifying the method that was
invoked and an array of type Object containing the arguments.
Standard proxy pattern https://en.wikipedia.org/wiki/Proxy_pattern
A proxy, in its most general form, is a class functioning as an
interface to something else. The proxy could interface to anything: a
network connection, a large object in memory, a file, or some other
resource that is expensive or impossible to duplicate. In short, a
proxy is a wrapper or agent object that is being called by the client
to access the real serving object behind the scenes. In the proxy
extra functionality can be provided, for example caching when
operations on the real object are resource intensive, or checking
preconditions before operations on the real object are invoked. For
the client, usage of a proxy object is similar to using the real
object, because both implement the same interface.

You have appeared to answer your own question. You should use the one which is easier to implement for your use case.
You need to dynamic proxy when you do not have an implementation for each method at compile time.
For example, mocking test libraries use the dynamic proxies so that can write code to handle any method generically.

Related

Java: How to listen on methods invocation without registering each object explicitely?

I want to listen on method calls in order to attach additional behavior dynamically around the call. I've already done it on JUnit methods with a custom annotation and runner. I'm trying to do it on a standard java application.
The main idea is to do:
#Override
public void beforeInvoke (Object self, Method m, Object[] args){
Object[] newargs = modifyArgs (args);
m.invoke (self, newargs);
}
It's just an abstract idea, I don't have any concrete example, but I'm curious if it's possible in java.
I've found some approaches:
java.lang.reflect.Proxy.newProxyInstance(...)
where a proxy is defined for an interface only (but not used to decorate concrete classes). It seems similar to injection pattern and it's a different concern.
Another approach here using a factory pattern with the ProxyFactory class. This other solution requires explicit calls to create() method to produce object proxies listening on method invocations. So, if you bypass it by using natural constructors of your classes, it's not working. It's very constraining if you must explicit a call to a factory each time you have to create an object.
There is a way to do it with transparency ?
Like Proxy.newProxyInstance() but working also on concrete classes ?
Thanks.
Well,this is commonly seen with Spring Framework and Aspect Oriented Programming. Since you delegate your constructor calls to Spring, it is quite easy for Spring to put a proxy in place to intercept calls to the actual objects.
As far as I can tell, the only way to intercept calls is to use a proxy. Either in the way you mentioned or using Spring and AOP.
I think cglib let you instrument concrete classes.
As far as I know there is no easy way to intercept method calls that are called on a concrete class.
As mentioned you could manipulate the bytecode during compilation (as Used in AOP) or at class loading time (as used from cglib).
Another product to instrument Classes would be jmockit (http://jmockit.org/). Usually I would use this special kind of black magic only in testing environments and not in an productive environment.
Another way you could go is Annotation Processing. It work's during compiling process. You have to write a Processor which will walk through your source code and generate source-code that contains the original code plus the enhanced method-calls you need.
Depending on how much source-code you have to enhance, this method might be a good idea, but in general it is a lot of work.
Here's a link (https://deors.wordpress.com/2011/10/08/annotation-processors/).
Despite usually it's used in combination with annotations, this is not a strict requirement.

spring aop proxy object

I'm now reading a Spring book written in Korean language and my English is bad. Please understand it.
In the book, it says Spring's AOP initiates class using Dynamic proxy if it uses Interface and it uses CGLIB to initiate class in case of not using Interface.
I don't clearly understand what it means. could you help me understand its deep meaning.
I don't know this question is silly or not. but I'm just curious THX.
A proxy is essentially a mediator between a client and an object such that it implements the object's non-final methods. Proxying an interface is relatively straightforward since an interface is simply a list of methods which need to be implemented, facilitating the interception of method invocations.
The Proxy class in Java is a class that implements a list of interfaces which are specified at runtime. A proxy then has an InvocationHandler associated with it, which delegates method calls made on the proxy to the object being proxied. It acts as a level of indirection such that methods are not invoked on the object itself but rather on its proxy. The InvocationHandler has but a single method which needs to be implemented:
public Object invoke(Object proxy, Method method, Object[] args)
Meanwhile, the client invoking the method can't tell the difference between a proxy and its underlying object representation, nor should it care.
Proxying a class dynamically, as opposed to an interface, is not quite as simple. While Java's Proxy is merely a runtime implementation of an interface or set of interfaces, objects do not have to implement an interface. Therefore, proxying classes requires bytecode generation, which is where libraries such as cglib come into play. cglib provides support for proxying classes because it can dynamically generate bytecode (i.e. class files), meaning it can extend classes at runtime in a way that Java's Proxy can implement an interface at runtime.
There are many uses of proxies. One such use is in lazy loading. Lazy loading allows objects in an object graph to be loaded only when they are needed. Rather than loading them all into memory immediately, which could be expensive and resource-intensive, we can load them on-the-fly when we need to access them, such as iterating over a collection of objects. Instead of loading the entire collection, we simply load a small set at a time. This can be achieved with proxies. The proxy represents the lazily-loaded object. The object itself, which might be loaded from a database, is not loaded until a method is invoked on its proxy. The proxy, which intercepts the method invocation, will then load the object into memory and delegate the method invocation to it.
Here is an example of a lazy-loading implementation:
public abstract class LazilyLoadedObject implements InvocationHandler {
private Object target;
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (target == null) {
target = loadObject();
}
return method.invoke(target, args);
}
/**
* Loads the proxied object. This might be an expensive operation
* or loading lots of objects could consume a lot of memory, so
* we only load the object when it's needed.
*/
protected abstract Object loadObject();
}
The above InvocationHandler would be passed to a proxy so that methods invoked on the proxy would be handled by the InvocationHandler. The handler checks to see if the object has been loaded. If it hasn't, it will call loadObject(), which could be some sort of database query that retrieves the object.
Proxies are very powerful because they allow for the interception of method invocations. Such is the case in AOP.
Java Dynamic Proxy is a reflective element of the Java language that allows a user to create a proxy of an interface at runtime. Being a part of the reflection package, it is a part of Java and it ships with the JRE/JDK.
CGLIB is a code generation library which has the capability to extend Java classes at runtime. Because of this, Spring utilizes this functionality to proxy non-interfaces for its AOP library.

How to detect what class is used in proxy?

For example I have proxy that is proxing interface CashManagment, toString of this proxy is somepackage.CashManagment:Stateless. I would like to know what real classes is being used by this proxy.
I think its EJB. CashManagment has more than one implementation.
As far as I know, java.lang.reflect.Proxy — I'm assuming that's what you're talking about — does not offer any way of discovering what the underlying proxied object is, or its class for that matter. It might be obtainable by using reflection, but that would be dependent on the runtime implementation and thus not a good idea.
If you're using Spring and its proxy mechanisms, then perhaps there is a way to obtain this.
You could introduce a function getType() in the interface, which returns the type of the implementation.

Javassist: how to create proxy of proxy?

I'm creating proxies with javassist ProxyFactory. When creating a single proxy all works fine.
However, when I pass a proxied object to the proxying mechanism, it fails with
javassist.bytecode.DuplicateMemberException: duplicate method: setHandler in com.mypackage.Bean_$$_javassist_0_$$_javassist_1
I'm creating the proxies with this:
public Object createProxiedInstance(Object originalInstance) throws Exception {
Class<?> originalClass = instance.getClass();
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(originalClass);
factory.setHandler(new MethodHandler() {..});
Class<T> proxyClass = factory.createClass();
return proxyClass.newInstance();
}
So, how do I create proxies of proxies?
Update: The actual problems is that each proxy implements the ProxyObject which defines setHandler(..) method. So the 2nd proxy is trying to redefine the method, instead of overriding it in the subclass.
The problem was (actually, it's the same with CGLIB - I tried it using commons-proxy) that I should not try to create a proxy class of the proxy class. The second proxy should again be of the original class. So adding the following line resolves the problem:
if (instance instanceof ProxyObject) {
originalClass = originalClass.getSuperclass();
}
And an advice - if you can use some sort of interceptors (like the ones defined in commons-proxy), do it instead of using multiple proxies.
Its a rather late answer but you might still be interested in knowing this:
Javassist proxies are implemented rather naively. In your above code, Javassist will always create a proxy class with the following methods:
A method for any overridable method of the base class
Two methods to (a) get a proxy handler (getHandler) and (b) set a proxy handler (setHandler)
The names of the two latter methods are hardcoded by Javassist and represented by the ProxyObject interface. If you now create a proxy class of a proxy class, Javassist would schedule the creation of ProxyObject's methods twice. Once by the first condition and once by the second condition.
You could avoid this by setting a MethodFilter which specifies to not override the ProxyObject's methods such that javassist would only create the methods by the second condition. However, this would imply that you could not longer set a ProxyObject for the super class proxy without directly accessing the corresponding field via reflection. Therefore, your approach is probably the cleanest.
cglib defines callbacks per class and not per instance such that this problem with cglib is slightly different but results in another conflict.
However, if you want to create proxy classes that do not suffer these shortcomings, you might be interested in my library Byte Buddy which I wrote after getting frustrated working with cglib and javassist when working in corner cases. If you are working with runtime code generation I hope that it might help offer you some flexibility that the other libraries lack.

Obj-c delegate model - in Java?

I'm writing a small chat program in Java. I got some classes whose objects have to keep track of one another (e.g. the connection listener needs to update the GUI when a new message comes in, just like the GUI needs to write to the connection's writer, when the user wants to send a message).
In Cocoa on Mac OS X I'd write & implement a delegate model. What about in Java? (So far, I'm just passing 'this' as an argument when I initialize a new object, in order to keep a reference to it from the new object.)
In Cocoa/Objective-C, delegates are objects that adhere to a specified protocol. A Java interface is analogous to an Objective-C protocol, except that Java does not permit optional methods: if your class implements an interface, you must implement all of the methods.
If you're cool with all of a delegate's methods being required, simply define an interface and use that.
If your delegate interface has a lot of methods and it would be convenient to make some of them optional, you could define an Adapter class that implements the delegate interface, providing a default implementation for each of the methods. To use it, your delegate class must either extend the adapter class or, if that is not possible, define a private inner class that extends the adapter class. (Look at Java's MouseListener interface and MouseAdapter class for an example of this.)
In summary, you can still use the delegate pattern in Java, although the static type checking will make optional methods a little more work.
Delegates are not directly provided by the Java language; using a listener pattern is the closest that standard Java comes to delegates.
However, I have implemented callback/delegate support in Java using reflection. Details and working source are available on my website.
How It Works
We have a principle class named Callback with a nested class named WithParms. The API which needs the callback will take a Callback object as a parameter and, if neccessary, create a Callback.WithParms as a method variable. Since a great many of the applications of this object will be recursive, this works very cleanly.
With performance still a high priority to me, I didn't want to be required to create a throwaway object array to hold the parameters for every invocation - after all in a large data structure there could be thousands of elements, and in a message processing scenario we could end up processing thousands of data structures a second.
In order to be threadsafe the parameter array needs to exist uniquely for each invocation of the API method, and for efficiency the same one should be used for every invocation of the callback; I needed a second object which would be cheap to create in order to bind the callback with a parameter array for invocation. But, in some scenarios, the invoker would already have a the parameter array for other reasons. For these two reasons, the parameter array did not belong in the Callback object. Also the choice of invocation (passing the parameters as an array or as individual objects) belongs in the hands of the API using the callback enabling it to use whichever invocation is best suited to it's inner workings.
The WithParms nested class, then, is optional and serves two purposes, it contains the parameter object array needed for the callback invocations, and it provides 10 overloaded invoke() methods (with from 1 to 10 parameters) which load the parameter array and then invoke the callback target.

Categories