Spring入门笔记之Aop
——2018年11月22日
Aop(Aspect Oriented Programming),即面向切面编程,可以说是对oop(Object Oriented Programming),即面向对象编程的补充和完善。Aop的存在就是让大量代码重复使用,将各个模块重用。
所谓“切面”,简单来说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
AOP核心概念
- 横切关注点
对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点。
- 切面(aspect)
类是对物体特征的抽象,切面就是对横切关注点的抽象
- 连接点(join point)
被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器.
4、切入点(pointcut)
对连接点进行拦截的定义
5、通知(advice)
所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类
6、目标对象
代理的目标对象
7、织入(weave)
将切面应用到目标对象并导致代理对象创建的过程
8、引入(introduction)
在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段.
代码了解阶段:
Spring AOP代理对象的生成
Xml配置方式:
- 把目标方法所有类和切面类放入ioc容器中。
- 配置<aop:config>
这里着重解释讲解第二种方式(注解)
步骤:
- spring框架中我们可以使用基于AspectJ注解来配置Aop(最主流)
简单理解就是,AspectJ就是一个支持AOP的第三方组件,Spring提供了很好的支持,首先需要引入Maven依赖。
- 在配置文件中声明 使用AspectJ注解
使AspectJ注解生效:
Util类:
package org.robert.util;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class Log {
/**
*声明此方法为了代码重用嘛
*/
@Pointcut("execution(* org.robert.Service.*.*(..))")
public void pointcut(){
}
/**
* 前置通知
* 进入方法就执行
*/
@Before(value = "pointcut()")
public void before(){
System.out.println("进来了");
}
/**
* 后置通知
* 业务执行完成通知
* 无论是否出异常就执行
*/
@After(value = "pointcut()")
public void after(){
System.out.println("干完了,要出去了");
}
/**
* 业务方法执行失败就不执行
* 返回通知
* 获取返回的值
// 声明该方法为返回通知:方法正常执行结束后执行的代码
// 返回 通知是可以访问到方法的返回值的!
/*切点表达式表示执行任意类的任意方法. 第
一个 * 代表匹配任意修饰符及任意返回值, 第二个 * 代表任意类的对象,
第三个 * 代表任意方法, 参数列表中的 .. 匹配任意数量的参数
*/
*/
@AfterReturning(value = "pointcut()",returning = "val")
public void success(Object val){
System.out.println("业务执行成功"+val);
}
/**
* 异常通知
* 出异常就执行
*/
@AfterThrowing(value = "pointcut()",throwing = "val")
public void testexception(Throwable val){
System.out.println("出异常啦"+val.getMessage());
}
/**
* 环绕通知
* 功能虽然强大,但用得少
*/
//@Around(value = "pointcut()")
public Object arroud(ProceedingJoinPoint pdj){
//前置
Object result = null;
try {
//执行目标方法
result = pdj.proceed();
} catch (Throwable e) {
//异常
e.printStackTrace();
}
//后置
return result;
}
}
Service类:
package org.robert.Service;
import org.robert.mapper.StudentMapper;
import org.springframework.stereotype.Service;
@Service
public class StudentService {
StudentMapper studentMapper;
public void testService() {
System.out.println(studentMapper);
}
public Integer insert(){
System.out.println("业务代码插入数据");
//System.out.println(2/0);
return 100;
}
public void delete(){
System.out.println("业务代码删除数据");
}
}