In Java, how can I create a “proxy” around an object that invokes a method when a property changes?

I am looking for something similar to a proxy template or Dynamic proxy classes , only that I do not want to intercept method calls before they are called on a real object, but I would like to intercept the changed properties. I would like the proxy to be able to represent multiple objects with different sets of properties. Something like the Proxy class in Action Script 3 will be fine.

Here is what I want to achieve overall:

I have a thread running with an object that manages a list of values ​​(numbers, strings, objects) that were transferred by other threads in the program, so the class can take care of creating regular constant snapshots on disk to assign an application breakpoint. This persistor object controls a dirty flag, which means whether the list of values ​​has changed since the last checkpoint and needs to block the list when it is busy writing it to disk.

The persistor and other components identify a specific element using a common name, so that when recovering from a failure, other components can first check whether their last copy was saved and continue working where they left off.

During normal operation, in order to work with objects transferred to persistor, I want them to get a link to a proxy object, which looks as if it was original, but whenever they change some value on it , persistor notices and acts accordingly, for example, by marking an element or list as dirty before the actual value is actually set.


Change Alternatively, are there universal setters in Java (for example, PHP 5), that is, a method called if the property does not exist? Or is there a type of object that I can add properties at runtime?

+4
source share
4 answers

If with “properties” you mean JavaBean properties, that is, imagine how to use getter and / or setter method, then you can use dynamic proxy to intercept the installed method.

If you mean instance variables, then no can can not - not at the Java level. Perhaps something can be done with manipulation at the byte code level .

In fact, the easiest way to do this is probably by using AspectJ and defining pointcut () that will intercept access to fields at the byte code level).

+3
source

The sample design you are looking for is: Differential execution. I believe.

How is differential execution performed?

I asked a question to which I answered regarding this.

However, can I suggest using a callback instead? You will have to read about it, but the general idea is that you can implement interfaces (often called listeners) that are active on "something interesting." Such as changing the data structure.

Public relations:

Differential Wiki Execution

Wiki Callback

Ok, here is the answer I see. Differential execution is O (N) time. This is really reasonable, but if this does not work for you, Callbacks will be called. Callbacks basically work by passing a method by parameter to your class, which changes the array. This method will take the value changed and the location of the element, pass it back to the parameter in the "storage class" and change the value accordingly. So yes, you have to support every change with a method call.

I understand that this is not what you want. What seems right to you is a way that you can provide some kind of listener for each variable in the array that will be called when this element is changed. Then the listener will modify the corresponding array in your “backup” to edit this change.

I can’t figure out how to do this. Of course, you can create your own listeners and events using the interface. This is basically the same idea as callbacks, although it's better to look at them.

Then there is a reflection ... Java has a reflection, and I'm sure you can write something using this for this. However, reflection is known to be slow. Not to mention the pain in the code (in my opinion).

Hope this helps ...

+2
source

I don’t want to intercept method calls before they are called on a real object, but rather I would like to intercept properties that change

Thus, the objects you want to control are not convenient beans, but the revival of C-structures. The only way that comes to my mind is to call field access in the JVMTI .

+1
source

I wanted to do the same myself. My solution was to use dynamic proxy wrappers using Javassist. I would generate a class that implements the same interface as the class of my target object, transfers the proxy class around the source class and delegates all method calls to the proxy to the original, except for setters that also run PropertyChangeEvent.

Anyway, I posted the full explanation and code on my blog: http://clockwork-fig.blogspot.com/2010/11/javabean-property-change-listener-with.html

+1
source

All Articles