aop概念
面向切面(方面)编程,扩展功能不通过源代码实现。
aop底层原理
原始方式:修改源代码
纵向继承方式:继承父类。
横向抽取机制:底层使用动态代理方式实现。
(1) JDK代理(有接口实现类)
(2) CGLB代理(无接口实现类)
aop中的专业术语
主要掌握:
Aspect,Advice,Pointcut
spring的aop操作
1. 在spring里面进行aop操作没使用AspectJ实现。
2. AspectJ本身不是spring的一部分。和spring结合操作。
aspectj介绍
使用aspectj实现aop有两种方式。
(1) 基于aspectj的xml配置文件方式。
(2) 基于aspectj的注解方式。
aop操作准备
1.导包
2. 创建spring核心配置文件,导入核心约束。
具体实现
- 要增强的类
package com.xu.springannotion.aop;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyBook {
public void before() {
System.out.println("前置增强");
}
public void after() {//不是最终增强
System.out.println("后置增强");
}
//环绕通知
//spring框架为我们提供了一个接口,
//该接口作为环绕通知方法的参数,在方法运行时,spring
//框架为我们提供该接口的实现类供我们使用
//ProceedingJoinPoint中有一个proceed方法明确了切入点的调用
//
public Object arround(ProceedingJoinPoint joinpoint) throws Throwable {
//方法之前
Object value=null;
//System.out.println("方法之前。。。");
try {
Object[] args = joinpoint.getArgs();//得到方法的参数
System.out.println("方法之前。。。前置");
value=joinpoint.proceed(args);//明确切入点方法,执行原方法
System.out.println("方法之后。。。后置");
} catch (Exception e) {
// TODO: handle exception
System.out.println("异常通知。。。异常");
throw new RuntimeException();
}
finally {
System.out.println("最终通知啊啊。。。最终");
}
//System.out.println("方法之后");
return value;
}
//最终通知
public void end() {
System.out.println("最终通知");
}
//异常通知
}
- 配置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:context="http://www.springframework.org/schema/context"
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置对象 -->
<bean id="Book" class="com.xu.springannotion.aop.Book"></bean>
<bean id="mybook" class="com.xu.springannotion.aop.MyBook"></bean>
<!-- 配置切面 -->
<aop:config>
<!-- 配置切入点:要增强的方法 -->
<aop:pointcut
expression="execution(* com.xu.springannotion.aop.Book.book(..))"
id="point1" />
<!-- 增强(通知) -->
<aop:aspect ref="mybook">
<!-- 前置通知 -->
<aop:before method="before" pointcut-ref="point1" />
<!-- 后置通知 -->
<aop:after-returning method="after"
pointcut-ref="point1" />
<!-- 这里pointcut-ref后的value是指定你增强的类 -->
<aop:around method="arround" pointcut-ref="point1" />
<aop:after method="end" pointcut-ref="point1" />
</aop:aspect>
</aop:config>
</beans>
测试
import static org.junit.Assert.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
@org.junit.Test
public void testAop() throws Exception {
ApplicationContext context=new ClassPathXmlApplicationContext("com/xu/springannotion/Aop.xml");
Book book=(Book) context.getBean("Book");
book.book();
}
}