AOP:(Aspect Oriented Programming) 面向切面编程
OOP:(Object Oriented Programming) 面向对象编程
AOP基于OOP,指在程序运行期间,将某段代码动态的切入到指定方法的指定位置进行运行的编程方式‘
加日志记录:
动态代理
1)写起来很难
2)动态代理,jdk默认的动态代理,如果目标对象没有实现任何接口,是无法创建代理对象的
Spring实现AOP功能;底层就是动态代理;
1)可以利用Spring一句代码都不写的去创建动态代理;
实现简单,而且没有强制目标对象实现接口
AOP的专业属于术语
AOP使用步骤:
1)导包
Spring支持面向切面编程的包:
spring-aspects-4.0.0.RELEASE.jar 基本版
以下为加强版(即使目标对象没有实现任何切口也能创建动态代理)
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
2)写配置
1)将目标类和切面类(封装了通知方法(在目标方法执行前后执行的方法))加入到IOC容器中。
2)还应该告诉Spring到底哪个是切面类(@Aspect)
3)告诉Spring,切面类里面的每个方法都是何时何地运行的
package com.lyj.utils;
import java.lang.reflect.Method;
import java.util.Arrays;
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.springframework.stereotype.Component;
/**
* 如何将这个类(切面类)中的这些方法(通知方法)动态的在目标方法运行的各个位置切入
* @author Administrator
*
*/
@Aspect
@Component
public class LogUtils {
/**
* 告诉Spring每个方法都什么时候运行
* [1]@Before:前置通知,在方法执行之前执行
[2]@After:后置通知,在方法执行之后执行
[3]@AfterRunning:返回通知,在方法返回结果之后执行
[4]@AfterThrowing:异常通知,在方法抛出异常之后执行
[5]@Around:环绕通知,围绕着方法执行
*/
//之前,写切入表达式
//excution(方法权限 返回类型 方法签名)
@Before("excution(public int com.lyj.impl.MyCalc.*(int, int))")
public static void logStart(){
System.out.println("【】方法开始执行,用参数列表");
}
//正常完成之后
@AfterReturning("excution(public int com.lyj.impl.MyCalc.*(int, int))")
public static void logReturn(){
System.out.println("【】方法执行结束,计算结果是");
}
//出现异常之后
@AfterThrowing("excution(public int com.lyj.impl.MyCalc.*(int, int))")
public static void logException(){
System.out.println("【】方法执行出现异常,异常信息是");
}
//结束
@After("excution(public int com.lyj.impl.MyCalc.*(int, int))")
public static void logEnd(){
System.out.println("【】方法最终结束");
}
}
3)测试
/**
* 动态代理,jdk默认的动态代理,如果目标对象没有实现任何接口,是无法创建代理对象的
* 因为代理对象和被代理对象的唯一关联就是实现了同一个接口
*/
@Test
public void test() {
//从ioc容器中拿到目标对象.要用类型获取 一定要用他的接口,不要用他的本类
//细节一:com.lyj.impl.MyCalc@131ef10
//class com.sun.proxy.$Proxy12
//AOP的底层就是动态代理,容器中保存到组件就是代理对象
//class com.lyj.impl.MyCalc$$EnhancerByCGLIB$$395d870
//cglib帮我们创建好的代理对象
Calculator bean = ioc.getBean(Calculator.class);
bean.add(2, 1);
System.out.println(bean);
System.out.println(bean.getClass());
MyCalc bean2 = (MyCalc) ioc.getBean("myCalc");
System.out.println(bean2.getClass());
}