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的底层实现
1、Spring框架的AOP技术底层也是采用代理技术,代理的方式提供了两种
* 基于JDK的动态代理
> 必须是面向接口的,只有实现了具体接口的类才能生成代理对象
* 基于CGLIB动态代理
> 对于没有实现接口的类,也可以产生代理,产生这个类的子类的方式
2、Spring的传统AOP中根据类是否实现接口,来采用不同的代理方式
* 如果实现类接口,使用JDK动态代理完成AOP
* 如果没有实现接口,采用CGLIB动态代理完成AOP
JDK的动态代理
使用Proxy类来生成代理对象
UserDaoImpl:
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("保存客户...");
}
public void update() {
System.out.println("修改客户...");
}
}
MyProxyUtils:
/**
* 使用JDK的方式生成代理对象
* @author Administrator
*/
public class MyProxyUtils {
public static UserDao getProxy(final UserDao dao) {
ClassLoader loader;
// 使用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;
}
}
测试代码:
public class Demo1 {
@Test
public void run1() {
// 目标对象
UserDao dao = new UserDaoImpl();
dao.save();
dao.update();
System.out.println("==================================");
// 使用工具类,获取到代理对象
UserDao proxy = MyProxyUtils.getProxy(dao);
// 调用代理对象的方法
proxy.save();
proxy.update();
}
}
CGLIB的代理技术
* 如果想使用CGLIB的技术来生成代理对象,需要引入CGLIB的开发jar包,在Spring框架核心包中已经引入了CGLIB的开发包。所以直接引入Spring核心开发包即可。。。
2)编写相关代码
BookDaoImpl:
public class BookDaoImpl {
public void save() {
System.out.println("保存图书");
}
public void update() {
System.out.println("修改图书");
}
}
MyCglibUtils:
public class MyCglibUtils {
/**
* 使用CGLIB方式生成代理的对象
* @return
*/
public static BookDaoImpl getProxy() {
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(BookDaoImpl.class);
// 设置回调函数
enhancer.setCallback(new MethodInterceptor() {
// 代理对象的方法执行,回调函数就会执行
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;
}
}
测试代码:
public class Demo2 {
@Test
public void run1() {
// 目标对象
BookDaoImpl dao = new BookDaoImpl();
dao.save();
dao.update();
System.out.println("==================================");
// 使用CGLIB方式生成代理对象
BookDaoImpl proxy = MyCglibUtils.getProxy();
proxy.save();
proxy.update();
}
}