The object graph mapper of Spring Data Graph relies heavily on AspectJ. AspectJ is the Java implementation of the Aspect Oriented Programming paradigm that allows easy extraction and controlled application of so called cross cutting concerns. Cross cutting concerns are repetitive tasks in a system (e.g. logging, security, auditing, caching, transaction scoping) that are difficult to extract using the normal OO paradigms. The means of the OO paradigm, of subclassing, polymorphism, overriding and delegation are still very cumbersome to use with many of those concerns applied in the codebase. Also the flexibility is limited or would add quite a number of configuration options or parameters.
The learning curve for the AspectJ pointcut language is quite slow but the developer who uses Spring Data Graph will not be confronted with that. Users do not have care about to hooking into a framework mechanism or having to extend a framework superclass.
That's why AspectJ uses a declarative approach, defining concrete advice, which is just the piece of code that contains the implementation of the concern. AspectJ advice can for instance be applied before, after, or instead of a method or constructor call, or variable access. This is declared using AspectJ's expressive pointcut language that is able to express any place within a code structure or flow. AspectJ is also able to introduce new methods, fields, annotations, interfaces, and superclasses to existing classes.
Spring Data Graph uses both mechanisms internally. First, when encountering @NodeEntity
or
@RelationshipEntity
annotations it introduces a new interface NodeBacked
or
RelationshipBacked
, depending on the annotation type. Secondly, it introduces fields and methods
to the annotated class. See Section 18.8, “Methods added to entity classes” for more
information on the methods introduced.
Spring Data Graph also leverages AspectJ to intercept access to fields, delegating the calls to the graph database instead. Under the hood, properties and relationships will be created.
So how is an aspect applied to a concrete class? This can be either done at compile time with the AspectJ Java compiler (ajc) that takes source files and aspect definitions, and then compiles the source files while adding all the necessary interception code for the aspects to hook in where they're declared to. This is known as compile-time weaving. At runtime only a small AspectJ runtime is needed, as the bytecode of the classes has already been rewritten to delegate appropriate calls via the declared advice in the aspects.
AspectJ also supports other types of weaving, for example load-time weaving and runtime weaving. These are currently not supported by Spring Data Graph.