Spring Core

Spring Professional Certification

Spring Professional Certification


Ursula Fernes
Diese Lernkarten bieten einen umfassenden Einblick in die Spring Core-Funktionen, insbesondere im Bereich der Konfiguration, JMS, RMI und JMX. Sie behandeln Themen wie die Konfiguration von MBeans, die Nutzung von JMS für asynchrone Nachrichtenverarbeitung und die Implementierung von Remote Services mit RMI. Entwickler, die Spring Core für die Erstellung robuster und skalierbarer Anwendungen nutzen möchten, profitieren von diesen Lernkarten, da sie praktische Beispiele und Best Practices für die Integration und Verwaltung von Services bereitstellen.
Cartes-fiches
227
Utilisateurs
2
Langue
Allemand
Catégorie
Informatique
Niveau
Autres
Créé / Mis à jour
21.10.2012 / 30.07.2016

Flashcards

Steps: How AOP works

  1. Implement mainline application logic
  2. write aspects to implement your cross-cuttin concerns
  3. 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

  1. Join Point
    = method call or
    = field assignment
    ~ like rows in database (they just exist)
  2. 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
  3. Advice
    = code to be executed at a Join Point that has been selected by a Pointcut
    ~ automatically called method
  4. 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

  1. Spring creates a proxy that brings aspect and target together
  2. proxy implements business interface of target
  3. all calls routed through proxy
  4. 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 

  1. @Before
  2. @AfterReturning
  3. @AfterThrowing
  4. @After
  5. @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

  1. Service layer (or application layer)
    = high-level application functions
    = business logic
  2. Data access layer
    = interface to application's data repository
  3. 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

  1. encapsulates a JDBC connection
  2. simplifies use of JDBC API
  3. provides full access to standard JDBC constructs

What handles JdbcTemplate?

6 steps

  1. acquisition of connection
  2. participation in transaction
  3. execution of statement
  4. processing of result set
  5. handling any exception
  6. 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

  1. simple java types (int, long, String, ...)
  2. generic maps
  3. 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"}

Étudier