Spring Aop

小编 2026-07-07 阅读:1584 评论:0
Spring Aop:面向切面编程 Spring Aop是Spring框架的一个核心技术点,那么使用Aop有什么好处呢?如下图 从图中可以看到,在以往我们处理业务逻辑的时候总是会去执行一些非业务性的...

Spring Aop:面向切面编程

Spring Aop是Spring框架的一个核心技术点,那么使用Aop有什么好处呢?如下图

\"\"

从图中可以看到,在以往我们处理业务逻辑的时候总是会去执行一些非业务性的代码,这样会使我们编写的代码业务逻辑非常混乱,

那么有了Aop之后,我们可以将业务逻辑中的非去,单独业务性代码(比如事务处理)移除出开设为一个模块(这是第一个好处,重复代码被移除出去独立为一个模块,减少代码的冗余),这样业务逻辑中就只剩下业务性的代码,使业务逻辑变得更加清晰(这是第二个好处)

有人就会问,如果我这个业务逻辑必须提交事务,而提交事务的代码又被移除了,那么如何提交事务?

这里就可以提出面向切面编程的思想了,什么是面向切面编程?简单理解就是我移除后的代码独立为一个模块,那么在我业务逻辑需要的时候,我们可以根据切点将代码切入到要用的地方,比如我们一般执行完业务逻辑要进行事务提交,那么我可以将提交事务的代码切入到该业务逻辑之后执行(第三个好处,因为代码独立,降低与业务逻辑的耦合,方便我们维护)

 

基础术语:

连接点(Joinpoint):程序执行过程中明确的点,如方法的调用,或者异常的抛出.

目标(Target):被通知(被代理)的对象
注1:完成具体的业务逻辑

通知(Advice):在某个特定的连接点上执行的动作,同时Advice也是程序代码的具体实现,例如一个实现日志记录的代码(通知有些书上也称为处理)
注2:完成切面编程

代理(Proxy):将通知应用到目标对象后创建的对象(代理=目标+通知),
             例子:外科医生+护士
注3:只有代理对象才有AOP功能,而AOP的代码是写在通知的方法里面的

切入点(Pointcut):多个连接点的集合,定义了通知应该应用到那些连接点。
                 (也将Pointcut理解成一个条件 ,此条件决定了容器在什么情况下将通知和目标组合成代理返回给外部程序)
    
适配器(Advisor):适配器=通知(Advice)+切入点(Pointcut)

如何实现AOP
目标对象只负责业务逻辑代码
通知对象负责AOP代码,这二个对象都没有AOP的功能,只有代理对象才有

 

通知:

前置通知:

package com.study.advice;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.springframework.aop.MethodBeforeAdvice;

public class MyMethodBeforeAdvice implements MethodBeforeAdvice {

	public void before(Method method, Object[] args, Object target) throws Throwable {
		// TODO Auto-generated method stub
		String targetName = target.getClass().getName();
		String methodName = method.getName();
		String params = Arrays.toString(args);
		String msg = \"{系统日志}:正在调用->\"+targetName+\".\"+methodName+\",携带的参数:\"+params;
		System.out.println(msg);
	}

}

后置通知:

package com.study.advice;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.springframework.aop.AfterReturningAdvice;

public class MyAfterReturningAdvice implements AfterReturningAdvice {

	public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
		// TODO Auto-generated method stub
		String targetName = target.getClass().getName();
		String methodName = method.getName();
		String params = Arrays.toString(args);
		String msg = \"{返利通知,返利三元}:正在调用->\"+targetName+\".\"+methodName+\",携带的参数:\"+params+\",方法返回值:\"+returnValue;
		System.out.println(msg);
	}

}

环绕通知:

package com.study.advice;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.aopalliance.intercept.MethodInvocation;

public class MethodInterceptor implements org.aopalliance.intercept.MethodInterceptor {

	public Object invoke(MethodInvocation invocation) throws Throwable {
		Object target = invocation.getThis();
		Method method = invocation.getMethod();
		Object[] args = invocation.getArguments();
		
		String targetName = invocation.getClass().getName();
		String methodName = method.getName();
		String params = Arrays.toString(args);
		
		String msg1 = \"{环绕通知}:正在调用->\"+targetName+\".\"+methodName+\",携带的参数:\"+params;
		System.out.println(msg1);
		Object returnValue = invocation.proceed();
		String msg2 = \"方法返回值:\"+returnValue;
		System.out.println(msg2);
		return returnValue;
	}

}

异常通知:

先声明异常:

package com.study.exception;

public class PriceException extends RuntimeException {

	public PriceException() {
		super();
	}

	public PriceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
	}

	public PriceException(String message, Throwable cause) {
		super(message, cause);
	}

	public PriceException(String message) {
		super(message);
	}

	public PriceException(Throwable cause) {
		super(cause);
	}
	
}
package com.study.advice;

import org.springframework.aop.ThrowsAdvice;

import com.study.exception.PriceException;

public class MyThrowsAdvice implements ThrowsAdvice {
	public void afterThrowing( PriceException ex ) {
		System.out.println(\"价格输出有误,购买失败,请重新输入\");
	}
}

过滤通知:

<bean class=\"org.springframework.aop.support.RegexpMethodPointcutAdvisor\" id=\"myRegexpMethodPointcutAdvisor\">
	<!-- <property name=\"pattern\" value=\".*buy\"></property> -->
	<property name=\"advice\" ref=\"myAfterReturningAdvice\"></property>
	<!-- .*buy:[.*]任意字符0-n个,以buy结尾的方法 -->
	<property name=\"patterns\">
		<list>
			<value>.*buy</value>
		</list>
	</property>
</bean>

 

配置:

<!-- 目标对象 -->
<bean class=\"com.study.biz.impl.BookBizImpl\" id=\"bookBizImpl\"></bean>

<!-- 前置通知 -->
<bean class=\"com.study.advice.MyMethodBeforeAdvice\" id=\"myMethodBeforeAdvice\"></bean>
<bean class=\"com.study.advice.MyAfterReturningAdvice\" id=\"myAfterReturningAdvice\"></bean>
<bean class=\"com.study.advice.MethodInterceptor\" id=\"myMethodInterceptor\"></bean>
<bean class=\"com.study.advice.MyThrowsAdvice\" id=\"myThrowsAdvice\"></bean>
<bean class=\"org.springframework.aop.support.RegexpMethodPointcutAdvisor\" id=\"myRegexpMethodPointcutAdvisor\">
	<!-- <property name=\"pattern\" value=\".*buy\"></property> -->
	<property name=\"advice\" ref=\"myAfterReturningAdvice\"></property>
	<!-- .*buy:[.*]任意字符0-n个,以buy结尾的方法 -->
	<property name=\"patterns\">
		<list>
			<value>.*buy</value>
		</list>
	</property>
</bean>

<!-- 生成代理 -->
<bean class=\"org.springframework.aop.framework.ProxyFactoryBean\" id=\"proxyFactoryBean\">
	<property name=\"target\" ref=\"bookBizImpl\"></property>
	<property name=\"proxyInterfaces\" value=\"com.study.biz.BookBiz\"></property>
	<property name=\"interceptorNames\">
		<list>
			<value>myMethodBeforeAdvice</value>
			<!-- <value>myAfterReturningAdvice</value> -->
			<value>myRegexpMethodPointcutAdvisor</value>
			<value>myMethodInterceptor</value>
			<value>myThrowsAdvice</value>
		</list>
	</property>
</bean>

 

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

上一篇:主题模型LDA 下一篇:Docker 特点
热门文章
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
标签列表