关于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)

posted @ 2019-04-19 17:57  人迹罕至的那条路  阅读(1946)  评论(0编辑  收藏  举报