Spring AOP入门使用详解

Spring AOP入门使用详解AOP入门详解

大家好,又见面了,我是你们的朋友全栈君。

1.maven 依赖:

 <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--aop-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>

2.接口和实现定义

接口定义:

package com.aop.api;

/**
 * Created by zhangzh on 2016/8/5.
 */
public interface Service {
    public void save(String info);
}

接口实现:

package com.aop.impl;

import com.aop.api.Service;

/**
 * Created by zhangzh on 2016/8/5.
 */
public class ServiceImpl implements Service {
    public void save(String info) {
        System.out.println("save info:" + info);
    }
}

 

3.采用before和after方式进行切面操作:

切面类 

package com.aop.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

/**
 * Created by zhangzh on 2016/8/5.
 */
public class aspect {

    public void before(JoinPoint call) {

        String className = call.getTarget().getClass().getName();
        String methodName = call.getSignature().getName();
       Object[] args = call.getArgs();
        for(Object obj:args) {
            if(obj instanceof String) {
                System.out.println(methodName +"的执行参数为:" + obj);
            }
        }

        System.out.println("前置通知:" + className + "类的" + methodName + "开始执行了......");

    } 
    public void after() {
        System.out.println("最终通知:不管方法有没有正常执行完成,一定会返回的");
    }
}

aopContext.xml配置:

  

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="service" class="com.aop.impl.ServiceImpl"/>
    <bean id="aspect" class="com.aop.aspect.aspect"/>

    <aop:config>
        <aop:aspect id="logAspect" ref="aspect">
            <aop:pointcut id="allMethod" expression="execution(* com.aop.api.Service.*(..))"/>
            <aop:before method="before" pointcut-ref="allMethod"/>
            <aop:after method="after" pointcut-ref="allMethod"/>
            <!--<aop:after-throwing method="afterThrowing" pointcut-ref="allMethod"/>-->
            <!--<aop:around method="doAround" pointcut-ref="allMethod"/>-->
        </aop:aspect>
    </aop:config>


</beans>

test类:

import com.aop.api.Service;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by zhangzh on 2016/8/5.
 */
public class AopTest {

    public static void main(String[] args) {

        ApplicationContext ac = new ClassPathXmlApplicationContext("META-INF/aopContext.xml");

        Service service = ac.getBean("service",Service.class); 
        service.save("### 1232536 #########");



    }
}

输出结果:

save的执行参数为:### 1232536 #########
前置通知:com.aop.impl.ServiceImpl类的save开始执行了......
save info:### 1232536 #########
最终通知:不管方法有没有正常执行完成,一定会返回的

4. 采用环绕aop配置:

切面类:

package com.aop.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

/**
 * Created by zhangzh on 2016/8/5.
 */
public class aspect {

    public void before(JoinPoint call) {

        String className = call.getTarget().getClass().getName();
        String methodName = call.getSignature().getName();
       Object[] args = call.getArgs();
        for(Object obj:args) {
            if(obj instanceof String) {
                System.out.println(methodName +"的执行参数为:" + obj);
            }
        }

        System.out.println("前置通知:" + className + "类的" + methodName + "开始执行了......");

    }

    public void afterReturn() {
        System.out.println("后置通知:方法正常结束了");
    }

    public void after() {
        System.out.println("最终通知:不管方法有没有正常执行完成,一定会返回的");
    }

    public void afterThrowing() {
        System.out.println("异常抛出后通知:方法执行时出异常了");
    }

    //用来做环绕通知的方法可以第一个参数定义为org.aspectj.lang.ProceedingJoinPoint类型
    public Object doAround(ProceedingJoinPoint call) throws Throwable {
        Object result = null;
        this.before(call);//相当于前置通知
        try {
            result = call.proceed();
            this.afterReturn(); //相当于后置通知
        } catch (Throwable e) {
            this.afterThrowing();  //相当于异常抛出后通知
            throw e;
        } finally {
            this.after();  //相当于最终通知
        }
        return result;
    }

}

aopContext.xml配置:

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="service" class="com.aop.impl.ServiceImpl"/>
    <bean id="aspect" class="com.aop.aspect.aspect"/>

    <aop:config>
        <aop:aspect id="logAspect" ref="aspect">
            <aop:pointcut id="allMethod" expression="execution(* com.aop.api.Service.*(..))"/>
            <!--<aop:before method="before" pointcut-ref="allMethod"/>-->
            <!--<aop:after method="after" pointcut-ref="allMethod"/>-->
            <!--<aop:after-throwing method="afterThrowing" pointcut-ref="allMethod"/>-->
            <aop:around method="doAround" pointcut-ref="allMethod"/>
        </aop:aspect>
    </aop:config>


</beans>

test类:

import com.aop.api.Service;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by zhangzh on 2016/8/5.
 */
public class AopTest {

    public static void main(String[] args) {

        ApplicationContext ac = new ClassPathXmlApplicationContext("META-INF/aopContext.xml");

        Service service = ac.getBean("service",Service.class); 
        service.save("### 1232536 #########");



    }
}

输出结果:

save的执行参数为:### 1232536 #########
前置通知:com.aop.impl.ServiceImpl类的save开始执行了......
save info:### 1232536 #########
后置通知:方法正常结束了
最终通知:不管方法有没有正常执行完成,一定会返回的

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/149583.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 图像传感器的 DVP 信号

    图像传感器的 DVP 信号一、DVP简述DVP是数字视频端口(digitalvideoport)的简称,传统的sensor输出接口,采用并行输出方式,DVP总线PCLK极限约在96M左右,所有DVP最大速率最好控制在72M以下,DVP是并口,需要PCLK、VSYNC、HSYNC、D[0:11]——可以是8/10/12bit数据,具体情况要看ISP或baseband是否支持。DVP接口在信号完整性方面受限制,速率也受限制。如图1所示,并口传输数据需要帧同步信号(Vsync

    2022年5月27日
    33
  • QQ邮箱开启SMTP服务的步骤

    QQ邮箱开启SMTP服务的步骤

    2021年9月21日
    96
  • eclipse中怎么自动补全_空格键坏了

    eclipse中怎么自动补全_空格键坏了eclipse自动补全及其空格键优化(去除空格自动补全)使用eclipse在创建其他工作区间的时候,想要配置代码自动补全,因为老是忘记,每次都要从网上查找,于是就自己总结一下。选1是代码自动补全,只需将“.”换为“.qwertyuiopasdfghjklzxcvbnm”就行了,看起来很乱,其实还是有规律可循的。(只需将键盘上的26字母按从左到右,从上到下的顺序按一遍就行了。)选2是空格不会自动补全,因为按空格会自动补全,所以有时候特别烦,而网上的大多数解决方法是需要改代码的,就会显得特别麻烦。于是

    2022年8月31日
    6
  • executorservice线程池建立_线程池 threadlocal

    executorservice线程池建立_线程池 threadlocalExecutorService建立多线程的步骤:1。定义线程类classHandlerimplementsRunnable{}2。建立ExecutorService线程池ExecutorServiceexecutorService=Executors.newCachedThreadPool();或者intc

    2025年10月23日
    3
  • Java开发经典实战!java编程培训学校排名

    Java开发经典实战!java编程培训学校排名GC概述垃圾收集(GarbageCollection)通常被称为“GC”,由虚拟机“自动化”完成垃圾回收工作。思考一个问题,既然GC会自动回收,开发人员为什么要学习GC和内存分配呢?为了能够配置上面的参数配置?参数配置又是为了什么?“当需要排查各种内存溢出,内存泄露问题时,当垃圾成为系统达到更高并发量的瓶颈时,我们就需要对GC的自动回收实施必要的监控和调节。”JVM中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生随线程而灭。栈帧随着方法的进入和退出做入栈和出栈操作,实现了自动的内存清理。它们的

    2022年7月7日
    32
  • listagg 函数[通俗易懂]

    listagg 函数[通俗易懂]listagg函数–oracle11grelease2转载:http://xpchild.blog.163.com/blog/static/10180985920108485721969/本文描述了在oracle11grelease2版本中新增的listagg函数,listagg是一个实现字符串聚合的oracle内建函数。作为一种普遍的技术,网络上也有多种实现字符串聚合的方…

    2025年9月29日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号