Agenda
Event Handling in Spring
Introduction to AOP
Writing Aspects
Pointcut and WildCard Expressions
Reusing pointcut definition
After advice
Around advice
Custom advice annotation
Understanding SpEL
Writing spring expression
Passing Objects to expressions
SpEL with Spring Bean (i) using systemProperties
(ii) Assigning values from property file
(iii) Collections with SpEL
(iv) Method factory wiring
(v) Static factory wiring
Spring Events
Built In Spring events
Publishing Spring Events
public class Dummy {
public void display() {
System.out.println("Display");
}
}
<bean id="dummy" class="com.spring.demo.Dummy"/>
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("config.xml");
ctx.start();
Dummy dummy = ctx.getBean("dummy", Dummy.class);
dummy.display();
ctx.stop();
Creating an Event Listener for Spring events
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
public class MyEventListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
System.out.println(event);
}
}
<bean class="com.spring.event.MyEventListener"/>
Capture a specific spring event
package com.spring.event;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent;
public class MyEventListener implements ApplicationListener<ContextStartedEvent> {
@Override
public void onApplicationEvent(ContextStartedEvent event) {
System.out.println(event);
}
}
Creating a custom Spring Event
import org.springframework.context.ApplicationEvent;
public class CustomEvent extends ApplicationEvent {
CustomEvent(Object object) {
super(object);
}
}
import com.spring.CustomEvent;
import org.springframework.context.ApplicationListener;
public class CustomEventListener implements ApplicationListener<CustomEvent> {
@Override
public void onApplicationEvent(CustomEvent event) {
System.out.println(event.getSource());
}
}
Create custom Event Listener
<bean class="com.spring.listener.CustomEventListener"/>
Introduce ApplicationEventPublisher
import com.spring.CustomEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
public class Dummy implements ApplicationEventPublisherAware {
ApplicationEventPublisher applicationEventPublisher;
void display() {
CustomEvent customEvent = new CustomEvent(this);
applicationEventPublisher.publishEvent(customEvent);
System.out.println("Display");
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
} }
Using event Listener annotation
import org.springframework.context.event.*;
public class MultipleEventListener {
@EventListener(ContextStartedEvent.class)
void start() {
System.out.println("----------------start");
}
@EventListener(ContextStoppedEvent.class)
void stopped() {
System.out.println("----------------stopped");
}
}
<context:annotation-config/>
Running spring event in separate Thread
<bean id="simpleAsyncTaskExecutor"
class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
<bean id="applicationEventMulticaster"
class="org.springframework.context.event.SimpleApplicationEventMulticaster">
<property name="taskExecutor" ref="simpleAsyncTaskExecutor"/>
</bean>
Advantages of Spring Events
Exercise 1
AOP (Aspect Oriented Programming)
AOP terminologies
AOP in action
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<aop:aspectj-autoproxy/>
</bean>
AOP in action (Cont.)
class Dummy{
public void display(){
System.out.println(“Dummy class display method“);
}}
<bean id="dummy" class="com.spring.demo.Dummy">
AOP in action (Cont.)
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MyAspect {
@Before("execution(public void display())")
void beforeAdvice() {
System.out.println("Before advice is running");
}
}
Wild Expressions for AOP
@Before("execution( void display())")
void beforeAdvice() {
System.out.println("Running before advice");
}
@Before("execution( * get*())")
void beforeAdvice() {
System.out.println("Running before advice");
}
@Before("execution( * com.spring.demo.Dummy.*())")
void beforeAdvice() {
System.out.println("Running before advice");
}
Wild Expressions for AOP (Cont.)
@Before("execution( * com.spring.demo.Dummy.*())")
void beforeAdvice() {
System.out.println("Running before advice");
}
@Before("execution(void *())")
void beforeAdvice() {
System.out.println("Running before advice");
}
@Before("execution(* *())")
void beforeAdvice() {
System.out.println("Running before advice");
}
Wild Expressions for AOP (Cont.)
@Before("execution(* *(..))")
void beforeAdvice() {
System.out.println("Running before advice");
}
Types of Advice
@Before("execution(void display())")
void beforeAdvice() {
System.out.println("Running before advice");
}
@AfterReturning(pointcut = "execution(Integer getInteger())", returning = "returnValue")
void afterReturningAdvice(Integer returnValue) {
System.out.println("Running AfterReturning " + returnValue);
}
@AfterThrowing(pointcut = "execution(void throwException())", throwing = "ex")
void afterReturningAdvice(Exception ex) {
System.out.println("Running AfterThrowing " + ex);
}
Types of Advice (Cont.)
@After("execution(void display())")
void afterAdvice(){
System.out.println("Running after advice");
}
@Around("execution(void display())")
void aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("Around before");
proceedingJoinPoint.proceed();
System.out.println("Around after");
}
Exercise 2
Pointcut Expressions
@Before("execution(void display())")
void beforeAdvice() {
System.out.println("Running before advice");
}
@Before("within(com.spring.demo.*)")
void beforeAdvice() {
System.out.println("Running before advice");
}
@Before("bean(dummy))")
void beforeAdvice() {
System.out.println("Running before advice");
}
Pointcut Expressions (Cont.)
@Before("args(Integer)")
void beforeAdvice() {
System.out.println("Running before advice");
}
@Before("this(com.spring.demo.Dummy)")
void beforeAdvice() {
System.out.println("Running before advice");
}
Reusing pointcut
@Before("dummyClassPointcut() || getStringPointcut()")
void beforeAdvice() {
System.out.println("Running before advice");
}
@After("displayPointcut()")
void afterAdvice(){
System.out.println("Running after advice");
}
@Pointcut("execution(void display())")
void displayPointcut(){}
@Pointcut("execution(String getString())")
void getStringPointcut(){}
Accessing JoinPoint in advice
@Before("execution(Integer getInteger(Integer))")
void beforeAdvice(JoinPoint joinPoint) {
System.out.println("Running before advice");
System.out.println(joinPoint);
System.out.println(joinPoint.getThis());
System.out.println(joinPoint.getSignature());
Object [] objects=joinPoint.getArgs();
for (Object object:objects){
System.out.println(object);
}
}
Exercise 3
Use cases of AOP
What is SpEL ?
Spel expressions can be used with XML or annotation based configurations for defining Bean Definations. In both the cases the syntax to define the expression is of the form #{<expressions>}
Where we can use SpEL ?
Writing a spring expression
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
public class SpelDemo {
public static void main(String[] args) {
ExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression("'hello'");
System.out.println(expression.getValue());
}
}
What all can we do inside Spring expression?
ExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression("1");
System.out.println(expression.getValue());
ExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression("{1,2,{3,4},5,6}");
System.out.println(expression.getValue());
ExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression("{framework:'Spring',version:4}");
System.out.println(expression.getValue());
ExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression("new int[]{1,2,3,4}");
System.out.println(expression.getValue());
ExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression("'hello'.toUpperCase()");
System.out.println(expression.getValue());
ExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression("2==2");
System.out.println(expression.getValue());
ExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression("true and false");
System.out.println(expression.getValue());
expression = expressionParser.parseExpression("1+1");
System.out.println(expression.getValue());
Passing Object to the expression
import com.spring.demo.Employee;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class SpelDemo {
public static void main(String[] args) {
Employee employee = new Employee("Dummy Employee", 26);
StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext(employee);
ExpressionParser expressionParser = new SpelExpressionParser();
Expression expression = expressionParser.parseExpression("name");
System.out.println(expression.getValue(standardEvaluationContext));
}
}
import com.spring.demo.Employee;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class SpelDemo {
public static void main(String[] args) {
StandardEvaluationContext context = new StandardEvaluationContext();
ExpressionParser expressionParser=new SpelExpressionParser();
Expression expression = expressionParser.parseExpression("(#a * #b)+#c");
context.setVariable("a", 2);
context.setVariable("b", 4);
context.setVariable("c", 1);
System.out.println(expression.getValue(context));
}
}
Exercise 4
Spel with Spring Beans
import org.springframework.beans.factory.annotation.Value;
import java.util.List;
import java.util.Map;
public class SpelBean {
@Value("#{'SpEL'}")
String name;
@Value("#{23}")
Integer age;
@Value("#{{1,2,3,4}}")
List list;
@Value("#{{a:1,b:2,c:3}}")
Map map;
// getters of all instance variables
}
<bean id="spelBean2" class="com.spring.demo.SpelBean">
<property name="age" value="#{23}"/>
<property name="name" value="#{'config bean'}"/>
<property name="list" value="#{{9,8,7,6}}"/>
<property name="map" value="#{{a:1,b:2}}"/>
</bean>
@Value("#{systemProperties['user.country']}")
String country;
Note: In order to use systemProperties you need to place this line in spring configuration file.
<context:annotation-config/>
Getting value from a file and placing it in the instance variable of a bean
valueFromFile=Delhi
<context:property-placeholder location="classpath:application.properties"/>
@Value("${valueFromFile}")
String state;
Exercise 5
Using Operators with Spring Beans
public class PersonalisedService {
Integer age;
Integer incrementedAge;
Boolean isAgeGreaterThan10;
Integer firstElementOfList;
Integer mapValue;
// generate getters and setters
}
<bean id="personalisedService" class="com.spring.demo.PersonalisedService">
<property name="age" value="#{spelBean.age}"/>
<property name="incrementedAge" value="#{spelBean.age + 1}"/>
<property name="isAgeGreaterThan10" value="#{spelBean.age>10}"/>
<property name="firstElementOfList" value="#{spelBean.list[0]}"/>
<property name="mapValue" value="#{spelBean.map[a]}"/>
</bean>
Static Method wiring
@Value("#{T(com.spring.demo.EmployeeService).getEmployeeViaStaticMethod()}")
Employee employee;
Method Factory Wiring
@Value("#{employeeService.getEmployeeViaInstanceMethod()}")
Employee employee;
Exercise 6