AOP通知消息

AOP通知

1、通知類型

  • 前置通知:方法執行前調用。
  • 後置通知:方法執行後調用,無論是否有異常,都會執行。
  • 返回通知:方法返回值返回前執行,如果有異常,無返回值,不會執行。
  • 異常通知:出現異常時候的通知。可以指定異常的具體子類型。
  • 環繞通知:類似代理整個過程的實現。一般不和其他幾種通知同時使用。

2、 示例

pom.xml

<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.mine</groupId>
	<artifactId>spring-study</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.3.RELEASE</version>
	</parent>

	<dependencies>
		<!-- SpringBoot整合Web組件 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>

		<!-- log -->
		<!-- log4j通過slf4j來代理 -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>log4j-over-slf4j</artifactId>
		</dependency>
		<!-- apache commons logging通過slf4j來代理 -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
		</dependency>
		<!-- java.util.logging 通過slf4j來代理 -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jul-to-slf4j</artifactId>
		</dependency>
		<!-- log -->
	</dependencies>
</project>

Caculator

package com.mine.aspectj.annotation.service;

public interface Caculator {
	public int add(int i, int j);
	public int sub(int i, int j);
	public int mul(int i, int j);
	public int div(int i, int j);
}

CaculatorImpl

package com.mine.aspectj.annotation.service.impl;

import org.springframework.stereotype.Service;

import com.mine.aspectj.annotation.service.Caculator;

@Service
public class CaculatorImpl implements Caculator {

	public int add(int i, int j) {
		return i + j;
	}

	public int sub(int i, int j) {
		return i - j;
	}

	public int mul(int i, int j) {
		return i * j;
	}

	public int div(int i, int j) {
		return i / j;
	}
}

LoggingAspect

package com.mine.aspectj.annotation.aspectj;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

@Component
@Aspect
@Slf4j
public class LoggingAspect {
	/**
	 * 聲明切入點表達式
	 */
	@Pointcut("execution(* com.mine.aspectj.annotation.service..*.*(..))")
	public void exec() {
		
	}
	

	/**
	 * 前置通知
	 */
	@Before("exec()")
	public void before(JoinPoint joinpoit) {
		String methodName = joinpoit.getSignature().getName();
		log.info("before " + methodName);
	}

	/**
	 * 後置通知
	 */
	@After("exec()")
	public void after(JoinPoint joinpoit) {
		String methodName = joinpoit.getSignature().getName();
		log.info("after " + methodName);
	}

	/**
	 * 返回通知
	 */
	@AfterReturning(value="exec()", returning="result")
	public void afterReturning(JoinPoint joinpoit, Object result) {
		String methodName = joinpoit.getSignature().getName();
		log.info(methodName + " method return :" + result);
	}

	/**
	 * 異常通知
	 */
	@AfterThrowing(value = "exec()",throwing = "ex")
	public void afterThrowing(JoinPoint joinpoit, ArithmeticException ex) {
		String methodName = joinpoit.getSignature().getName();
		log.info(methodName + " occur exception:" + ex);
	}


	/**
	 * 環繞通知
	 */
	@Around(value = "exec()")
	public Object around(ProceedingJoinPoint joinpoit) {
		String methodName = joinpoit.getSignature().getName();
		
		try {
			// 前置通知
			log.info("around 前置通知 " + methodName);
			
			// 執行方法
			Object[] args = joinpoit.getArgs();
			Object result = joinpoit.proceed(args);
			
			// 返回通知
			log.info("around 返回通知 " + methodName);
			return result;
		} catch (Throwable e) {
			// 異常通知
			log.error("around 異常通知 " + methodName);
			e.printStackTrace();
		} finally {
			// 後置通知
			log.info("around 後置通知 " + methodName);
		}
		
		return null;
	}
}

AspectController

package com.mine.aspectj.annotation.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.mine.aspectj.annotation.service.Caculator;

@RestController
@RequestMapping("/aspectj")
public class AspectController {
	@Autowired
	private Caculator caculator;

	@RequestMapping("/add")
	public int add(int i, int j) {
		int result = caculator.add(i, j);
		return result;
	}

	@RequestMapping("/sub")
	public int sub(int i, int j) {
		int result = caculator.sub(i, j);
		return result;
	}

	@RequestMapping("/mul")
	public int mul(int i, int j) {
		int result = caculator.mul(i, j);
		return result;
	}

	@RequestMapping("/div")
	public int div(int i, int j) {
		int result = caculator.div(i, j);
		return result;
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章