Cross-cutting code, the homemade way
I though I’d do something different this time. Instead of describing something technical, I have recorded a five minute video that shows a very neat trick in Java: How to create a bit of code that wraps existing method calls to an object with any behavior you may desire.
This is nothing new, but I’ve noticed that not many developers know how to use it, so I hope this video may be useful:
If you would rather not include a library like cglib in your code and you don’t mind having to create an interface to create this sort of code, you can do the same with java.lang.reflect.Proxy
.
Comments:
Thomas Ferris Nicolaisen - Oct 26, 2010
Neat indeed. Few people know this feature, and even fewer actually make use of it.
I like video-blogging as a consumer, although as an author, I thought it was too much hassle with processing and uploading (took me like 1-2 hours). Any tips on that?
Johannes Brodwall - Oct 26, 2010
Thanks for the comment, Thomas.
I use BB FlashBack Express (free!) to record the videos. It automatically uploads them to blip.tv for me, so the whole recording and conversion toolchain is very simple.
It did take me four tries to get the recording right, though!
Thomas Ferris Nicolaisen - Oct 27, 2010
I’ll give it a spin. Thanks!
Rune Flobakk - Dec 7, 2010
Nice! I just used this technique to do a small POC to create simple Wicket models. E.g. model(of(dataprovider).size()) instead of new Model() { Integer getObject() { return dataprovider.size(); } }
I recommend using Objenesis for instantiating the actual proxy class generated by CGLIB. Objenesis handles instantiating classes without default constructors. In fact it can bypass constructors so that side effects in constructors (ugh..), if any, will not happen. Very applicable to proxies/dynamic subclasses which blocks all calls to the actual object.
Johannes Brodwall - Dec 7, 2010
Very nice example with the dataprovider. Objenesis looks interesting. How do you use it with CgLib?
Johannes Brodwall - Dec 7, 2010
Hei, Rune
Takk for kommentarer og for et godt eksempel. Har svart deg kort på /2010/10/26/cross-cutting-code/#comment-108269550
~Johannes
Rune Flobakk - Dec 11, 2010
First I create a dynamic subclass using CGLIB. But instead of using the static create-method on Enhancer, I new up an instance of Enhancer, sets callbacks, superclass, etc, then I call createClass() on the Enhancer instance, and let ObjenesisHelper.newInstance(proxyClass) do the actual instantiation of the class from Enhancer’s createClass().
This is in essence the same approach used by Mockito and LambdaJ, and is why you are able to mock classes without a default constructor :)
Johannes Brodwall - Dec 11, 2010
Nice internal description of CGLIB. I’ve limited my use to the static factory methods, but I realize there’s a lot of untapped potential here. Thank! :-)
Johannes Brodwall - Dec 11, 2010
Hei, Rune
Takk for bra beskrivelse av CGLIB på et nivå jeg ikke har utforsket det før. Her ser jeg at det er spennende ting å prøve.
Vet du forresten hvorfor CGLIB er så treg (synlig med store klasser) og om det er mulig å forbedre dette?
~Johannes