Enterprise AOP - JUGSwsame as used for JPA (Java Persistence API) entity weaving wfor any supported...
Transcript of Enterprise AOP - JUGSwsame as used for JPA (Java Persistence API) entity weaving wfor any supported...
Enterprise AOPWith the Spring Framework
Jürgen HöllerVP & Distinguished Engineer,
Interface21
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 Frameworkw originally based on Rod Johnson’s book
“J2EE Design & Development” (Wiley, 2002)w popularized by "J2EE Development without EJB"
(Rod Johnson, Jürgen Höller; Wiley, 2004)
§ Focus on "Plain Old Java Objects" (POJOs)w natural component model for applications
§ Open Source Project on SourceForgew since February 2003w Apache licensew >40000 downloads per month
Spring Framework (2)
§ Business objects as decoupled POJOsw configuration and wiring through framework
• or usage as normal Java objects
w independent from the actual environment• no unnecessary ties to a framework
w reusable in any kind of environment• in particular: testability in unit / integration tests
§ Generic middleware servicesw e.g. declarative transactions for POJOs
• flexible alternative to EJB CMT
w for all applications, including standalone• leverage container services when available
Core Container (1)
§ "Inversion of Control"w configuration and lifecycle of application objectsw objects do not configure themselves, but get
configured from the outsidew objects don't know the origin of their
configuration
§ "Dependency Injection"w "setter-based" (JavaBean properties)w "constructor-based" (constructor arguments)w 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 configurationw representing the internal structure of the
application• references to other components• configuration parameters
w enables flexible configuration management• at fine-grained component level• switching between different deployment scenarios
§ XML bean definitionsw most common configuration formatw often: 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 Orientationw proxies for arbitrary POJOs
• no fixed component model
w flexible combination of interceptorsw instance-based AOP
§ Interceptors for Cross-Cutting Concernsw actions at beginning/end of method call
Target methodCaller
intercept
AOP Framework (2)
§ Do not repeat code: factor out interceptorw e.g. logging: configurable trace logw e.g. security: authorization checksw e.g. common exception handlingw e.g. transaction demarcation
§ Method interceptorw interceptor can be applied to any methodsw interceptor can be enabled/disabledw AOP Alliance: MethodInterceptor interfacew reuse of pre-built interceptors
AOP Framework (3)
§ Custom interceptor implementationsw rarely necessary, but straightforwardw usually delegate to target ("proceed")w 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 proxiesw build proxy for target object
• JDK dynamic proxy or CGLIB proxy
w build interceptor chain between proxyand target• according to AOP advice configuration
§ Hooks into Spring's core containerw FactoryBean or auto-proxy creatorw core container does not create proxies
itself!
ProxyFactoryShopFacadeImpl 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.SimpleTraceInterceptor"/>
<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 configurationw using <aop:*/> tags
§ Closer AspectJ integrationw pointcut expression languagew AspectJ-style aspects in Spring AOPw @AspectJ-style aspects in Spring AOP
• fully interoperable with ajc compiled aspects
§ @Configurablew 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:afterpointcut="execution(public void set*(*))"method="afterSetter"/>
</aop:aspect>
</aop:config>
AspectJ-style Aspects
@AspectJ-style Aspects@Aspectpublic 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 thebean definitions, and applies them to allother 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-basedand weaving-based AOPw choice of implementation strategiesw consistent programming modelw based on AspectJ
§ Typically: start with proxy-based AOPw seamlessly works in any kind of ClassLoader
environment§ Use AspectJ compile-time / load-time weaving
for more demanding needsw 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 demarcationw available since Spring 1.2
public class AccountService {
@Transactional(readOnly = true)public List<Account> findAccounts(...) {...
}
@Transactionalpublic 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?w We configured the aspect, but how does it kick in?
§ Option 1: compile-time weavingw AccountService class statically weaved using
the AspectJ compiler
§ Option 2: load-time weavingw on-the-fly weaving of classes when they get
loaded into a Spring application contextw driven by AspectJ's META-INF/aop.xmlw Spring 2.0: need to use AspectJ VM agent
What's Coming in Spring 2.1?
§ Support for Spring-driven AspectJ load-time weavingw through Spring's LoadTimeWeaver abstractionw same as used for JPA (Java Persistence API)
entity weavingw for any supported platform
• generic Spring VM agent, various application servers
§ "beanName" pointcut elementw in AspectJ-based pointcut expressions
• as a custom extension elementw 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 containerw proxy-based
• pre-built AOP Alliance MethodInterceptors• AspectJ-style and @AspectJ-style aspects• note: public, externally called methods only!
w weaving-based• standard AspectJ aspects• supports private, internally called methods too• however: requires weaving infrastructure
§ Typical usage: middleware aspectsw transaction managementw 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