Spring学习笔记(三) 面向切面的Spring

本文代码以及工程文件托管在github:https://github.com/Wuchenwcf/SpringAOPDemo

一、Spring和AOP

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");
	}
	
	
}


2.编写performce的实现类

package concert;

public class Singger implements Performance {

	public void perform() {
		// TODO Auto-generated method stub
		System.out.println("lalallala");
	}
	

}


3.在JavaConfig中启用AspectJ注解的自动代理

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();
	}
}

4.编写主程序

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中声明切面,此处不一一赘述。


你可能感兴趣的:(Spring)