Blogger templates

Your Ad Here

Video

Blogroll

Blogger news

AOP

Since 2003 there has been much interest in applying AOP solutions to those enterprise concerns, such as transaction management, which have traditionally been addressed by EJB.
The first goal of Spring's AOP support is to provide J2EE services to POJOs. Spring AOP is portable between application servers, so there's no risk of vendor lock in. It works in either web or EJB container, and has been used successfully in WebLogic, Tomcat, JBoss, Resin, Jetty, Orion and many other application servers and web containers.
Spring AOP supports method interception. Key AOP concepts supported include:
  • Interception: Custom behaviour can be inserted before or after method invocations against any interface or class. This is similar to "around advice" in AspectJ terminology.
  • Introduction: Specifying that an advice should cause an object to implement additional interfaces. This can amount to mixin inheritance.
  • Static and dynamic pointcuts: Specifying the points in program execution at which interception should take place. Static pointcuts concern method signatures; dynamic pointcuts may also consider method arguments at the point where they are evaluated. Pointcuts are defined separately from interceptors, enabling a standard interceptor to be applied in different applications and code contexts.
Spring supports both stateful (one instance per advised object) and stateless interceptors (one instance for all advice).
Spring does not support field interception. This is a deliberate design decision. I have always felt that field interception violates encapsulation. I prefer to think of AOP as complementing, rather than conflicting with, OOP. In five or ten years time we will probably have travelled a lot farther on the AOP learning curve and feel comfortable giving AOP a seat at the top table of application design. (At that point language-based solutions such as AspectJ may be far more attractive than they are today.)
Spring implements AOP using dynamic proxies (where an interface exists) or CGLIB byte code generation at runtime (which enables proxying of classes). Both these approaches work in any application server, or in a standalone environment.
Spring was the first AOP framework to implement the AOP Alliance interfaces (www.sourceforge.net/projects/aopalliance). These represent an attempt to define interfaces allowing interoperability of interceptors between AOP frameworks.
Spring integrates with AspectJ, providing the ability to seamlessly include AspectJ aspects into Spring applications . Since Spring 1.1 it has been possible to dependency inject AspectJ aspects using the Spring IoC container, just like any Java class. Thus AspectJ aspects can depend on any Spring-managed objects. The integration with the forthcoming AspectJ 5 release is still more exciting, with AspectJ set to provide the ability to dependency inject any POJO using Spring, based on an annotation-driven pointcut.
Because Spring advises objects at instance, rather than class loader, level, it is possible to use multiple instances of the same class with different advice, or use unadvised instances along with advised instances.
Perhaps the commonest use of Spring AOP is for declarative transaction management. This builds on the transaction abstraction described above, and can deliver declarative transaction management on any POJO. Depending on the transaction strategy, the underlying mechanism can be JTA, JDBC, Hibernate or any other API offering transaction management.
The following are the key differences from EJB CMT:
  • Transaction management can be applied to any POJO. We recommend that business objects implement interfaces, but this is a matter of good programming practice, and is not enforced by the framework.
  • Programmatic rollback can be achieved within a transactional POJO through using the Spring transaction API. We provide static methods for this, using ThreadLocal variables, so you don't need to propagate a context object such as an EJBContext to ensure rollback.
  • You can define rollback rules declaratively. Whereas EJB will not automatically roll back a transaction on an uncaught application exception (only on unchecked exceptions, other types of Throwable and "system" exceptions), application developers often want a transaction to roll back on any exception. Spring transaction management allows you to specify declaratively which exceptions and subclasses should cause automatic rollback. Default behaviour is as with EJB, but you can specify automatic rollback on checked, as well as unchecked exceptions. This has the important benefit of minimizing the need for programmatic rollback, which creates a dependence on the Spring transaction API (as EJB programmatic rollback does on the EJBContext).
  • Because the underlying Spring transaction abstraction supports savepoints if they are supported by the underlying transaction infrastructure, Spring's declarative transaction management can support nested transactions, in addition to the propagation modes specified by EJB CMT (which Spring supports with identical semantics to EJB). Thus, for example, if you have doing JDBC operations on Oracle, you can use declarative nested transactions using Spring.
  • Transaction management is not tied to JTA. As explained above, Spring transaction management can work with different transaction strategies.
It's also possible to use Spring AOP to implement application-specific aspects. Whether or not you choose to do this depends on your level of comfort with AOP concepts, rather than Spring's capabilities, but it can be very useful. Successful examples we've seen include:
  • Custom security interception, where the complexity of security checks required is beyond the capability of the standard J2EE security infrastructure. (Of course, before rolling your own security infrastructure, you should check the capabilities of Acegi Security for Spring, a powerful, flexible security framework that integrates with Spring using AOP, and reflects Spring's architectural approach.
  • Debugging and profiling aspects for use during development
  • Aspects that apply consistent exception handling policies in a single place
  • Interceptors that send emails to alert administrators or users of unusual scenarios
Application-specific aspects can be a powerful way of removing the need for boilerplate code across many methods.
Spring AOP integrates transparently with the Spring BeanFactory concept. Code obtaining an object from a Spring BeanFactory doesn't need to know whether or not it is advised. As with any object, the contract will be defined by the interfaces the object implements.
The following XML stanza illustrates how to define an AOP proxy:
<bean id="myTest"
       class="org.springframework.aop.framework.ProxyFactoryBean">
       <property name="proxyInterfaces">
              <value>org.springframework.beans.ITestBean</value>
       </property>
       <property name="interceptorNames">
             <list>
                   <value>txInterceptor</value>
                   <value>target</value>
            </list>
      </property>
</bean>
Note that the class of the bean definition is always the AOP framework's ProxyFactoryBean, although the type of the bean as used in references or returned by the BeanFactory getBean() method will depend on the proxy interfaces. (Multiple proxy methods are supported.) The "interceptorNames" property of the ProxyFactoryBean takes a list of String. (Bean names must be used rather than bean references, as new instances of stateful interceptors may need to be created if the proxy is a "prototype", rather than a singleton bean definition.) The names in this list can be interceptors or pointcuts (interceptors and information about when they should apply). The "target" value in the list above automatically creates an "invoker interceptor" wrapping the target object. It is the name of a bean in the factory that implements the proxy interface. The myTest bean in this example can be used like any other bean in the bean factory. For example, other objects can reference it via <ref> elements and these references will be set by Spring IoC.
There are a number of ways to set up proxying more concisely, if you don't need the full power of the AOP framework, such as using Java 5.0 annotations to drive transactional proxying without XML metadata, or the ability to use a single piece of XML to apply a consistent proxying strategy to many beans defined in a Spring factory.
It's also possible to construct AOP proxies programmatically without using a BeanFactory, although this is more rarely used:
TestBean target = new TestBean();
DebugInterceptor di = new DebugInterceptor();
MyInterceptor mi = new MyInterceptor();
ProxyFactory factory = new ProxyFactory(target);
factory.addInterceptor(0, di);
factory.addInterceptor(1, mi);
// An "invoker interceptor" is automatically added to wrap the target
ITestBean tb = (ITestBean) factory.getProxy();
We believe that it's generally best to externalize the wiring of applications from Java code, and AOP is no exception.
The use of AOP as an alternative to EJB (version 2 or above) for delivering enterprise services is growing in importance. Spring has successfully demonstrated the value proposition.


Next : MVC web framework
 

Most Reading

Stats