Spring入门第二十一课

切面优先级

先看代码:

package logan.study.aop.impl;

public interface ArithmeticCalculator {

    int add(int i, int j);
    int sub(int i, int j);
    int mul(int i, int j);
    int div(int i, int j);

}
package logan.study.aop.impl;

import org.springframework.stereotype.Component;

@Component
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {

    @Override
    public int add(int i, int j) {
        // TODO Auto-generated method stub
        int result = i + j;
        return result;
    }

    @Override
    public int sub(int i, int j) {
        // TODO Auto-generated method stub
        int result = i - j;
        return result;
    }

    @Override
    public int mul(int i, int j) {
        // TODO Auto-generated method stub
        int result = i * j;
        return result;
    }

    @Override
    public int div(int i, int j) {
        // TODO Auto-generated method stub
        int result = i / j;
        return result;
    }

}
package logan.study.aop.impl;

import java.util.Arrays;
import java.util.List;

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.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

//把这个类声明为一个切面:需要把该类放入到IOC容器中,在声明为一个切面
@Order(2)
@Aspect
@Component
public class LoggingAspect {

    /**
     * 环绕通知需要携带ProceedingJoinPoint类型的参数
     * 环绕通知类似于动态代理的全过程:ProceedingJoinPoint类型的参数可以决定是否执行目标方法
     * 且环绕通知必须有返回值,返回值即为目标方法的返回值
     */

    @Around("execution(public int logan.study.aop.impl.ArithmeticCalculator.*(int, int))")
    public Object aroundMethod(ProceedingJoinPoint pjd){
        Object result = null;
        String methodName = pjd.getSignature().getName();
        //执行目标方法
        try{
            //前置通知
            System.out.println("The method" + methodName + " begins with " + Arrays.asList(pjd.getArgs()));

            result = pjd.proceed();
            //返回通知
            System.out.println("The method" + methodName + " ends with " + result);
        }catch(Throwable e){
            //异常通知
            System.out.println("The method occurs exception:" + e);

        }
        //后置通知
        System.out.println("The method " + methodName + "ends");
        return result;
    }

}
package logan.study.aop.impl;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
//可以
@Order(1)
@Aspect
@Component
public class VlidationAspect {
    @Before("execution(public int logan.study.aop.impl.ArithmeticCalculator.*(int, int))")
    public void validateArgs(JoinPoint joinPoint){
        System.out.println("validate: " + Arrays.asList(joinPoint.getArgs()));
    }

}
<?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-4.3.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">

    <context:component-scan base-package="logan.study.aop.impl"></context:component-scan>
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>
package logan.study.aop.impl;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //1.创建Spring的IOC容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.从IOC容器里面获取bean实例
        ArithmeticCalculator arithmeticCalculator = ctx.getBean(ArithmeticCalculator.class);
        //使用Bean
        int result = arithmeticCalculator.add(3, 6);
        System.out.println(result);

        result = arithmeticCalculator.div(3, 0);
        System.out.println(result);

    }

}

返回结果:

五月 28, 2017 7:03:16 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org[email protected]49c2faae: startup date [Sun May 28 07:03:16 CST 2017]; root of context hierarchy
五月 28, 2017 7:03:16 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
validate: [3, 6]
The methodadd begins with [3, 6]
The methodadd ends with 9
The method addends
9
validate: [3, 0]
The methoddiv begins with [3, 0]
The method occurs exception:java.lang.ArithmeticException: / by zero
The method divends
Exception in thread "main" org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public abstract int logan.study.aop.impl.ArithmeticCalculator.div(int,int)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:227)
    at com.sun.proxy.$Proxy9.div(Unknown Source)
    at logan.study.aop.impl.Main.main(Main.java:18)

可以看到我们这里有两个切面,但是哪个切面先执行?哪个切面后执行?

我们可以在切面上加@Order(1),这样来规定哪个先执行,哪个后执行,数字越小,优先级越高,越先执行。

时间: 2024-10-07 06:47:44

Spring入门第二十一课的相关文章

Spring入门第二十三课

我们看基于XML配置的方式配置AOP 看代码: package logan.study.aop.impl; public interface ArithmeticCalculator { int add(int i, int j); int sub(int i, int j); int mul(int i, int j); int div(int i, int j); } package logan.study.aop.impl; public class ArithmeticCalculato

Spring入门第二十课

返回通知,异常通知,环绕通知 看代码: package logan.study.aop.impl; public interface ArithmeticCalculator { int add(int i, int j); int sub(int i, int j); int mul(int i, int j); int div(int i, int j); } package logan.study.aop.impl; import org.springframework.stereotyp

Spring入门第二十七课

声明式事务 直接上代码: db.properties jdbc.user=root jdbc.password=logan123 jdbc.driverClass=com.mysql.jdbc.Driver jdbc.jdbcUrl=jdbc:mysql://localhost:3306/spring jdbc.initPoolSize=5 jdbc.maxPoolSize=10 applicationContext.xml <?xml version="1.0" encodin

Python第二十一课(反射/元类)

Python第二十一课(反射/元类)    >>>思维导图>>>中二青年 反射reflect 什么是反射, 其实是反省,自省的意思 反射指的是一个对象应该具备,可以检测,修改,增加自身属性的能力 反射就是通过字符串操作属性 涉及的四个函数,这四个函数就是普通的内置函数 没有双下划綫,与print等等没有区别 hasattr getattr setattr delattr p = Person("jack",18,"man") #

Spring入门第二课

看代码 package logan.spring.study; public class HelloWorld { private String name; public void setName2(String name){ System.out.println("setName: "+ name); this.name = name; } public void hello(){ System.out.println("hello: " + name); } p

Spring入门第二十二课

重用切面表达式 我们有的时候在切面里面有多个函数,大部分函数的切入点都是一样的,所以我们可以声明切入点表达式,来重用. package logan.study.aop.impl; public interface ArithmeticCalculator { int add(int i, int j); int sub(int i, int j); int mul(int i, int j); int div(int i, int j); } package logan.study.aop.im

Spring入门第二十四课

Spring对JDBC的支持 直接看代码: db.properties jdbc.user=root jdbc.password=logan123 jdbc.driverClass=com.mysql.jdbc.Driver jdbc.jdbcUrl=jdbc:mysql://localhost:3306/selective-courses-system jdbc.initPoolSize=5 jdbc.maxPoolSize=10 applicationContext.xml <?xml ve

Spring入门第二十五课

使用具名参数 直接看代码: db.properties jdbc.user=root jdbc.password=logan123 jdbc.driverClass=com.mysql.jdbc.Driver jdbc.jdbcUrl=jdbc:mysql://localhost:3306/selective-courses-system jdbc.initPoolSize=5 jdbc.maxPoolSize=10 applicationContext.xml <?xml version=&quo

Spring入门第二十九课

事务的隔离级别,回滚,只读,过期 当同一个应用程序或者不同应用程序中的多个事务在同一个数据集上并发执行时,可能会出现许多意外的问题. 并发事务所导致的问题可以分为下面三种类型: -脏读 -不可重复读 -幻读 看代码: db.properties jdbc.user=root jdbc.password=logan123 jdbc.driverClass=com.mysql.jdbc.Driver jdbc.jdbcUrl=jdbc:mysql://localhost:3306/spring jd