本文代码以及工程文件托管在github:https://github.com/Wuchenwcf/SpringAOPDemo
1.AOP的基本术语
(1)通知(Advice)
切面的工作被称为通知,有五类通知:前置通知,后置通知,返回通知,异常通知,环绕通知。
(2)连接点(Jion point)
应用运行时插入切面的一个点,比如函数调用时,函数异常时等。
(3)切点
定义在何处插入切面
2.Spring对AOP的支持
Spring通知是Java编写的,Spring在运行时通知对象,Spring只支持方法级别的连接点
1.编写切点
定义一个接口
package concert;
public interface Performance {
public void perform();
}
1.创建切面
package concert;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class Audience {
@Before("execution(**concert.Performance.perform(..))")//表演之前
public void silenceCellPhones()
{
System.out.println("Silence Cell phones");
}
@Before("execution(**concert.Performance.perform(..))")//表演之前
public void takeSeats()
{
System.out.println("Taking seats");
}
@AfterReturning("execution(**concert.Performance.perform(..))")//表演之后
public void applause()
{
System.out.println("CLAP CLAP CLAP!!!");
}
@AfterThrowing("execution(**concert.Performance.perform(..))")//表演失败之后
public void demandRefund()
{
System.out.println("Demanding a refund");
}
}
但是上面程序相同的切点反复定义了四次,据说不是一件光彩的事情。
可以使用@Pointcut注解声明频繁使用的切点表达式
package concert;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class Audience {
@Pointcut("execution(**concert.Performance.perform(..))")
public void performance()
{
}
@Before("performance()")//表演之前
public void silenceCellPhones()
{
System.out.println("Silence Cell phones");
}
@Before("performance()")//表演之前
public void takeSeats()
{
System.out.println("Taking seats");
}
@AfterReturning("performance()")//表演之后
public void applause()
{
System.out.println("CLAP CLAP CLAP!!!");
}
@AfterThrowing("performance()")//表演失败之后
public void demandRefund()
{
System.out.println("Demanding a refund");
}
}
package concert;
public class Singger implements Performance {
public void perform() {
// TODO Auto-generated method stub
System.out.println("lalallala");
}
}
package concert;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class ConcertConfig {
@Bean
public Audience audience()
{
return new Audience();
}
@Bean
public Performance Singger()
{
return new Singger();
}
}
package concert;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class PerformanceMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext context = new AnnotationConfigApplicationContext(ConcertConfig.class);
Performance singger=context.getBean(Performance.class);
singger.perform();
}
}
除了上面介绍的通知外还有环绕通知
除了在注解中声明切面,还可以在XML中声明切面,此处不一一赘述。