AOP是什么
没错,就是这一碗美味的刀削面。
AOP--面向切面的编程便是拌一碗刀削面的过程,这些佐料构成了切面,而这碗刀削面便是切点,佐料一勺一勺的拌入干面中,加以搅拌,这碗刀削面才可口啊。
即切面中的代码要织入到切点中,增强切点的功能。
增强处理
前言
何为增强处理?举个栗子。假设你现在项目中有十个save类型方法,你现在想在所有方法执行前在控制台输出一个“执行save方法”。这显然是对原来方法的增强。
我们通常的做法是在每一个save方法中,写一条输出,可能说十个save方法你还可以一条条添加,但如果是一百个甚至更多个方法呢?所以遇到这个问题,Spring AOP来了,用它来增强方法显然是十分方便的,还可以减少对原代码的入侵,降低耦合度。
通知分类
AspectJ 支持 5 种类型的通知注解:
@Before : 前置通知, 在方法执行之前执行
@After : 后置通知, 在方法执行之后执行
@AfterRunning: 返回通知, 在方法返回结果之后执行
@AfterThrowing: 异常通知, 在方法抛出异常之后
@Around : 环绕通知, 围绕着方法执行。
增强实现
定义一个接口,只有两个方法,分别输出一行文本。
public interface HelloWorld {
void sayHi();
void sayHi2();
}
public class HelloWorldImpl implements HelloWorld{
@Override
public void sayHi() {
System.out.println("Hello World");
}
@Override
public void sayHi2() {
System.out.println("Hello World2");
}
}
现在我想在方法输出的前后,增强一点功能--打印时间。有两种方式实现--基于XML方式和基于注解方式
基于XML方式
public class TimeHandler {
public void printTime()
{
System.out.println("CurrentTime = " + System.currentTimeMillis());
}
}
<!-- 基于XML配置的Spring AOP -->
<bean id="timeHandler" class="com.cfx.other.TimeHandler"></bean>
<aop:config>
<aop:aspect id="time" ref="timeHandler" order="1">//order执行优先级
<aop:pointcut id="addAllMethod" expression="execution(* com.cfx.service.HelloWorld.sayHi*(..))" />//拦截所有sayHi开头的方法
<aop:before method="printTime" pointcut-ref="addAllMethod" />//方法执行前,执行printTime()
<aop:after method="printTime" pointcut-ref="addAllMethod" />//方法执行后,执行printTime()
</aop:aspect>
</aop:config>
基于注解方式
@Aspect
@Order(1)
public class AspectHandler {
//定义切入点,表示要拦截的方法位置,作用是advice重用
@Pointcut("execution(* com.cfx.service.HelloWorld.*(..))")
private void addAllMethod(){};
@Before("addAllMethod()")
public void before(){
System.out.println("CurrentTime = " + System.currentTimeMillis());
}
@After("addAllMethod()")
public void after(){
System.out.println("CurrentTime = " + System.currentTimeMillis());
}
}
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<bean id="aspectHandler" class="com.cfx.other.AspectHandler"></bean>
运行测试
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-aop.xml");
HelloWorld hw = (HelloWorld)ctx.getBean("helloWorldImpl");
hw.sayHi();
hw.sayHi2();
}
}