Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


POJO-Based Solutions for LDAP Access: One Good, One Better : Page 3

Find out how to employ dependency injection, annotation, and aspect-oriented programming to enable POJO-based application development.


Solution 2. Enhanced with Annotation and AOP

Although the DAO interface requires only the property key and the property type as the two input parameters, the calling syntax is more complicated than necessary. You have to pass the data type in explicitly, which duplicates what is already in the getter return type. The construction of the array type key, coupled with the explicit type cast, also makes the calling syntax less clear. A much cleaner version based on Java 5 annotations is possible:

public class AnnotatedAccount { public void businessLogicUsingThreshold() { System.out.println("threshold = " + getThreshold()); // business logic using the threshold... } @PropertyKey( {"dc", "com", "dc", "my-domain", "cn", "app1", "cn", "threshold"}) long getThreshold() { return threshold; } void setThreshold(long value) { this.threshold = value; } private long threshold; }

The annotation represents the property key, while the getter's signature contains the data type. As long as the two values are made available to the DAO implementation at runtime, this new solution could reuse the same DAO while simplifying the client interface.

The AspectJ implementation of AOP can extract both the annotation value and the getter return type at runtime. Because the explicit key construction and the type cast are absent, the resulting client code is cleaner and can focus purely on its account-related business logic.

First, let's define the annotation that is to be consumed by an aspect:

@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface PropertyKey { /** * for properties stored in LDAP, the key is the array of Common Names * that represents the Distinguished Name, which need to match the * top-down hierarchical order of the CNs */ String[] value(); }

This annotation specifies the following:

  • The annotation is part of the public API of the annotated elements.
  • It is to be retained by the JVM, so it can be read reflectively at runtime.
  • It can be used to annotate only method declarations.
  • The String array specifies the ordered list of CNs that defines the DN.

Next, the PropertyAccess aspect extracts the key from the annotation and the return type from the method signature. It then passes them to the DAO:

aspect PropertyAccess { pointcut propertyGetter(PropertyKey key) : @annotation(key); Object around(PropertyKey key) : propertyGetter(key) { String returnType = ((MethodSignature)thisJoinPointStaticPart.getSignature()). getReturnType().getName(); return dao.getProperty( key.value(), PropertyType.fromString(returnType)); } public void setDao(PropertyDAO dao) { this.dao = dao; } private PropertyDAO dao; }

The aspect first defines the propertyGetter pointcut that captures the methods marked with the annotation and makes the annotation available to aspect advice methods at runtime. The around advice obtains the return type from the joinpoint context and the DN from the annotation values. It then passes them to the DAO to perform LDAP lookup. From the DAO onward, the program flow is the same as the Spring LDAP-enabled version of the solution.

The new Spring configuration file is very similar to the first version, except now it is the aspect that has a dependency on the DAO. Because of the strong integration between Spring and AspectJ, Spring can treat the aspect almost as a regular POJO:

<beans> <bean class="com.company.ldap.PropertyAccess" factory-method="aspectOf" lazy-init="false"> <property name="dao"> <bean class="com.company.ldap.LdapPropertyDAOImpl"> <property name="ldapTemplate"> <bean class="org.springframework.ldap.core.LdapTemplate"> <constructor-arg ref="contextSource"/> </bean> </property> </bean> </property> </bean> … </beans>

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.