一、什么是AOP?
1、AOP
AOP(Aspect Oriented Programming),即面向切面编程,是OOP的补充,它也提供了模块化。在面向对象编程中,关键的单元是对象,AOP的关键单元是切面,或者说关注点(可以简单地理解为你程序中的独立模块)。一些切面可能有集中的代码,但是有些可能被分散或者混杂在一起,例如日志或者事务。这些分散的切面被称为横切关注点。一个横切关注点是一个可以影响到整个应用的关注点,而且应该被尽量地集中到代码的一个地方,例如事务管理、权限、日志、安全等。
AOP让你可以使用简单可插拔的配置,在实际逻辑执行之前、之后或周围动态添加横切关注点。这让代码在当下和将来都变得易于维护。如果你是使用XML来使用切面的话,要添加或删除关注点,你不用重新编译完整的源代码,而仅仅需要修改配置文件就可以了
总而言之,AOP就是使用不修改源代码的方式,在主干功能里添加新的功能。
二、AOP的底层原理
1、AOP底层使用动态代理
有2种情况的动态代理
(1) 有接口情况使用JDK代理
使用 JDK 动态代理,使用 Proxy 类里面的方法创建代理对象
方法有三个参数:
ClassLoder
,类加载器
类<?>[ ] interfaces
,增强方法所在的类,这个类实现的接口,支持多个接口
InvocationHandler
,实现这个接口 InvocationHandler,创建代理对象,写增强的部分
下面编写代码来演示使用JDK动态代理
1、接口
public interface UserDao {
int add(int a, int b);
/**
*
* @param id
*/
void update(String id);
}
2、接口实现类
public class UserDaoImpl implements UserDao {
@Override
public int add(int a, int b) {
System.out.println("add方法执行了...");
return a+b;
}
@Override
public void update(String id) {
System.out.println("update方法执行了" + id);
}
}
3、代理类
public class JDKProxy {
public static void main(String[] args) {
// 创建接口实现类代理对象
Class[] interfaces = {UserDao.class};
UserDaoImpl userDaoImpl = new UserDaoImpl();
/**
* 第一个参数:ClassLoder,类加载器
* 第二个参数:类<?>[ ] interfaces,增强方法所在的类,这个类实现的接口,支持多个接口
* 第三个参数:InvocationHandler,实现这个接口 InvocationHandler,创建代理对象,写增强的部分
*/
UserDao userDao = (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(),
interfaces,
new UserDaoProxy(userDaoImpl));
int res = userDao.add(1, 2);
System.out.println(res);
}
}
/**
* 增强的逻辑
*/
class UserDaoProxy implements InvocationHandler {
private Object obj;
public UserDaoProxy(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("方法之前执行...." + method.getName() + ";传递的参数" + Arrays.toString(args));
// 被增强的方法执行
Object res = method.invoke(obj, args);
// 方法之后
System.out.println("方法之后执行" + obj);
return res;
}
}
2、没有接口的情况使用CGLIB动态代理
三、AOP相关术语
1、连接点
类里面哪些方法可以被增强,这些方法称为连接点,上面的接口UserDaoImpl中的add()方法和update()方法就是连接点。
2、切入点
实际被真正增强的方法,称为切入点。
UserDaoImpl中的只对add()方法进行增强,不对update()方法增强,那么add()方法就是真正的切入点,update方法不能称为切入点。
3、通知(增强)
实际增强的逻辑部分称为通知(增强)。例如登录功能中,添加的权限判断就是增强的逻辑,那么这个权限判断就称为通知(增强)。
通知类型:
* 前置通知
* 后置通知
* 环绕通知
* 异常通知
* 最终通知
4、切面(是一个动作)
把通知应用到切入点的过程
四、SpringAOP的实现
后面再补充