AOP的概述
1. 什么是AOP的技术?在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程
AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构
AOP最早由AOP联盟的组织提出的,制定了一套规范。Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范
通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术
AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型
利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
2. AOP:面向切面编程(思想---解决OOP遇到一些问题)
3. AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)
4. 为什么要学习AOP
可以在不修改源代码的前提下,对程序进行增强!!
Spring框架的AOP的底层实现
Srping框架的AOP技术底层也是采用的代理技术,代理的方式提供了两种1. 基于JDK的动态代理
必须是面向接口的,只有实现了具体接口的类才能生成代理对象。 在运行期生成代理对象。
2. 基于CGLIB动态代理
对于没有实现了接口的类,也可以产生代理,产生这个类的子类的方式。有可能在 编译时就生成代理类了,也有可能在 类加载的时候生成代理对象。不管怎样,都会生成 代理对象。
Spring的传统AOP中根据类是否实现接口,来采用不同的代理方式
1. 如果实现类接口,使用JDK动态代理完成AOP
2. 如果没有实现接口,采用CGLIB动态代理完成AOP
自我解读:其实代理的本质是,通过生一个代理对象。然后,访问代理对象,代理对象去决定目标对象的执行。
JDK的动态代理(代码了解,理解原理)
1. 使用Proxy类来生成代理对象的一些代码如下:
/**
* 使用JDK的方式生成代理对象
*/
public class MyProxyUtils {
public static UserDao getProxy(final UserDao dao) {
// 使用Proxy类生成代理对象
UserDao proxy = (UserDao) Proxy.newProxyInstance(dao.getClass().getClassLoader(),
dao.getClass().getInterfaces(), new InvocationHandler() {
// 代理对象方法一直线,invoke方法就会执行一次
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("save".equals(method.getName())) {
System.out.println("记录日志...");
// 开启事务
}
// 提交事务
// 让dao类的save或者update方法正常的执行下去
return method.invoke(dao, args);
}
});
// 返回代理对象
return proxy;
}
}
基于JDK的动态代理
CGLIB的代理技术(代码了解)
1. 引入CBLIB的开发包* 如果想使用CGLIB的技术来生成代理对象,那么需要引入CGLIB的开发的jar包,在Spring框架核心包中已经引入了CGLIB的开发包了。所以直接引入Spring核心开发包即可
2. 编写相关的代码
public class MyCglibUtils {
/**
* 使用CGLIB方式生成代理的对象
*/
// 生成子类,用父类来接收
public static BookDaoImpl getProxy() {
Enhancer enhancer = new Enhancer();
// 设置父类。因为cglib就是要生成子类嘛
enhancer.setSuperclass(BookDaoImpl.class);
// 设置回调函数
enhancer.setCallback(new org.springframework.cglib.proxy.MethodInterceptor() {
// 代理对象的方法执行,回调函数就会执行
// 注意:methodProxy是对前面的参数method,底层生成了一个代理对象
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy)
throws Throwable {
if (method.getName().equals("save")) {
System.out.println("记录日志...");
}
// 正常执行
return methodProxy.invokeSuper(obj, args);
}
});
// 生成代理对象
BookDaoImpl proxy = (BookDaoImpl) enhancer.create();
return proxy;
}
}
如果,你写程序,提供了接口,spring就选择jdk动态代理。如果没有提供接口,spring就选择cglib。
jdk动态代理,是在运行期间,动态的生成代理对象。而cglib是在类加载的时候生成子类。
cglib的方式