spring-aop notification example

Application of Spring AOP Notification

xml version

Create a new maven project
Project Structure Diagram

pom.xml file

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.spring</groupId>
    <artifactId>SpringAOP</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>


</project>

Create a new advice class to configure notifications

package com.spring.advice;

import org.aspectj.lang.ProceedingJoinPoint;

public class MyAdvice {

    public void before(){
        System.out.println("Before advice");
    }

    public void afterReturning(){
        System.out.println("Post notification");
    }

    public void afterThrowing(){
        System.out.println("Exception notification");
    }

    public void after(){
        System.out.println("Final notice");
    }

    /**
     * Around Advice
     * @param pjp Obtain the information of the target object and its method parameters, etc.
     * @return
     */
    public Object around(ProceedingJoinPoint pjp){
        Object obj = null;
        try {
            System.out.println("Around Advice--Before advice");
            //Get the parameters of the current execution method
            Object[] args = pjp.getArgs();
            //Release method
            obj = pjp.proceed(args);
            System.out.println("Around Advice--Post notification");
        }catch (Throwable t){
            t.printStackTrace();
            System.out.println("Around Advice--Exception notification");
        }finally {
            System.out.println("Around Advice--Final notice");
        }
        return obj;
    }

Create a service class

package com.spring.service;

public interface Service {
    public void findAll();

    public Integer save();

    public Integer update(Integer i);
}

Implementation class of service

package com.spring.service.impl;

import com.spring.service.Service;

public class ServiceImpl implements Service {
    @Override
    public void findAll() {
        //int i=1/0;
        System.out.println("query was successful");
    }

    @Override
    public Integer save() {
        System.out.println("Save successfully");
        return 1;
    }

    @Override
    public Integer update(Integer i) {
        System.out.println("Update success");
        return 1;
    }
}

Create a beans.xml file to configure entry points for notifications

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
			    http://www.springframework.org/schema/beans/spring-beans.xsd
			    http://www.springframework.org/schema/context
			    http://www.springframework.org/schema/context/spring-context.xsd
			    http://www.springframework.org/schema/aop
			    http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--Deliver the target object to ioc container-->
    <bean id="userService" class="com.spring.service.impl.ServiceImpl"/>
    <!--Deliver the notification object to ioc container-->
    <bean id="myAdvice" class="com.spring.advice.MyAdvice"/>
    <!--To configure aop:It can be configured with multiple facets.-->
    <aop:config>
        <!--Pointcut expression-->
        <aop:pointcut id="pointcut" expression="execution(* com.spring.service.impl.*.*(..))"/>
        <!--
            //A specific aspect configuration
            id Is the only identification of the current section
            ref Is to specify which notification to use for the current aspect
        -->
        <aop:aspect id="aspect" ref="myAdvice">
            <!--Before advice-->
            <!--Notification class myAdvice Medium before Method in UserServiceImpl.findAll Execution before execution-->
            <aop:before method="before" pointcut-ref="pointcut"/>
            <!--Post notification-->
            <aop:after-returning method="afterReturning" pointcut-ref="pointcut"/>
            <!--Exception notification-->
            <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut"/>
            <!--Final notice-->
            <aop:after method="after" pointcut-ref="pointcut"/>
            <!--Around Advice-->
            <!--<aop:around method="around" pointcut-ref="pointcut"/>-->
        </aop:aspect>
    </aop:config>

</beans>

Test class

package com.spring.test;

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:beans.xml")
public class Test {
    @Autowired
    private com.spring.service.Service service;

    @org.junit.Test
    public void test() {
        service.findAll();
        System.out.println();
    }
}

Test results:

Before advice
 query was successful
 Post notification
 Final notice

If you want to use surround notification, you need to annotate the pre-notification, post-notification, and final notification in beans.xml, and then open the annotation of surround notification.

Annotated edition

Project Structure Diagram

The pom.xml file is the same as the XML version
Class advice

package com.spring.advice;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class MyAdvice {

    @Pointcut("execution(* com.spring.service.impl.*.*(..))")
    public void pointcut(){};

    @Before("pointcut()")
    public void before(){
        System.out.println("Before advice");
    }

    @AfterReturning("pointcut()")
    public void afterReturning(){
        System.out.println("Post notification");
    }

    @AfterThrowing("pointcut()")
    public void afterThrowing(){
        System.out.println("Exception notification");
    }

    @After("pointcut()")
    public void after(){
        System.out.println("Final notice");
    }

    /**
     * Around Advice
     * @param pjp Obtain the information of the target object and its method parameters, etc.
     * @return
     */
//    @Around("execution(* com.spring.service.impl.*.*(..))")
    public Object around(ProceedingJoinPoint pjp){
        Object obj = null;
        try {
            System.out.println("Before advice");
            //Get the parameters of the current execution method
            Object[] args = pjp.getArgs();
            //Release method
            obj = pjp.proceed(args);
            System.out.println("Post notification");
        }catch (Throwable t){
            t.printStackTrace();
            System.out.println("Exception notification");
        }finally {
            System.out.println("Final notice");
        }
        return obj;
    }



}

Class service

package com.spring.service;

public interface Service {
    public void findAll();

    public Integer save();

    public Integer update(Integer i);
}

package com.spring.service.impl;

import com.spring.service.Service;

@org.springframework.stereotype.Service
public class ServiceImpl implements Service {
    @Override
    public void findAll() {
        //int i=1/0;
        System.out.println("query was successful");
    }

    @Override
    public Integer save() {
        System.out.println("Save successfully");
        return 1;
    }

    @Override
    public Integer update(Integer i) {
        System.out.println("Update success");
        return 1;
    }
}

Write a configuration class

package com.spring.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@ComponentScan("com.spring")
@EnableAspectJAutoProxy
public class SpringConfig {
}

Test class

package com.spring.test;

import com.spring.config.SpringConfig;
import com.spring.service.Service;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class Test {
    @Resource
    private Service service;
    @Test
    public void test() {
        service.findAll();
        System.out.println();
    }
}

Test results:

Before advice
 query was successful
 Final notice
 Post notification

Keywords: Spring xml Maven Junit

Added by ngolehung84 on Fri, 11 Oct 2019 22:45:17 +0300