Enterprise AOP With the Spring Framework Jrgen Hller VP & - - PowerPoint PPT Presentation
Enterprise AOP With the Spring Framework Jrgen Hller VP & - - PowerPoint PPT Presentation
Enterprise AOP With the Spring Framework Jrgen Hller VP & Distinguished Engineer, Interface21 Agenda Spring Core Container Spring AOP Framework AOP in Spring 2.0 Example: Transaction Advice What's Coming in Spring
Agenda
Spring Core Container Spring AOP Framework AOP in Spring 2.0 Example: Transaction Advice What's Coming in Spring 2.1?
Spring Framework (1)
Java / J2EE Application Framework
- riginally based on Rod Johnson’s book
“J2EE Design & Development” (Wiley, 2002)
popularized by "J2EE Development without EJB"
(Rod Johnson, Jürgen Höller; Wiley, 2004)
Focus on "Plain Old Java Objects" (POJOs)
natural component model for applications
Open Source Project on SourceForge
since February 2003 Apache license >40000 downloads per month
Spring Framework (2)
Business objects as decoupled POJOs
configuration and wiring through framework
- or usage as normal Java objects
independent from the actual environment
- no unnecessary ties to a framework
reusable in any kind of environment
- in particular: testability in unit / integration tests
Generic middleware services
e.g. declarative transactions for POJOs
- flexible alternative to EJB CMT
for all applications, including standalone
- leverage container services when available
Core Container (1)
"Inversion of Control"
configuration and lifecycle of application objects
- bjects do not configure themselves, but get
configured from the outside
- bjects don't know the origin of their
configuration
"Dependency Injection"
"setter-based" (JavaBean properties) "constructor-based" (constructor arguments) alternative: "Service Lookup"
- for example: JNDI
Core Container (2)
public class ShopFacadeImpl implements ShopFacade { private OrderDao orderDao; private ItemDao itemDao; ... public void setOrderDao(OrderDao orderDao) { this.orderDao = orderDao; } public void setItemDao(ItemDao itemDao) { this.itemDao = itemDao; } ... public void insertOrder(Order order) { this.orderDao.insertOrder(order); this.itemDao.updateQuantity(order); } }
Core Container (3)
Fine-grained externalized configuration
representing the internal structure of the
application
- references to other components
- configuration parameters
enables flexible configuration management
- at fine-grained component level
- switching between different deployment scenarios
XML bean definitions
most common configuration format
- ften: separate admin properties file
- linked into XML bean definitions through placeholders
Core Container (4)
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${ jdbc.username}"/> <property name="password" value="${ jdbc.password}"/> </bean> <bean id="orderDao" class="com.myshop.dao.jdbc.JdbcOrderDao"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="petStore" class="com.myshop.service.ShopFacadeImpl"> <property name="orderDao" ref="orderDao"/> <property name="itemDao" ref="itemDao"/> </bean>
AOP Framework (1)
Proxy-based Aspect Orientation
proxies for arbitrary POJOs
- no fixed component model
flexible combination of interceptors instance-based AOP
Interceptors for Cross-Cutting Concerns
actions at beginning/end of method call
Target method Caller intercept
AOP Framework (2)
Do not repeat code: factor out interceptor
e.g. logging: configurable trace log e.g. security: authorization checks e.g. common exception handling e.g. transaction demarcation
Method interceptor
interceptor can be applied to any methods interceptor can be enabled/disabled AOP Alliance: MethodInterceptor interface reuse of pre-built interceptors
AOP Framework (3)
Custom interceptor implementations
rarely necessary, but straightforward usually delegate to target ("proceed") can also abort invocations
- for example: authorization interceptor
public class TestInterceptor implements MethodInterceptor { public Object invoke(MethodInvocation inv) throws Throwable { System.out.println("before invocation"); try { return inv.proceed(); } finally { System.out.println("after invocation"); } } }
AOP Framework (4)
AOP Framework = creation of proxies
build proxy for target object
- JDK dynamic proxy or CGLIB proxy
build interceptor chain between proxy
and target
- according to AOP advice configuration
Hooks into Spring's core container
FactoryBean or auto-proxy creator core container does not create proxies
itself!
ProxyFactory
ShopFacadeImpl facade = new ShopFacadeImpl(); facade.setOrderDao(...); ProxyFactory pf = new ProxyFactory(); pf.setTarget(facade); pf.addAdvice(new SimpleTraceInterceptor()); pf.addInterface(ShopFacade.class); ShopFacade proxy = (ShopFacade) pf.getProxy(); proxy.insertOrder(...); // Every call on the proxy will delegate to the target // but first go through the trace interceptor. ProxyFactory pf = new ProxyFactory(); pf.setTarget(facade); pf.addAdvice(new SimpleTraceInterceptor()); pf.setProxyTargetClass(true); ShopFacadeImpl proxy = (ShopFacadeImpl) pf.getProxy(); // Enforce CGLIB proxy that can be cast to the target class!
ProxyFactoryBean
<bean id="petStoreTarget" class="com.myshop.service.ShopFacadeImpl"> <property name="orderDao" ref="orderDao"/> <property name="itemDao" ref="itemDao"/> </bean> <bean id="traceInterceptor" class="org.springframework.aop.interceptor.SimpleTraceIntercepto r"/> <bean id="petStore" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="petStoreTarget"/> <property name="interceptorNames" value="traceInterceptor"> <property name="proxyInterfaces" value="com.myshop.service.ShopFacade"> </bean>
AOP in Spring 2.0
Simplified configuration
using <aop:*/> tags
Closer AspectJ integration
pointcut expression language AspectJ-style aspects in Spring AOP @AspectJ-style aspects in Spring AOP
- fully interoperable with ajc compiled aspects
@Configurable
dependency injection on domain objects
Simplified AOP Configuration
<aop:config> <aop:advisor id="getAgeAdvisor" pointcut="execution(* *..TestBean.getAge(..))" advice-ref="getAgeCounter"/> </aop:config> <bean id="getAgeCounter" class="...CountingBeforeAdvice"/>
public class JavaBeanPropertyMonitor { private int getterCount = 0; private int setterCount = 0; public void beforeGetter() { this.getterCount++; } public void afterSetter() { this.setterCount++; } }
AspectJ-style Aspects
<aop:config> <aop:aspect ref="javaBeanMonitor"> <aop:before pointcut="execution(public !void get*())" method="beforeGetter"/> <aop:after pointcut="execution(public void set*(*))" method="afterSetter"/> </aop:aspect> </aop:config>
AspectJ-style Aspects
@AspectJ-style Aspects
@Aspect public class AjLoggingAspect { @Pointcut("execution(* *..AccountService.*(..))") public void callsToAccountService(){} @Before("callsToAccountService()") public void before(JoinPoint jp) { System.out.println("Before " + jp.toShortString()); } @AfterReturning("callsToAccountService()") public void after() { System.out.println("After."); } }
@AspectJ-style Aspects
<!-- detects all @AspectJ aspects among the bean definitions, and applies them to all
- ther beans in the application context -->
<aop:aspectj-autoproxy/> <bean id="aspect" class="demo.AjLoggingAspect"/> <bean id="account" class="demo.AccountService"/>
@Configurable("accountBean") public class Account { private AccountService service; public void setAccountService(AccountService service) { this.service = service; } … } // Automatically injected on 'new'! Account acc = new Account(…); <aop:spring-configured/>
Configuration Aspect for Domain Objects
Spring 2.0: AOP Unification
Same programming model for proxy-based
and weaving-based AOP
choice of implementation strategies consistent programming model based on AspectJ
Typically: start with proxy-based AOP
seamlessly works in any kind of ClassLoader
environment
Use AspectJ compile-time / load-time weaving
for more demanding needs
with same configuration model
Using <tx:advice/>
<aop:config> <aop:advisor pointcut="execution(* *..AccountService.*(..))" advice-ref="txAdvice"/> </aop:config> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="find*" read-only="true"/> <tx:method name="save*"/> </tx:attributes> </tx:advice>
<bean id="txManager" class="org.springframework.transaction.jta. JtaTransactionManager"/>
@Transactional
Java 5 annotation for tx demarcation
available since Spring 1.2
public class AccountService { @Transactional(readOnly = true) public List<Account> findAccounts(...) { ... } @Transactional public void saveAccount(Account account) { ... } }
<tx:annotation-driven/>
<!-- automatically detects annotated beans --> <tx:annotation-driven transaction-manager="txManager"/> <bean id="txManager" class="org.springframework.transaction.jta. JtaTransactionManager"/> <!-- proxied: allowed to use @Transactional on public, externally called methods only --> <bean id="accountService" class="demo.AccountService"/>
AspectJ AnnotationTransactionAspect
<!-- configures AspectJ transaction aspect --> <bean id="txAspect" class="org.springframework.transaction.aspectj. AnnotationTransactionAspect" factory-method="aspectOf"> <property name="transactionManager" ref="txManager"/> </bean> <bean id="txManager" class="org.springframework.transaction.jta. JtaTransactionManager"/> <!– weaved: allowed to use @Transactional on any methods --> <bean id="accountService" class="demo.AccountService"/>
AspectJ Class Weaving
How does the AnnotationTransactionAspect on
the previous slide get applied?
We configured the aspect, but how does it kick in?
Option 1: compile-time weaving
AccountService class statically weaved using
the AspectJ compiler
Option 2: load-time weaving
- n-the-fly weaving of classes when they get
loaded into a Spring application context
driven by AspectJ's META-INF/aop.xml Spring 2.0: need to use AspectJ VM agent
What's Coming in Spring 2.1?
Support for Spring-driven AspectJ load-time
weaving
through Spring's LoadTimeWeaver abstraction same as used for JPA (Java Persistence API)
entity weaving
for any supported platform
- generic Spring VM agent, various application servers
"beanName" pointcut element
in AspectJ-based pointcut expressions
- as a custom extension element
matching specific beans by name rather than
by type
- leverage availability of named beans in Spring
Summary
Spring 2.0 offers broad AOP support,
integrated into its core container
proxy-based
- pre-built AOP Alliance MethodInterceptors
- AspectJ-style and @AspectJ-style aspects
- note: public, externally called methods only!
weaving-based
- standard AspectJ aspects
- supports private, internally called methods too
- however: requires weaving infrastructure
Typical usage: middleware aspects
transaction management statistics, event notification, etc
And of course...
… we'll be happy to assist you! ☺
Interface21 – Spring from the Source
Spring Training: e.g. 26.6.-29.6. Frankfurt
... or in-house
Quick Scan: How can Spring help you? Support contracts for Spring