SpringAOP使用注解實現5種通知類型


spring aop的5種通知類型都有

Before前置通知

AfterReturning后置通知

Around環繞通知

AfterThrowing異常通知

After最終通知

首先創建接口和實現類 先測試后置通知

package com.aaa.spring.dao;



public interface UserService {

    public void insertUser();

    public void updateUser();

    public void deleteUser();

    public void find();
}
package com.aaa.spring.dao.umpl;

import com.aaa.spring.dao.UserService;
import com.aaa.spring.exception.MyException;
import org.springframework.stereotype.Component;

@Component(創建userServiceImpl bean)
public class UserServiceImpl implements UserService {
    @Override
    public void insertUser() {
        System.out.println("添加用戶");
    }

    @Override
    public void updateUser() {
        System.out.println("修改用戶");
    }

    @Override
    public void deleteUser() {
        System.out.println("刪除用戶");
    }

    @Override
    public void find() {
        System.out.println("查詢用戶");
    }
}

創建要在執行的方法前后的類

package com.aaa.spring.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;

@Component(獲取bean對象)
@Aspect(面向切面)
public class LogAdvice {
    @AfterReturning("execution(void *User(..))")(后置通知(切入點))
    public void log(JoinPoint jp){  (JoinPoint 連接點參數)
        String name=jp.getSignature().getName();(獲取攔截的方法名)
        System.out.println(name+"執行之后記錄成功");
    }
}

 

創建ApplicationContext文件

<?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"
> <context:component-scan base-package="com.aaa.spring"></context:component-scan>(掃描創建bean的包就是加@Component的類的所有包 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>(聲明以注解的方式配置spring aop) </beans>

創建測試類

package com.aaa.spring.text;

import com.aaa.spring.dao.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;



public class Text {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationcontext.xml");(獲取主配置文件)
        UserService bean = (UserService)context.getBean("userServiceImpl");(獲取實現類對象)
        bean.deleteUser();
        System.out.println("*****************************");
        bean.find();
        System.out.println("*****************************");
        bean.insertUser();
        System.out.println("*****************************");
        bean.updateUser();

    }
}

測試結果

五月 20, 2019 9:01:24 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@68de145: startup date [Mon May 20 21:01:24 CST 2019]; root of context hierarchy
五月 20, 2019 9:01:24 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationcontext.xml]
刪除用戶
deleteUser執行之后記錄成功
*****************************
查詢用戶
*****************************
添加用戶
insertUser執行之后記錄成功
*****************************
修改用戶
updateUser執行之后記錄成功

Process finished with exit code 0

前置通知

只需要在LogAdvice 類里邊再加方法

package com.aaa.spring.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;

@Component
@Aspect
public class LogAdvice {
    @AfterReturning("execution(void *User(..))")
    public void log(JoinPoint jp){
        String name=jp.getSignature().getName();
        System.out.println(name+"執行之后記錄成功");
    }
    @Before("execution(void *User(..))")
    public void befor(JoinPoint jp){
        String name=jp.getSignature().getName();
        System.out.println(name+"執行之前記錄成功");
    }
}

 

測試結果

五月 20, 2019 9:08:07 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@68de145: startup date [Mon May 20 21:08:07 CST 2019]; root of context hierarchy
五月 20, 2019 9:08:08 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationcontext.xml]
deleteUser執行之前記錄成功
刪除用戶
deleteUser執行之后記錄成功
*****************************
查詢用戶
*****************************
insertUser執行之前記錄成功
添加用戶
insertUser執行之后記錄成功
*****************************
updateUser執行之前記錄成功
修改用戶
updateUser執行之后記錄成功

Process finished with exit code 0

環繞通知

只需要在LogAdvice 類里邊再加方法

package com.aaa.spring.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;

@Component
@Aspect
public class LogAdvice {
    @AfterReturning("execution(void *User(..))")
    public void log(JoinPoint jp){
        String name=jp.getSignature().getName();
        System.out.println(name+"執行之后記錄成功");
    }
    @Before("execution(void *User(..))")
    public void befor(JoinPoint jp){
        String name=jp.getSignature().getName();
        System.out.println(name+"執行之前記錄成功");
    }
    @Around("execution(void *User(..))")
    public  void around(ProceedingJoinPoint pjp){
        String name=pjp.getSignature().getName();
        System.out.println(name+"環繞執行前");
        try {
            pjp.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println(name+"環繞后執行");
    }

}

測試結果

五月 20, 2019 9:10:12 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@68de145: startup date [Mon May 20 21:10:12 CST 2019]; root of context hierarchy
五月 20, 2019 9:10:12 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationcontext.xml]
deleteUser環繞執行前
deleteUser執行之前記錄成功
刪除用戶
deleteUser環繞后執行
deleteUser執行之后記錄成功
*****************************
查詢用戶
*****************************
insertUser環繞執行前
insertUser執行之前記錄成功
添加用戶
insertUser環繞后執行
insertUser執行之后記錄成功
*****************************
updateUser環繞執行前
updateUser執行之前記錄成功
修改用戶
updateUser環繞后執行
updateUser執行之后記錄成功

Process finished with exit code 0

最終通知

只需要在LogAdvice 類里邊再加方法

package com.aaa.spring.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;

@Component
@Aspect
public class LogAdvice {
    @AfterReturning("execution(void *User(..))")
    public void log(JoinPoint jp){
        String name=jp.getSignature().getName();
        System.out.println(name+"執行之后記錄成功");
    }
    @Before("execution(void *User(..))")
    public void befor(JoinPoint jp){
        String name=jp.getSignature().getName();
        System.out.println(name+"執行之前記錄成功");
    }
    @Around("execution(void *User(..))")
    public  void around(ProceedingJoinPoint pjp){
        String name=pjp.getSignature().getName();
        System.out.println(name+"環繞執行前");
        try {
            pjp.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println(name+"環繞后執行");
    }
    @After("execution(void *User(..))")
    public  void after(JoinPoint jp){
        String name=jp.getSignature().getName();
        System.out.println(name+"最終執行記錄成功");
    }

}

測試結果

五月 20, 2019 9:12:00 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@68de145: startup date [Mon May 20 21:12:00 CST 2019]; root of context hierarchy
五月 20, 2019 9:12:00 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationcontext.xml]
deleteUser環繞執行前
deleteUser執行之前記錄成功
刪除用戶
deleteUser環繞后執行
deleteUser最終執行記錄成功
deleteUser執行之后記錄成功
*****************************
查詢用戶
*****************************
insertUser環繞執行前
insertUser執行之前記錄成功
添加用戶
insertUser環繞后執行
insertUser最終執行記錄成功
insertUser執行之后記錄成功
*****************************
updateUser環繞執行前
updateUser執行之前記錄成功
修改用戶
updateUser環繞后執行
updateUser最終執行記錄成功
updateUser執行之后記錄成功

Process finished with exit code 0

異常通知,這里我們自定義一個異常

先創建一個異常類繼承RuntimeException程序異常

package com.aaa.spring.exception;

public class MyException extends  RuntimeException{
    public  MyException(String yc){
        super(yc);
    }
}

然后在LogAdvice  類里添加方法這里為了方便測試把上面的都加上了注釋

package com.aaa.spring.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ExceptionHandler;

@Component
@Aspect
public class LogAdvice {
   /* @AfterReturning("execution(void *User(..))")
    public void log(JoinPoint jp){
        String name=jp.getSignature().getName();
        System.out.println(name+"執行之后記錄成功");
    }
    @Before("execution(void *User(..))")
    public void befor(JoinPoint jp){
        String name=jp.getSignature().getName();
        System.out.println(name+"執行之前記錄成功");
    }
    @Around("execution(void *User(..))")
    public  void around(ProceedingJoinPoint pjp){
        String name=pjp.getSignature().getName();
        System.out.println(name+"環繞執行前");
        try {
            pjp.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println(name+"環繞后執行");
    }
    @After("execution(void *User(..))")
    public  void after(JoinPoint jp){
        String name=jp.getSignature().getName();
        System.out.println(name+"最終執行記錄成功");
    }*/
    @AfterThrowing(pointcut = "execution(void *User(..))")
    public  void excaption(JoinPoint jp){
        String name=jp.getSignature().getName();
        System.out.println("執行"+name+"時發生異常");
    }
}

然后在實現類里拋出異常

package com.aaa.spring.dao.umpl;

import com.aaa.spring.dao.UserService;
import com.aaa.spring.exception.MyException;
import org.springframework.stereotype.Component;

@Component
public class UserServiceImpl implements UserService {
    @Override
    public void insertUser() {
       if(true){
            throw new MyException("自定義異常");
        }
        System.out.println("添加用戶");
    }

    @Override
    public void updateUser() {
        System.out.println("修改用戶");
    }

    @Override
    public void deleteUser() {
        System.out.println("刪除用戶");
    }

    @Override
    public void find() {
        System.out.println("查詢用戶");
    }
}

測試結果

五月 20, 2019 9:18:57 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@68de145: startup date [Mon May 20 21:18:57 CST 2019]; root of context hierarchy
五月 20, 2019 9:18:57 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationcontext.xml]
刪除用戶
*****************************
查詢用戶
*****************************
執行insertUser時發生異常
Exception in thread "main" com.aaa.spring.exception.MyException: 自定義異常
    at com.aaa.spring.dao.umpl.UserServiceImpl.insertUser(UserServiceImpl.java:12)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
    at com.sun.proxy.$Proxy7.insertUser(Unknown Source)
    at com.aaa.spring.text.Text.main(Text.java:17)

Process finished with exit code 1

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM