AOP基本概念
- 横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等
- 切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。
- 通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。
- 目标(Target):被通知对象
- 代理(Proxy):向目标对象应用通知之后创建的对象
- 切入点(PointCut):切面通知 执行的 “地点”的定义
- 连接点(JointPoint):与切入点匹配的执行点
使用Spring实现AOP
目的:通过AOP插入前置日志类和后置日志类
依赖包导入
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
实现方式
通过Spring API实现
- 基础类
public interface UserService {
public void hello();
}
public class UserServiceImpl implements UserService{
public void hello() {
System.out.println("哈哈哈");
}
}
- 日志类
public class Log implements MethodBeforeAdvice {
/**
* 前置日志类
* @param method:要执行的目标对象的方法
* @param args:参数
* @param target: 目标对象
* @throws Throwable
*/
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");
}
}
public class AfterLog implements AfterReturningAdvice {
/**
* 后置日志类
* @param returnValue 返回值
* @param method 方法
* @param args 参数
* @param target 目标对象
* @throws Throwable
*/
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("使用了"+method.getName()+"方法,返回结果为:"+returnValue);
}
}
- 配置类 applicationContext.xml
“aop:pointcut”标签中"expression"的写法规则如下:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
ret-type-pattern,name-pattern(param-pattern)是必须的.
ret-type-pattern:标识方法的返回值,需要使用全路径的类名如java.lang.String,也可以为表示任何返回值;
name-pattern:指定方法名,代表所有,例如set,代表以set开头的所有方法.
param-pattern:指定方法参数(声明的类型),(…)代表所有参数,()代表一个参数,(*,String)代表第一个参数为任何值,第二个为String类型.
advisor标签是需要定义在aspect标签里面的,其作用与aspect类似,可以简单的把它理解为一个特殊的切面,用于把一个Advice和一个Pointcut组合起来
- advice-ref说明切别人的程序是什么,advice的英文翻译是“通知”,意思是主业务程序执行到某个方法之前之后发出的通知
- pointcut-ref说明被切的业务主程序是什么
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--注册bean-->
<bean id="userService" class="study.service.UserServiceImpl"/>
<bean id="log" class="study.log.Log"/>
<bean id="afterLog" class="study.log.AfterLog"/>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* study.service.UserServiceImpl.*(..))"/>
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
</beans>
测试
@Test
public void testAop(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = context.getBean("userService", UserService.class);
userService.add();
}