一、概述
AOP,aspect object programming 面向切面编程(面向重复的代码编程)
作用:让关注点代码与业务代码分离
关注点:
重复代码就叫做关注点
切面:
关注点形成的类,就叫做切面类
面向切面编程,就是指 对很多功能都有的重复代码的抽取,再在运行的时候往业务方法上动态植入“切面代码”。
切入点:
执行目标对象方法,动态植入切面代码。
可以通过切入点表达式,指定拦截哪些类的哪些方法;给指定的类在运行的时候植入切面类代码
二、注解的方式实现AOP编程
步骤:
1)先引入AOP相关jar文件
2)在bean.xml中引入aop名称空间
3)开启AOP注解方式
切面类示例
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect // 指定当前类为切面类
public class Aop {
// 指定切入点表单式: 拦截哪些方法; 即为哪些类生成代理对象
@Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))")
public void pointCut_(){
}
// 前置通知 : 在执行目标方法之前执行
@Before("pointCut_()")
public void begin(){
System.out.println("开始事务/异常");
}
// 后置/最终通知:在执行目标方法之后执行 【无论是否出现异常最终都会执行】
@After("pointCut_()")
public void after(){
System.out.println("提交事务/关闭");
}
// 返回后通知: 在调用目标方法结束后执行 【出现异常不执行】
@AfterReturning("pointCut_()")
public void afterReturning() {
System.out.println("afterReturning()");
}
// 异常通知: 当目标方法执行异常时候执行此关注点代码
@AfterThrowing("pointCut_()")
public void afterThrowing(){
System.out.println("afterThrowing()");
}
// 环绕通知:环绕目标方式执行
@Around("pointCut_()")
public void around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕前....");
pjp.proceed(); // 执行目标方法
System.out.println("环绕后....");
}
}
三、xml方式配置AOP编程
1.编写切面示例类
Pointcut
package com.demo.aop;
public class Book {
public void add(){
System.out.println("Book.add..........");
throw new RuntimeException("this is test Exception");
}
}
2.编写增强类(
Advice
)
package com.demo.aop;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyBook {
public void before1(){
System.out.println("前置增强。。。。。。。。");
}
public void after1(){
System.out.println("后置增强/最终增强:。。。。。。。。");
}
public void around1(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕通知:。。。。。。。。前");
pjp.proceed();
System.out.println("环绕通知:。。。。。。。。后");
}
public void afterThrowing(){
System.out.println("异常通知。。。。。");
}
public void afterReturning(){
System.out.println("返回后通知。。。。。。");
}
}
3.配置xml
<?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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->
<!-- 配置对象 -->
<bean id="book" class="com.demo.aop.Book"></bean>
<bean id="myBook" class="com.demo.aop.MyBook"></bean>
<!-- 配置aop操作 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* com.demo.aop.Book.*(..))" id="pointcut1"/>
<!-- 配置切面 -->
<aop:aspect ref="myBook">
<!-- 前置增强 -->
<aop:before method="before1" pointcut-ref="pointcut1"/>
<!-- 后置/最终通知:在执行目标方法之后执行 【无论是否出现异常最终都会执行】 -->
<aop:after method="after1" pointcut-ref="pointcut1"/>
<!-- 环绕通知:环绕目标方式执行 -->
<aop:around method="around1" pointcut-ref="pointcut1"/>
<!-- 异常通知: 当目标方法执行异常时候执行此关注点代码 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut1"/>
<!-- 返回后通知: 在调用目标方法结束后执行 【出现异常不执行】 -->
<aop:after-returning method="afterReturning" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
</beans>
4.测试
package com.demo.aop;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BookTest {
private ClassPathXmlApplicationContext context;
@Before
public void setUp() throws Exception {
this.context = new ClassPathXmlApplicationContext("bean3.xml");
}
@Test
public void testAdd() {
Book book = (Book)this.context.getBean("book");
book.add();
}
}
四、AOP的应用场景
程序的“事务控制”,可以用AOP实现!即只需要写一次,运行时候动态植入到业务方法上。
spring提供了对事务的管理,开发者只需要按照spring的方式去做就行。