關於AOP切面注解失效的老式解決辦法


1.AOP底層是基於反射的

   a)先來一個代理接口:

 1 ackage com.laola.arthimetic;
 2 
 3 import org.springframework.stereotype.Component;
 4 
 5 public interface Arthimetic { //這個接口就是用來接受代理對象的
 6     int add(int i,int j);
 7     int sub(int i,int j);
 8     int mul(int i,int j);
 9     int div(int i,int j);
10 }

    b) 實現類:

package com.laola.arthimetic;

import org.springframework.stereotype.Component;

@Component
public class ArthimeticImpl implements Arthimetic{ //實現此接口
    @Override
    public int add(int i, int j) {
        return i+j;
    }

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

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

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

2.日志消息類

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

import java.sql.SQLOutput;
import java.util.Arrays;
import java.util.List;
//注意這里的注解我是沒有用的
@Aspect
@Component
public class LogAspect {
     // 切面的before方法
    public  void logbefore(JoinPoint joinPoint){
       String name=joinPoint.getSignature().getName();
       List<Object> args= Arrays.asList(joinPoint.getArgs());
        System.out.println(name+"   begin"+args);
    }
     //切面的after方法
    public void logafter(JoinPoint joinPoint){
        String name=joinPoint.getSignature().getName();
        System.out.println(name+"   end");
    }
//切面的returing方法
public void logreturing(JoinPoint joinPoint,Object r){ String name=joinPoint.getSignature().getName(); System.out.println(name+" returing "+r); }
//切面的throwing方法
public void aftethrowing(JoinPoint joinPoint,Exception e) { String name=joinPoint.getSignature().getName(); System.out.println(name+" throwing "+e); } }

3.測試類

import com.laola.arthimetic.Arthimetic;
import com.laola.arthimetic.ArthimeticImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test {
    //雖然注解比較方便,但有時候jdk或者其他插件版本更新會有切面注解失效等問題的存在,為了省去找解決辦法的時間,還是使用bean配置文件
    public static void main(String[] args) {
        ApplicationContext ctx= new ClassPathXmlApplicationContext("beans.xml");
//接口代理 Arthimetic arthimetic
=(Arthimetic) ctx.getBean("arthimeticImpl"); int r=arthimetic.div(12,0); System.out.println(r); } }

4.beans.xml文件配置

<?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: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/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 "

                           >
<!--    1.注冊bean和切面-->
    <bean id="arthimeticImpl" class="com.laola.arthimetic.ArthimeticImpl"></bean>
    <bean id="logaspect" class="LogAspect"></bean>

<!--    2.開始配置-->
    <aop:config>
<!--     創建一個共有切入點,這樣就不用頻繁的使用 "execution(* com.laola.arthimetic.Arthimetic.*(..))"了  -->
        <aop:pointcut id="pointcut" expression="execution(* com.laola.arthimetic.Arthimetic.*(..))"/>
<!--     3.創建切面-->
        <aop:aspect ref="logaspect" order="1">
<!--      4.切面方式      -->
            <aop:before method="logbefore" pointcut-ref="pointcut"/>
            <aop:after method="logafter" pointcut-ref="pointcut" />
            <aop:after-returning method="logreturing" pointcut-ref="pointcut" returning="r"/>
            <aop:after-throwing method="aftethrowing" pointcut-ref="pointcut" throwing="e"/>
        </aop:aspect>
    </aop:config>
</beans>

這里面有些命名空間沒用到,沒啥影響。

5.總結

    a. 如果使用idea編寫Spring,有些包是沒有下載的,比如aspectj-weaver這個jar包,有時候采用注解方式會發現提示中沒有@Aspect以及它以下的子注解,所以這個包單獨下載或者從本地導入。

    b.  一般我們使用配置文件這種形式出錯率會少,雖然效率相對較慢,但若這種情況發生在idea上,不會是個大問題,因為它有很好的提示功能。

    c. 另外要注意切面的每個細節屬性,不然容易報錯。

    d. 為了減少多次service層的公有方法的代碼調用量,一般用pointcut來創建切入點,使用expression=execution(* com.laola.arthimetic.Arthimetic.*(..))"來完成公有方法的調用

    e. 另外遇到注解括號內有(name和value兩個屬性的二選一的,最好選擇value)


免責聲明!

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



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