1.什么是AOP
AOP 的全称是 Aspect Oriented Programming
,即面向切面编程,它将业务逻辑的各个部
分进行隔离,使开发人员在编写业务逻辑时可以专心于核心业务,从而提高了开发效率。
AOP 采取横向抽取机制,取代了传统纵向继承体系的重复性代码,其应用主要体现在
事务处理、日志管理、权限控制、异常处理等方面。
目前最流行的
AOP
技术有两个,分别为
Spring
框架的
AOP
和
AspectJ
框架。
2.什么是面向切面编程
把一个个的横切关注点放到某个模块中去,称之为切面。每个切面影响业务的一种功能,
切面的目的就是为了功能增强,将需要增强的方法做成切面,实现对业务的增强,就是面向
切面编程。
面向切面编程的目的:将与业务本身无关,却被业务模块所共同调用的功能代码封装成
切面,以减少系统的重复代码,降低耦合,提高可扩展性。
面向切面编程的优势:把多个方法前
/
后的共同代码抽离出来,使用动态代理机制来控
制,先执行抽离出来的代码,再执行每一个真实方法。
3.AOP 术语
Joinpoint
(连接点)
指那些被拦截到的点。是指应用在执行过程中能够插入切面的一个点
Pointcut
(切入点)
指要对哪些
Joinpoint
进行拦截,即被拦截的连接点
Advice
(通知)
指拦截到
Joinpoint
之后要做的事情,即对切入点增强的内容
Target
(目标)
指代理的目标对象
Weaving
(织入)
指把增强代码应用到目标上,生成代理对象的过程
Proxy
(代理)
指生成的代理对象
Aspect
(切面)
切入点和通知的结合
4.Spring AOP 模块中的通知类型
org.springframework.aop.MethodBeforeAdvice(前置通知)
在调用目标方法之前自动执行的通知称为前置通 知,可以应用于权限管理等功能。
org.springframework.aop.AfterReturningAdvice(后置通知)
在调用目标方法之后自动执行的通知称为后置通 知,可以应用于关闭流、上传文件、删除临时文件等功能。
org.aopalliance.intercept.MethodInterceptor(环绕通知)
在调用目标方法前后自动执行的通知称为环绕通 知,可以应用于日志、事务管理等功能。
org.springframework.aop.ThrowsAdvice(异常通知)
在方法抛出异常时自动执行的通知称为异常通知,可以应用于处理异常记录日志等功能。
注意
:
ThrowsAdvice
接口是一个标识接口没有任何抽象方法。如果通知类型定义为异常 通知,那么除了要实现 ThrowsAdvice
以外,还需要在切面中添加下面
4
个方法中的一个,并在该方法中实现具体的增强处理。
public void afterThrowing(Exception ex)
public void afterThrowing(RemoteException)
public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
public void afterThrowing(Method method, Object[] args, Object target, ServletException
ex)
5.创建切面
实现那些需要通知的接口
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;
import java.lang.reflect.Method;
public class MyAspect implements MethodBeforeAdvice, AfterReturningAdvice, MethodInterceptor, ThrowsAdvice {
/**
* 前置通知
*
* @param method 目标方法对象
* @param objects 目标方法的参数列表
* @param o 目标对象
* @throws Throwable
*/
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("Before...." + method.getName());
}
/**
* 后置通知
*
* @param o 目标方法的返回值
* @param method 目标方法对象
* @param objects 目标方法的参数列表
* @param o1 目标对象
* @throws Throwable
*/
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println("After...." + method.getName());
}
/**
* 环绕通知
*
* @param methodInvocation 目标方法对象
* @return
* @throws Throwable
*/
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("Around .....Before" + methodInvocation.getMethod().getName());
//执行目标方法
Object obj = methodInvocation.proceed();
System.out.println("Around.....After" + methodInvocation.getMethod().getName());
return obj;
}
/**
* 异常通知
*
* @param ex
*/
public void afterThrowing(Exception ex) {
System.out.println(ex + " Exception");
}
}
|
6.配置切面
Spring 的 AOP
模块实现
AOP 编程的方式:
使用
org.springframework.aop.framework.ProxyFactoryBean
工厂对象创建代理对象。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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"> <!--配置目标对象--> <bean id="usersService" class="com.service.impl.UsersServiceImpl"/> <!--配置切面对象--> <bean id="myAspect" class="com.aop.MyAspect"/> <bean id="toUppercaseAspect" class="com.aop.ToUppercaseAspect"/> <!--配置切面--> <bean id="usersServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 配置目标对象所实现的接口--> <property name="proxyInterfaces" value="com.bjsxt.service.UsersService"/> <!-- 配置目标对象--> <property name="target" ref="usersService"/> <!--配置切面对象--> <property name="interceptorNames"> <list> <value>myAspect</value> <value>toUppercaseAspect</value> </list> </property> <!--如何生成代理对象 true:使用CGLIB,false使用JDK的Proxy--> <property name="proxyTargetClass" value="true"/> </bean> </beans> |