AOP的目标:让我们可以"专心做事"
AOP的原理
- 将复杂的需求分解出不同方面,将散步在系统中的公共功能集中解决
- 采用代理机制组装起来运行,在不改变原程序的基础上对代码段进行增强处理,增加新的功能
AOP的相关术语
增强处理(Advice)
前置增强,后置增强,环绕增强,异常抛出增强,最终增强等类型
- 切入点(PointCut)
- 连接点(Join Point)
- 切面(Aspect)
- 目标对象(Target object)
- AOP代理(AOP proxy)
- 织入(Weaving)
实例
Student类中
public void studyChin(){
System.out.println(“正在学习语文”);
}
public void studyEng(){
System.out.println(“正在学习英语”);
}
Parent类中
public void bf(){
System.out.println(“端茶倒水”);
}
public void af(){
System.out.println(“给与鼓励”);
}
对这两个类建立关系
<bean id=”parent” class=”com.pojo.Parent”></bean>
<aop:config>
<!--定义切入点-->
<aop:pointcut expression=”execution(public void *())” id=”pt”>
<!--各种增强-->
<aop:aspect ref = “parent”> parent表示的是额外添加的功能
<aop:before method=”bf” point-ref=”studyChin”/> bf和af为Parent类里的方法
<aop:after method=”af” point-ref=”studyChin”/> pt:表示的是切入到哪个方法里面
</aop:aspect>
</aop:config>
spring的aop的增强处理实现日志通知
public class StuLogger{
public void before(JoiPoint joinPoint){
//获取目标对象
Object target = joinPoint.getTarget();
//获取传入的参数
Object[] ob = joinPoint.getArgs();
//获取对应的方法
String name = joinPoint.getSignature().getName();
}
public void after(JoiPoint joinPoint){
//获取目标对象
Object target = joinPoint.getTarget();
//获取传入的参数
Object[] ob = joinPoint.getArgs();
//获取对应的方法
String name = joinPoint.getSignature().getName();
}
}
<bean id=”logger” class=”com.pojo.StuLogger”></bean>
<aop:config>
<!--定义切入点-->
<aop:pointcut expression=”execution(public void *(..))” id=”pt”>
<!--各种增强-->
<aop:aspect ref = “logger”> parent表示的是额外添加的功能
<aop:before method=”before” point-ref=”pt”/> bf和af为Parent类里的方法
<aop:after method=”after” point-ref=”pt”/> pt:表示的是切入到哪个方法里面
</aop:aspect>
</aop:config>
使用注解来实现AOP(增强处理) 在不涉及主业务的基础上加了一些功能
Spring AOP术语:连接点和切点的区别
1.连接点(Join point):连接点是在应用执行过程中能够插入切面(Aspect)的一个点。这些点可以是调用方法时、甚至修改一个字段时。
2.切点(Pointcut):切点是指通知(Advice)所要织入(Weaving)的具体位置。
理解:
连接点:连接点是一个虚拟的概念,可以理解为所有满足切点扫描条件的所有的时机。
具体举个例子:比如开车经过一条高速公路,这条高速公路上有很多个出口(连接点),但是我们不会每个出口都会出去,只会选择我们需要的那个出口(切点)开出去。
简单可以理解为,每个出口都是连接点,但是我们使用的那个出口才是切点。每个应用有多个位置适合织入通知,这些位置都是连接点。但是只有我们选择的那个具体的位置才是切点。
@Component(“p”)
public class Person{
private String name;
private String age;
//省略get和get方法
}
@Component
@Aspect
public class PersonLogger {
//切入点的表达式,只需要写一次即可
@PointCut(“execution(public * test())”)
public void pt(){} //然后把其他位置都改成pt()就可以了
@Before(“pt()”)
public void before(JointPoint jp){
System.out.println(“这是一个前置增强,方法是:“ + jp.getSignature().getName());
}
@After(“pt()”)
public void after(){
System.out.println(“这是一个后置增强));
}
@AfterReturning(value=“pt()”, returning=”rs”)
public void t1(Object rs){
System.out.println(“这是一个返回增强: “ + rs);
}
@AfterThrowing(value=”execution(public * test())”, throwing=”e”)
public void t2(){
System.out.println(“这是一个异常增强,异常是“ +e );
}
}
让配置的切点生效
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>