Spring AOP 理解
文章目录
AOP 的概述
Aop:aspect object programming 面向切面编程。让关注点代码与业务代码进行分离,对很多功能都有的重复代码进行抽取,再在运行时往业务方法上动态植入“切面类代码”。
public void add(User user) {
Factory factory = null;
MybatisUtils mybatisUtils = null;
try {
factory = user.getSession(); // 关注点代码
mybatisUtils = factory.getMybatisUtils(); // 关注点代码
mybatisUtils.insert(user); // 核心的业务代码
mybatisUtils.commit(); // 关注点代码
} catch (Exception e){
e.printStackTrace();
if (mybatisUtils != null) {
mybatisUtils.rollBack(); // 关注点代码
}
} finally {
factory.close();
mybatisUtils.close();
}
}
切面类:关注点代码形成的类。
切入点:执行目标对象方法,动态植入切面代码。可通过切面表达式指定拦截哪些方法,给指定的类在运行的时候植入切面类代码。
一、使用Spring AOP 开发
1. 引入pom 依赖
spring-aop、aopalliance、aspectjweaver、aspectjrt
2. bean.xml 中引入对应的命名空间,在xml 中开启 AOP
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="cc"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
3. 切面类
@Component
@Aspect
public class AOP {
// 里面的值为切入点表达式, 代表拦截包下哪些类哪些方法
@Before("execution(* cc.*.*(..))")
public void begin() {
System.out.println("切面开始...");
System.out.println("开始处理日志.........");
}
@After("execution(* cc.*.*(..))")
public void end() {
System.out.println("结束处理日志.........");
System.out.println("切面关闭...");
}
}
4. UserDao 实现类
@Repository
public class UserDao implements IUser{
@Override
public void save() {
System.out.println("UserDao : save 业务方法处理.........保存用户........");
}
}
// IUser 接口
public interface IUser {
void save();
}
5. AOP 接口对象切面测试(动态代理)
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("aopContext.xml");
System.out.println("IOC 容器创建完成");
IUser iUser = (IUser) ac.getBean("userDao");
iUser.save();
}
6. AOP 非接口对象切面测试(cglib 代理)
@Repository
// UserDao 类不实现 IUser 接口了
public class UserDao {
public void save() {
System.out.println("UserDao : save 业务方法处理.........保存用户........");
}
}
// 测试类中
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("aopContext.xml");
System.out.println("IOC 容器创建完成");
UserDao userDao = (UserDao) ac.getBean("userDao");
System.out.println(userDao.getClass());
userDao.save();
}
7. AOP 中的注解,拦截器路径
api:
- @Aspect 指定一个类为切面
- @Pointcut(“execution(* cn.itcast_aop_anno…(…))”) 指定切入点表达式,后续可直接使用该注解的方法作为切面方法
- @Before(“pointCut_()”) 前置通知,在目标方法执行之前执行
- @After(“pointCut_()”) 后置通知,在目标方法之后执行(始终执行)
- @AfterReturning(“pointCut_()”) 返回后通知,执行方法结束前执行(异常不执行)
- @AfterThrowing(“pointCut_()”) 异常通知,出现异常时执行
- @Around(“pointCut_()”) 环绕通知,环绕目标方法执行
execution 切入点表达式可定位到包、类、方法名、参数类型、返回值,具体使用参考 Spring面向切面编程(AOP-execution表达式)
总结
AOP 理解。