笔记目录
Spring 学习之路–SpringAOP学习笔记
Spring AOP
一、 什么是AOP
1 定义
面向切面编程,通过预编译的方式和运行期间动态代理实现程序功能的 统一维护的一种技术,是面向对象的补充
2 特点
AOP横向的抽取 OOP 纵向的继承
3 场景
事务,日志
4 好处
解耦,不用过多的关注于其他业务逻辑的实现
二 、AOP的术语
1 Aspect 切面 (含有增强功能的类)
2 JoinPoint 连接点 (可以被增强的地方)
3 poingCut 切入点 (增强的地方)
4 advice 通知/增强 (切面类里的方法)
5 target 目标类
6 Porxy 代理类 (目标类被增强以后,生成的对象)
7 Weaving 织入 (把增强方法放入到切入点的过程,也可以理解为生成对立对象 的过程)
三 、动态代理
1 jdk的动态代理(基于接口)
步骤
1.1 接口和目标类
1.2 切面类(含有增强方法)
1.3 代理类(织入)
proxy.newProxyInstance()
2 cglib的动态代理
把目标对象,当作父类,生成新的代理对象
步骤
2.1 目标对象
2.2 切面类(含有增强方法)
2.3 代理类(织入)
核心方法:增强器 Enhancer,
四 、Spring的通知类型
1 前置
2 后置
3 环绕
4 异常
5 引介
五、 ProxyFactoryBean
理解: 在spring的容器离,配置了目标类,切面类(经过了处理,方法拦截器),和生成代理对象的proyxFactroyBean
六、 AspectJ 编程
1 XML
<aop:config> 配置标签
<aop:pointcut id="" expression="" /> 全局切点表达式 名称和规则
<aop:aspect id="" ref=""> 切面类配置
<aop:before method="" pointcut-ref=""/>
</aop:aspect>
</aop:config>
ctrl+p 可以查看方法里的参数类型
七 案例实现(AspectJ开发)
1.创建一个Web项目
导入 Spring框架所需JAR包到项目的lib目录中,并发布到类路径下。
所需jar包路径:
2.创建接口 IUserDao
在src目录下,创建一个 com. soft. xml 包,在该包下创建接口 IUserDao,并在该接口中编写添加的方法
package com.soft.xml;
public interface IUserDao {
public void addUser();
}
3.创建接口的实现类 UserDaolmpl
在 com. soft. xml 包中,创建 IUserDao接口的实现类 UserDaolmpl,分别实现接口中的方法,并在每个方法中添加一条输出语句
package com.soft.xml;
public class UserDaoImpl implements IUserDao {
@Override
public void addUser() {
System.out.println("添加用户");
}
}
4.在该包下创建切面类 MyAspect
在该类中定义一个模拟权限检查的方法和一个模拟记录日志的方法,这两个方法就表示切面中的通知
切面类:可以存在多个通知 Advice(即增强的方法)
package com.soft.xml;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class Myspect {
//前置通知
public void myBefore(JoinPoint joinPoint) {
System.out.println("前置通知,模拟执行权限检查");
System.out.println("目标方法是:" + joinPoint.getTarget());
System.out.println("被增强方法" + joinPoint.getSignature().getName());
}
//后置通知
public void myAfterReturning(JoinPoint joinPoint) {
System.out.println("后置通知,模拟日志");
System.out.println("被增强方法" + joinPoint.getSignature().getName());
}
//环绕通知
public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕开始");
Object proceed = proceedingJoinPoint.proceed();
System.out.println("环绕结束");
return proceed;
}
//异常通知
public void myAfterThrowable(JoinPoint joinPoint, Throwable t) {
System.out.println("异常通知," + t.getMessage());
}
//最终通知
public void myAfter() {
System.out.println("最终通知");
}
}
6.配置文件 applicationContext
在 src下,创建配置文件 applicationContext-xml.xml,并编写相关配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!--目标类-->
<bean id="userDao" class="com.soft.xml.UserDaoImpl"/>
<!--切面-->
<bean id="myspect" class="com.soft.xml.Myspect"/>
<!--aop编程-->
<aop:config>
<!--配置切面-->
<aop:aspect id="aspect" ref="myspect">
<!--配置切入点,通知最后增强哪些方法-->
<aop:pointcut id="myPoinCut" expression="execution(* com.soft.xml.*.*(..))"/>
<!--关联通知Advice和切入点pointCut-->
<!--前置通知-->
<aop:before method="myBefore" pointcut-ref="myPoinCut"/>
<!--后置通知-->
<aop:after-returning method="myAfterReturning" pointcut-ref="myPoinCut"/>
<!--环绕通知-->
<aop:around method="myAround" pointcut-ref="myPoinCut"/>
<!--异常(抛出)通知-->
<aop:after-throwing method="myAfterThrowable" pointcut-ref="myPoinCut" throwing="t"/>
<!--最终通知-->
<aop:after method="myAfter" pointcut-ref="myPoinCut"/>
</aop:aspect>
</aop:config>
</beans>
5.创建测试类TestXmlAspect
在com.soft.xml包下,创建测试类 TestXmlAspect,在类中为了更加清晰地演示几种通知的执行情况,这里只对 addUser方法进行增强测试
package com.soft.xml;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestXmlAspect {
public static void main(String[] args) {
ApplicationContext applicationContext= new ClassPathXmlApplicationContext("applicationContext-xml.xml");
IUserDao iUserDao=(IUserDao)applicationContext.getBean("userDao");
iUserDao.addUser();
}
}
7.控制台输出结果
要查看异常通知的执行效果,可以在 UserDaolmpl类的 addUser()方法中添加错误代码,如“int i=1/0;",重新运行测试类,将可以看到异常通知的执行,此时控制台的输出结果: