Spring Core
Spring Professional Certification
Spring Professional Certification
-
- 1 / 227
-
Lernkarten
Steps: How AOP works
- Implement mainline application logic
- write aspects to implement your cross-cuttin concerns
- weave aspects into application
Leading AOP Technologies
AspectJ
- original AOP technology
- offers more than Spring AOP
- uses byte code modification for aspect weaving
at compile time
Spring AOP
- java-based AOP framework
- especially and only for Spring Beans
- uses dynamic proxies for aspect weaving
at load time
4 Core AOP Concepts
- Join Point
= method call or
= field assignment
~ like rows in database (they just exist) - Pointcut
= where to apply advice
= expression that selects one or more Join Points
~ like sql statements, they select Join Points just as sql selects rows - Advice
= code to be executed at a Join Point that has been selected by a Pointcut
~ automatically called method - Aspect
= module that encapsulate pointcuts and advice
~ class-like concept
Implement the Aspect:
Log a message every time a property is about to change.
@Aspect
public class PropertyChangeTracker {
private Logger logger = Logger.getLogger(getClass());
@Before("execution(void set*(*))") = Advice
public void trackChange() {
logger.info("Property about to change.");
}
}
Configure the Aspect as a Bean
aspects-config.xml
<beans>
<aop:aspectj-autoproxy>
<aop:include name="propertyChangeTracker" />
</aop:aspectj-autoproxy>
<bean id="propertyChangeTracker"
class="example.PropertyChangeTracker" />
</beans>
Include the Aspect Configuration
application-config.xml
<beans>
<import resource="aspects-config.xml" />
<bean name="cache-A" class="example.Cache"/>
<bean name="cache-B" class="example.Cache"/>
</beans>
How Aspects are applied?
4 steps
- Spring creates a proxy that brings aspect and target together
- proxy implements business interface of target
- all calls routed through proxy
- matching advice is executed
AOP advice with context
context is provided by the JoinPoint method parameter
@Before("execution(void set*(*))")
public void trackChange(JoinPoint point) {
String name = point.getSignature().getName();
Object value = point.getArgs()[0];
logger.info(name + "about to change to " + value + " on "
+ point.getTarget());
}
INFO: setCacheSize about to change to 2500 on cache-A
writing pointcut expressions
method pattern
execution(<method pattern>)
[Modifiers or Annotations] ReturnType [ClassType] MethodName ([Arguments]) [throws ExceptionType]
NOTE: Only public methods will match!
execution(void send*(String))
any method starting with send that takes a single String parameter and has a void return type
execution(* send(*))
any method named send that takes a single parameter
execution(* send(int, ..))
any method named send whose first parameter is an int followed by zero or more parameters
.. = 0 or more parameters
execution(void example.MessageServiceImpl.*(..))
any visible void method in the MessageServiceImpl class
execution(void example.MessageService+.send(*))
any void method named send in any object of type MessageService (that include possible child classes or implementors of MessageService)
execution(@javax.annotation.security.RolesAllowed void send*(..))
any void method starting with send that is annotated with the @RolesAllowed annotation
execution(* rewards.*.restaurant.*.*(..))
there is one directory between rewards and restaurant
execution(* rewards..restaurant.*.*(..))
there may be several directories between rewards and restaurant
execution(* *..restaurant.*.*(..))
any sub-package called restaurant
5 advice types
- @Before
- @AfterReturning
- @AfterThrowing
- @After
- @Around
@Before("execution(void set*(*))")
public void trackChange() { ... }
trackChange() method is called before all setter methods with one method parameter and a void return type
NOTE: if advice throws an exception, target will not be called!
@AfterReturning(value="execution(* service..*.*(..)), returning="reward")
public void audit(JoinPoint jp, Reward reward) {
audit(reward.toString());
}
audit all operations in the service package that return a Reward object
NOTE: for void methods no returning attribute is needed
NOTE: advice is called only for successfully returning methods
NOTE: return value is included in JoinPoint object as well, but getting it there is bad style!
@AftherThrowing(value="execution(" "..Repository+(..))", throwing="e")
public void report(JoinPoint jp, DataAccessException e) {
mailService.emailFailure("...");
}
sends an email every time a Repository class throws an exception of type DataAccessException
NOTE: @AfterThrowing advice will not stop the exception form propagating but it can throw different type of exception!
@After("excecution(void update*(*))")
public void trackChange() { ... }
trackChange() method is called after all update methods with one method parameter and a void return type
NOTE: advice is called regardless of whether an exception has been thrown by the target or not
@Around("execution(@example.Cacheable * rewards.service..*.*(..))")
public Object cache(ProceedingJoinPoint point) throws Throwable {
Object value = cacheStore.get(cacheKey(point));
if(value == null) {
value = point.proceed();
cacheStore.put(cacheKey(point), value);
}
return value;
}
cache values returned by cacheable services
ProceedingJoinPoint (parameter) inherits from JoinPoint and adds the proceed() method
AOP: XML vs Annotation
Annotation syntax is Java 5+ only
XML syntax works on Java 1.4
=> aspect logic defined in Java (no annotations)
=> aspect configuration in XML (aop namespace)
<aop:config>
<aop:aspect ref="propertyChangeTracker">
<aop:before pointcut="execution(void set*(*))" method="trackChange" />
</aop:aspect>
</aop:config>
Spring Data Access:
advantages & features
- works consistently with leading data access technologies (JDBC, Hibernate, iBatis, ...)
- declarative transaction management (@Transactional)
- automatic connection management
- intelligent exception handling
Layered Application Architecture:
3 layers
- Service layer (or application layer)
= high-level application functions
= business logic - Data access layer
= interface to application's data repository - Infrastructure layer
= low-level services needed by the other layers
checked vs unchecked expections
checked exceptions
- force developers to handle errors
- intermediate methods must declare exception(s) from all methods below = BAD
unchecked exceptions
- can be thrown up the call hierarchy to the best place to handle it
- methods in between don't know about it = GOOD
Spring throws Runtime (unchecked) exceptions!
Spring Data Access Exceptions
Spring provides DataAccessException hierarchy
= hides whether you are using JPA, Hibernate, JDBC, ...
RuntimeException
=> DataAccessException
=> DataAccessResourceFailureException
=> CleanupFailureDataAccessException
=> OptimisticLockingFailureException
=> DataIntegrityViolationException
=> ...
jdbc Namespace:
characteristics & example
- introduced with Spring 3.0
- especially useful for testing
- supports H2, HSQL and Derby
<bean class="example.JdbcRepository">
<property name="dataSource" ref="dataSource" />
</bean>
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:schema.sql" />
<jdbc:script location="classpath:test-data.sql" />
</jdbc:embedded-database>
jdbc Namespace:
populating other database example
<bean id="dataSource" class="...">
<property name="url" value="${dataSource.url}" />
<property name="username" value="${...}" />
<property name="password" value="${...}" />
</bean>
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="classpath:schema.sql" />
<jdbc:script location="classpath:test-data.sql" />
</jdbc:initialize-database>
JdbcTemplate:
characteristics & advantages
- encapsulates a JDBC connection
- simplifies use of JDBC API
- provides full access to standard JDBC constructs
What handles JdbcTemplate?
6 steps
- acquisition of connection
- participation in transaction
- execution of statement
- processing of result set
- handling any exception
- release of connection
Creating a JdbcTemplate
JdbcTemplate template = new JdbcTemplate(dataSrc);
- requires a data source
- is thread safe after construction
=> create a template once and re-use it!
When to use JdbcTemplate?
Useful for implementing a repository also known as data access object (DAO) in a layered application.
Implementation of JDBC-based Repository (DAO)
public class JdbcRepository implements Repository
{
private JdbcTemplate template;
public JdbcRepository(DataSource dataSource) {
this.template = new JdbcTemplate(dataSource);
}
public int getCustomerCount() {
String sql = "select count(*) from customer";
return template.queryForInt(sql);
}
}
What JdbcTemplate can query for?
3 points
- simple java types (int, long, String, ...)
- generic maps
- domain objects
Query examples for simple java types
=> no bind variables
public int getPersonCount() {
String sql = "select count(*) from PERSON";
return jdbcTemplate.queryForInt(sql);
}
Query example for simple java type
=> with bind variable
public int getCountOfPersonsOlderThan(int age) {
return jdbcTemplate.queryForInt("select count(*) from PERSON where age > ?", age);
}
generic query: single row
queryForMap(..)
=> when expecting a single row
=> returns map of [Column Name | Field Value] pairs
Map {ID=1, FIRST_NAME="John", NAME="Smith"}