欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring AOP (面向切面编程)

程序员文章站 2022-06-04 22:06:23
...

主要用于事务控制、权限检查、日志…等

分类(按修改的时机):

静态AOP实现:AOP框架在编译阶段即实现对目标类的修改(增强),生成静态的AOP代理类(生成*.class文件已经被改掉了,需要使用特定的编辑器)。以AspectJ(需要安装 java -jar aspectj-1.9.2.jar,并添加环境变量和CLASSPATH(aspectjrt.jar、aspectjtools.jar))为代表。

动态AOP实现:AOP框架在运行阶段动态生成AOP代理(在内存中动态地生成AOP代理类:JDK动态代理、cglib、javassist),以实现对目标对象的增强。以Spring AOP为代表。

静态AOP性能更好,动态AOP更方便。

AOP相关概念:

切面(Aspect):业务流程运行的某个特定步骤,也就是应用运行过程的关注点。关注点可能横切多个对象,所以常常也称为横切关注点。

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

增强处理(Advice):AOP框架在特定的切入点执行的增强动作。处理有“around”、“before”和“after”等类型。

切入点(Pointcut):可以插入增强处理的连接点。简而言之,当某个连接点满足指定要求时,该连接点将被添加增强处理,该连接点也就变成了切入点。

引入(Introduction):为被修改的类添加方法或成员变量。Spring允许引入新的接口到任何被处理的对象。例如,你可以使用一个引入,使任何对象实现IsModified接口,以此来简化缓存。

目标对象:被AOP框架进行增强处理的对象,也被成为被增强对象。如果AOP框架是通过运行时代理来实现的,那这个对象僵尸一个被代理的对象。

AOP代理:AOP框架创建的对象,简单地说,代理就是对目标对象的加强。Spring中的AOP代理可以是JDK的动态代理,也可以是CGLIB代理。前者为实现接口的目标对象的代理,后者为不实现接口的目标对象的代理。

织入(Weaving):将增强处理添加到目标对象中、并创建一个被增强的对象(AOP代理)的过程就是织入。织入有两种实现方式:编译时增强(例如AspectJ)和运行时增强(例如CGLIB)。Spring和其他船Java AOP框架一样,在运行时完成织入。

AOP配置:

定义Aspect:(3种方式)

注解、XML配置、将class改成aspect

定义Advice:(3种方式)

注解、XML配置、将方法签名改成特殊语法(例如:before():execution(* com.lwy.service.*.*(..)))

  • XML配置实例:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:c="http://www.springframework.org/schema/c"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	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="musicService" class="com.lwy.service.MusicService" />
	<bean id="authAspect" class="com.lwy.aspect.AuthAspect" />
	<aop:config>
		<!-- 将指定的Bean转成Aspect切面 -->
		<aop:aspect ref="authAspect">
			<!-- 将auth方法转换成Before的Advice -->
			<!-- 将Advice放到目标方法的指定位置 pointcut或pointcut-ref -->
			<aop:before method="auth" pointcut="execution(* com.lwy.service.*.*(..))" />
		</aop:aspect>
	</aop:config>
</beans>
  • 注解配置实例:

用注解时需要注意两点:

  1. 需要添加<aop:aspectj-autoproxy />元素
  2. 强制Spring去处理@Aspect的注解
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:c="http://www.springframework.org/schema/c"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	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">
	<context:component-scan base-package="com.lwy">
		<!-- 告诉Spring去处理Aspect注解 -->
		<context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect" />
	</context:component-scan>
	<aop:aspectj-autoproxy />
</beans>
package com.lwy.aspect;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class AuthAspect {
	@Before(value="execution(* com.lwy.service.*.*(..))")
	public void auth() {
		System.out.println("模拟权限验证");
	}
}
package com.lwy.service;
import org.springframework.stereotype.Component;
@Component
public class MusicService {
	public void listenMusicService() {
		System.out.println("模拟听音乐服务");
	}
}

 

相关标签: Spring