Going back to the times when I was playing computer games one of my favorites was Diablo 2. To my shame I’ve been sitting for it days and nights for almost 2 months. The second my favorite was C++, though I was far not as good in it as in Blizzard’s blockbuster.
A decade later not much has changed. Two things I’d be happy to see in late 2010 are Diablo 3 and Java 7 (and the both will unlikely appear).
One of the most anticipated features of Java 7 is “closures” (which are not fully defined yet). It was always hard to survive without them in Java world. Lack of closures has given birth to a huge number of best practices, patterns, workarounds and really bad code. The only elegant alternative before cheerful future of a new mighty Java has come is AOP.
AOP allows developers play with Plain Old Java Objects and Services non-intrusively, pulling away logging, monitoring, caching and other aspects that doesn’t depend on a specific context and domain. AOP can help you following modern best coding practices (like Single Level of Abstraction and Composite Method (see “Productive Programmer” by Neal Ford)) and make your architecture transparent.
Assume you’ve developed a business application that blindly implements business requirements, and at the end of the day you 1. don’t have much time to implement utility services 2. afraid to add complexity to the design. Spending just several hours with AOP you will achieve those goals, and moreover make your application look trendy.
Monitoring (performance tracking)
Monitoring is the simplest aspect you can start with. In terms of the simplified SCA described previously, I prefer to monitor methods of the flow (those methods are the highest level of the backend API that encapsulates calls to the service infrastructure and are directly called from the “controller” level).
With a very small code in XML to declare around aspects/endpoints and straightforward code of the aspects you can achieve the following:
- Monitor calls to the methods (track start/end of the method execution and time to execute). In the legacy applications this code looked just awful – you had to put logging in the beginning/end of every method to be monitored. With aspects you keep the generic (horizontal) functionalities away from the business logic.
- Agent/system performance analysis. Making the aspect a bit more intellectual (so that it can tie calls to the agent sessions, distinguish services, etc.) and storing history of calls in the database you can build a huge number of charts that can be used not only for analyzing system performance and revealing bottlenecks, but also for analyzing the ways users interact with the system.
Caching
Caching logics without aspects has the same crucial impact on the code. Variety of calls is preceded with the same blocks of code to check/update the cache over and over again.
Leveraging around/before aspects you can plug any caching engine to your system non-intrusively. I argue strongly for EhCache as cache of choice – it’s the best freeware caching engine on the market. The benefits are:
- If you’re not replicating/clustering your cache, using EhCache not much harder than using a simple Map;
- You can declaratively configure in-memory/disk cache ratio, TTL and TTI policy, and much more;
- Health of the server (cache misses, number of element in cache, etc.) can be easily monitored with JMX (via JConsole or other monitor);
- EhCache Server is shipped with Glassfish, can be started in one click and has REST/WS-* endpoints;
- EhCache is integrated with Terracota (the most promising feature for me);
Properly ordering caching and monitoring aspects you can track the cache performance and fine-tune it.
Bean validation
I bet, JSR-303 that has already been implemented by Hibernate and Spring (and will be implemented in Java 7), is going to be a de-facto standard in the industry soon. It delivers the same vision of the validation at all levels of the application and saves from a burden of writing rule-checking code (in particular, null-checking and exception throwing code). You’re just calling validatior.validate(bean), and that’s it.
With Bean Validation enabled, every single bean is aware of its own constraints (contract), so validation process is fairly generic and can be moved to the aspect.