软件由多个独立的模块组成,但有些功能分布于各个模块之中,比如记日志,这些功能叫做“横切关注点”,cross-cutting concerns。面向切面编程的目的就是——将横切关注点与模块的业务逻辑相分离。
概念
通知,advice
切面要做的事情称作通知。五种类型的通知:before:在方法运行之前。
after:在方法运行之后,无论方法运行是否成功。
after-returning:在方法成功运行之后通知。
after-throwwing:在方法运行期间抛出异常时通知。
around::类似于jsp的Filter,切点的执行由around()方法调用。
切点,pointCut
切点定义了通知发生在何处。
切面,aspect
切面是“通知”和“切点”的结合。
AOP工具
有三大框架——AspectJ、JBossAOP、SpringAOP。通常用AspectJ。
常用类
org.aspectj.lang.ProceedingJoinPoint
实现around通知的方法的形参。
org.aspectj.lang.ProceedingJoinPoint.proceed()
调用切点方法,类似于jsp的Filter的chain.doFilter(request, response)。
实现around通知的方法的形参。
org.aspectj.lang.ProceedingJoinPoint.proceed()
调用切点方法,类似于jsp的Filter的chain.doFilter(request, response)。
例子
演员表演前观众要入席,表演后观众要鼓掌。
App.java
package com.likeyichu.aop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { @SuppressWarnings("resource") public static void main(String[] args) { ApplicationContext ctx ; ctx=new ClassPathXmlApplicationContext("com/likeyichu/aop/beans.xml"); Performer performer=ctx.getBean("performer", Performer.class); performer.perform(); } } /*the audience is taking seats the performer is performing clap clap */
Performer.java
package com.likeyichu.aop; public class Performer{ public void perform(){ System.out.println("the performer is performing"); } }
package com.likeyichu.aop; public class Audience { //表演之前要坐下 public void takeSeats(){ System.out.println("the audience is taking seats"); } //表演成功,故障 public void applause(){ System.out.println("clap clap "); } //若表演失败 需要喝倒彩 public void boo(){ System.out.println("boo boo "); } }
beans.xml
<?xml version="1.0" encoding="GBK"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" > <bean id="performer" class="com.likeyichu.aop.Performer"/> <bean id="audience" class="com.likeyichu.aop.Audience"/> <aop:config> <aop:aspect ref="audience"> <aop:pointcut id="performance" expression="execution (* com.likeyichu.aop.Performer.perform(..))"/> <aop:before pointcut-ref="performance" method="takeSeats"/> <aop:after-returning pointcut-ref="performance" method="applause"/> <aop:after-throwing pointcut-ref="performance" method="boo"/> </aop:aspect> </aop:config> </beans>
maven依赖
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.6.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.6.11</version> </dependency> </dependencies>