Spring 学习(七):AOP简介及Schema-base实现前置和后置通知

本文详细介绍了Spring AOP的概念,包括面向切面编程的原理、执行流程和编程实践。重点讲解了如何使用Schema-based配置实现方法执行的前置和后置通知,通过示例展示了在`demo2`方法执行前后插入通知的完整流程。内容涵盖AOP在权限校验、日志记录、性能监控和事务控制等场景的应用。
摘要由CSDN通过智能技术生成

一、 AOP概述

1.1 什么是AOP?

AOP(Aspect Oriented Programing)面向切面编程。

AOP采取横向抽取机制,取代了传统的继承纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)

Spring的AOP采用了纯Java实现,不需要专门的编译过程和类加载器,在运行期间通过动态代理的方式向目标类注入增强代码。

1.2 AOP应用场景说明

  • 权限校验
  • 日志记录
  • 性能监控
  • 事务控制.

二、AOP 执行流程

正常程序执行流程都是纵向执行流程

demo1
demo2
demo3

AOP采取横向抽取机制,在demo2执行期间执行 前置通知–>demo2–>后置通知

前置通知
demo2
后置通知

三、AOP编程

  • 又叫面向切面编程,在原有纵向执行流程中添加横切面。
  • 不需要修改原有程序代码
    • 高扩展性
    • 原有功能相当于释放了部分逻辑,让主程序(demo2)职责更加明确

面向切面编程是什么?

  1. 在程序原有纵向执行流程中,对某一个或某一些方法添加通知,形成横切面的过程。
  2. 常用概念
    1. 切点:原有功能 pointcut
    2. 前置通知:在切点之前执行的功能 before advice
    3. 后置通知:在切点之后执行的功能 after acvice
    4. 异常通知:如果切点执行过程中发现异常会触发异常通知 throws advice
    5. 切面:所有功能总称
    6. 织入:把切面嵌入原有功能的过程

四、Schema-base实现前置和后置通知

applicationContext.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:tx="http://www.springframework.org/schema/tx"
    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/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd"
        default-autowire="byName">
        
        <!-- 注入通知类 -->
        <bean id="myBefore" class="com.zhang.advice.MyBefore"></bean>
        <bean id="myAfter" class="com.zhang.advice.MyAfter"></bean>
        
        <aop:config>
        	<!-- 
        		aop:pointcut : 定义切点  
        		expression: 通用配置: execution(* 形成切面的某一个人或者某一些方法,如有参数在方法里添加 .. )
        		id: 形成的切点 id
        	 -->
        	<aop:pointcut expression="execution(* com.zhang.pojo.Demo.demo2(..))" id="mypoint"/>
        	
        	<!-- 
        		aop:advisor: 通知
        		
        		advice-ref: 通知类 bean 的 id
        		
        		pointcut-ref: 切点id
        		
        	 -->
        	
        	<aop:advisor advice-ref="myBefore" pointcut-ref="mypoint"/>
        	<aop:advisor advice-ref="myAfter" pointcut-ref="mypoint"/>
        </aop:config>
        
       <bean id="demo" class="com.zhang.pojo.Demo"></bean>
</beans>

前置通知 myBefore 内容如下:

package com.zhang.advice;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;


public class MyBefore implements MethodBeforeAdvice{

	
	/*
	 *  1.实现MethodBeforeAdvice接口下的 before方法
	 *  2.参数列表
	 *  	2.1 Method arg0 : 指明是哪个方法形成了切面
	 *  	2.2 Object[] arg1 : 形成切面方法的参数列表
	 *  	2.3 Object arg2 : 形成切面方法的类对象
	 *  
	 */
	
	@Override
	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
		
		System.out.println("======================");
		System.out.println("前置通知");
		System.out.println(arg0);
		if(arg1.length != 0) {
			System.out.println(arg1[0]);
		}
		System.out.println(arg2);
		System.out.println("======================");
	}
}

后置通知 myAfter 内容如下:

package com.zhang.advice;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

public class MyAfter implements AfterReturningAdvice{

	
	/*
	 *  1.实现AfterReturningAdvice接口下的 afterReturning方法
	 *  2.参数列表
	 *  	2.1 Object arg0 : 返回的类对象
	 *  	2.2 Method arg1 : 指明是哪个方法形成了切面
	 *  	2.3 Object[] arg2 : 形成切面方法的参数列表
	 *  	2.4 Object arg3 : 形成切面方法的类对象
	 *  
	 */
	
	@Override
	public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
		System.out.println("======================");
		System.out.println("后置通知");
		System.out.println(arg0);
		System.out.println(arg1);
		if(arg2.length != 0) {
			System.out.println(arg2[0]);
		}
		System.out.println(arg3);
		System.out.println("======================");
	}

}

Test测试类如下:

package com.zhang.test;

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

import com.zhang.pojo.Demo;

public class Test {

	public static void main(String[] args) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		Demo demo = applicationContext.getBean("demo",Demo.class);
		
		demo.demo1();
		
		demo.demo2("Mark");
		
		demo.demo3();
	}
}

执行Test测试类,其结果如下:
在这里插入图片描述
其结果说明在执行 demo2 的方法的时候,形成了切面,并且执行了前后通知。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值