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.
Related
I would like to use a CGLIB proxy to add my own reusable equals() method to existing objects.
The objects do not necessarily implement any interfaces and I need to be able to cast the proxied object to the original class (without getting the target of the proxy).
Unfortunately, it seems that CGLIB implements its own equals() method and makes sure that only that method is called: there is a private static class (EqualsInterceptor) whose method intercept() implements a reasonable logic to compare proxied objects.
The problem is that this method, at the end, delegates the comparison to the target objects: I need instead to reuse some logic that is not implemented by the target classes.
Using a standard proxy, I was able to intercept the call to the equals() method and execute my logic. The problem is that these kind of proxies cannot be cast to the original class.
It seems that the only way is to rewrite some classes in the CGLIB library. It does not seem a good idea.
No, this is not possible using cglib.
You can use another library such as Byte Buddy which allows you to intercept equals/hashCode just like any other method.
For disclosure: I am the author of Byte Buddy and a maintainer for cglib which are both Apache 2.0 licensed.
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.
In class today, we were talking about reflection in Java programming. A part of the lesson today was about using InvocationHandlers in Java, rather than just implementing an interface.
When I asked the teacher what the advantages were of using an invocation handler, there wasn't a clear answer.
So let's say we have an interface Plugin
public interface Plugin {
void calculate(double a, double b);
String getCommand();
}
you can easily implement this interface in a class Multiply
public class Multiply implements Plugin {
#Override
public void calculate(double a, double b){
return a * b;
}
#Override
public String getCommand(){
return "*";
}
}
Then why would I prefer another implementation using an InvocationHandler?
public class MyMock {
public static Object createMock(Class myClass) {
InvocationHandler handler = new MyInvocationHandler();
Object result = Proxy.newProxyInstance(myClass.getClassLoader(), new Class[]{myClass}, handler);
return result;
}
}
Thanks in advance :)
Proxy is a dynamic proxy, allowing you to alter the behaviour of objects at runtime instead of having to decide it at compile-time.
For example, let's say we want to return only nulls during the night. If you were to implement it statically, you would need to write the logic into all the classes with something like
if(isNight())
return null;
return normalValue;
This requires that you can actually change the class, and you would need to change all the classes.
However with a Proxy, you can write the above logic into the InvocationHandler and the normal classes won't even know that their values aren't used during the night. Instead of the original class, your code is now using the dynamic proxy, but it won't know the difference.
This also allows you to have multiple InvocationHandlers, so you could run your code with parameters to decide if you want to log calls, prevent calls for security reasons, or any other such thing, which would be quite impossible to do with static implementations.
You're unlikely to use those classes directly though, as they're quite low level. However AOP uses either dynamic proxies or bytecode manipulation to achieve its task. If you've ever used Spring, you've most likely used an InvocationHandler without knowing it. When you put #Transactional on a method, an InvocationHandler is what will intercept the method call and start (and end) the transaction for you.
InvocationHandler together with Proxy allow implementation of an interface at runtime, without the faff of compiling interface-specfic code. It is often used to mediate access to an object of a class that implements the same interface. Proxy does not allow changing the behaviour of existing objects or classes.
For instance, it can be used in remote method calling on the client side, forwarding method call across a network to a server.
My first use of Proxy was for logging method calls to a wide interface that represented command received over a wire format. This easily produced very consistent debug output, but required little maintenance when the interface changed.
Java annotation interfaces may be represented by a Proxy proxy object at runtime, to prevent an explosion of classes.
java.beans.EventHandler was useful before lambdas and method references came along, to implement event listeners without bloating jars.
As per a more specific or real-world example, you may run into these kind of reflection usages more using a third-party or open-source API. A very popular example of this would be minecraft, specifically Bukkit/Spigot.
This api is used to write plugins, which the main server then loads and runs. This means you're not 100% in control of some of the code that exists in that codebase, inviting solutions using reflection. Specifically, when you want to intercept calls being made in the API (or even another plugin's API, e.g. Vault for those familiar), you may look to use a Proxy.
We'll stick with the minecraft example, but we're parting from bukkit's api here (and pretending it's not accepting PRs). Say there's a part of the API that just doesn't quite work the way you need.
public interface Player {
//This method handles all damage! Hooray!
public void damagePlayer(Player source, double damage);
}
This is great, but if we want to code something where we could find out if a player was damaged (maybe to make cool effects?), we'd need to modify the source (not possible for distributed plugins), or we'd need to find a way to figure out when #damagePlayer has been called and with what values. So in comes a Proxy:
public class PlayerProxy implements IvocationHandler {
private final Player src;
public PlayerProxy(Player src) {
this.src = src;
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
//Proceed to call the original Player object to adhere to the API
Object back = m.invoke(this.src, args);
if (m.getName().equals("damagePlayer") && args.length == 2) {
//Add our own effects!
//Alternatively, add a hook so you can register multiple things here, and avoid coding directly inside a Proxy
if (/* 50% random chance */) {
//double damage!
args[1] = (double) args[1] * 2;
//or perhaps use `source`/args[0] to add to a damage count?
}
}
}
}
With our Proxy, we've effectively created a fake Player class, one which will simply call the methods in place for Player. If our PlayerProxy is invoked with myPlayerProxy.someOtherMethod(...), then it will happily pass along a call to myPlayerProxy.src.someOtherMethod(...) via reflection (the m#invoke in the method above).
Simply put, you hot-potato the objects in the library to suit your needs:
//we'll use this to demonstrate "replacing" the player variables inside of the server
Map<String, Player> players = /* a reflected instance of the server's Player objects, mapped by name. Convenient! */;
players.replaceAll((name, player) ->
(PlayerProxy) Proxy.newProxyInstance(/* class loader */, new Class<?>[]{Player.class}, new PlayerProxy(player)));
InvocationHandler can handle multiple interfaces too. By using a generic Object to pass along the invocations, you can then listen to a variety of different methods in the API all within the same Proxy instance.
I have an interface whose implementors all require a common method internally - it is not required to be part of the public interface. Also, there are future interfaces in the pipeline that will need this functionality.
Is it good design to have this interface implement a different interface that just has this default method implemented? This way all implementors have access to the common method seamlessly. But, since there is no concept of 'private default' methods, the method is also exposed to clients, which I feel isn't right.
Is resorting to a separate concrete utils class a better means to this end? Or creating an abstract implementation of my interface with the required method and have clients extend that?
EDIT: My question is more inclined towards finding out whether an interface with only default methods is sound, design-wise? Having static methods in the interface does not seem to be in contention actually.
interface is used to segregate the users and the implementors. In your situation, i think an abstract class is more suitable.
default methods are overridable methods, but your scenario describes a utility method that is intended to be neither, part of the API nor overridable. Note that since default methods can work on the instance only in terms of the public methods defined in the interface, i.e. can not access any internals, there is no difference between:
interface MyInterface {
default ReturnType method(Parameter parameter) {
}
}
and
interface MyInterface {
static ReturnType method(MyInterface instance, Parameter parameter) {
}
}
regarding what the method can do. It’s only that within the default method, you may omit the qualifying this. when invoking other interface method, whereas in the static method, using instance. is mandatory. But in either case, you may invoke all public methods of the MyInterface instance but nothing else.
But the static method is not overridable and you may move it to any other class to avoid it becoming part of MyInterface’s API. But note that there is little reason to worry about the accessibility of the utility method. Since it can’t access any internals of the implementation classes, it can’t offer anything that the callers couldn’t do otherwise. It only makes it more comfortable than re‑implementing the functionality at the caller’s site. So moving the method into another class primarily documents the intention of not being part of the MyInterface’s API. It’s no harm, if the method is public there (to support implementations in arbitrary packages).
See for example the methods in the class StreamSupport. They are there to aid implementing Streams, needed by different packages, but not part of the Stream interface API itself. The fact that the methods there are public does not create any harm, they don’t offer anything you couldn’t do yourself using the other available public APIs. But it’s convenient for implementors not needing to do it themselves.
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.