01、AOP的依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.17.RELEASE</version>
</dependency>
02、AOP:动态代理
指定程序运行期间动态的将某段代码切入到指定方法指定的位置进行运行的编码
- 导入AOP模块:spring-aspects
- 定义一个业务逻辑类AopDemo.java。在业务逻辑运行的时候打印日志,包括方法运行之前,方法运行之后或出现异常
- 定义一个日志切面类LogAspect.java。切面类里面的方法需要动态感知到AopDemo类的方法
- 给切面的目标类标注何时何地运行(通知注解)
- 将代理类和委托类都加入到容器中
- 告诉容器那个类是代理类,给代理类上加上一个注解
- 给配置类加@EnableAspectJAutoProxy(开始给予注解的AOP模式)
- 在Spring中很多的@EnableXxxx;
03、通知方法:
- 前置通知:(@Before)
- 后置通知(@After)
- 返回通知(@AfterReturning)
- 异常通知(@AfterThrowing)
- 环绕通知:动态代理,手动推进目标方法运行(jionPoint.procced())
public class AopDemo {
public int div(int i,int j){
return i/j;
}
}
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
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:告诉Spring当前类是一个切面类
* @author Administrator
*
*/
@Aspect
public class LogAspects {
/**
* 抽取公共的切入点表达式
* 1、本类引用
* 2、其他的切面引用
*/
@Pointcut("execution(* com.ceshi.aop.AopDemo.*(..))")
public void pointCur(){
}
//@Before("public int com.ceshi.aop.AopDemo.div(int i,int j)")//具体方法
@Before("pointCur()")
public void logStart(JoinPoint joinpoint){
System.out.println(joinpoint.getArgs());
System.out.println(joinpoint.getStaticPart().getSignature().getName());
System.out.println("开始");
}
@After("pointCur()")
public void logEnd(){
System.out.println("结束");
}
@AfterReturning(value="pointCur()",returning="obj")
public void logReturn(Object obj){
System.out.println(obj);
System.out.println("正常返回");
}
//JoinPoint joinpoint一定要出现在参数表的第一位
@AfterThrowing(value="pointCur()",throwing="exception")
public void logException(JoinPoint joinpoint,Exception exception){
System.out.println(exception);
System.out.println("出现异常");
}
}
/**
* AOP:动态代理
* 指定程序运行期间动态的将某段代码切入到指定方法指定的位置进行运行的编码
* 1、导入AOP模块:spring-aspects
* 2、定义一个业务逻辑类AopDemo.java。在业务逻辑运行的时候打印日志,包括方法运行之前,方法运行之后或出现异常
* 3、定义一个日志切面类LogAspect.java。切面类里面的方法需要动态感知到AopDemo类的方法
*
* 4、给切面的目标类标注何时何地运行(通知注解)
* 5、将代理类和委托类都加入到容器中
* 6、告诉容器那个类是代理类,给代理类上加上一个注解
* 7、给配置类加@EnableAspectJAutoProxy(开始给予注解的AOP模式)
* 在Spring中很多的@EnableXxxx;
*
* 通知方法:
* 前置通知:(@Before)
* 后置通知(@After)
* 返回通知(@AfterReturning)
* 异常通知(@AfterThrowing)
* 环绕通知:动态代理,手动推进目标方法运行(jionPoint.procced())
*
* 总结:
* 1、将代理类和委托类都加入到容器中,并且告诉容器那个代理类(@Aspect)
* 2、在代理类上的每一个通知方法上标注通知注解,告诉Spring何时何地运行(切入点)
* 3、开启基于注解的AOP模式
*
*
*
*/
//配置类==配置文件(xml)
@EnableAspectJAutoProxy
@Configuration //告诉Spring这个一个配制类
public class BeanConfigOfAOP {
@Bean
public AopDemo aopDemo(){
return new AopDemo();
}
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
}
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.ceshi.aop.AopDemo;
import com.ceshi.config.BeanConfigOfAOP;
/**
*
* @author wangyongxun
*
*/
public class IOCTest {
@Test
public void test01(){
//创建Applicaation
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
//设置需要激活的环境
//annotationConfigApplicationContext.getEnvironment().setActiveProfiles("test");
//注册主配制类
annotationConfigApplicationContext.register(BeanConfigOfAOP.class);
//启动刷新容器
annotationConfigApplicationContext.refresh();
AopDemo aopDemo = annotationConfigApplicationContext.getBean(AopDemo.class);
aopDemo.div(1, 1);
// String[] names = annotationConfigApplicationContext.getBeanDefinitionNames();
// for(String name:names){
// System.out.println(name);
// }
}
}