什么是AOP
面向切面编程, 即利用AOP可以对业务逻辑的各个部分进行隔离, 从而使得业务逻辑各个部分之间的耦合度降低, 提高程序的可重用性, 同时提高了开发的效率.
底层原理
AOP通过代理对象的方式来增强其他的类的功能, 从而避免修改源代码, 根据待增强类有无实现接口, 可以将代理对象分为两类:
- 有接口情况, 使用JDK动态代理: 即创建原来接口实现类的代理对象, 用此对象去增强待增强类;
- 无接口情况, 使用CGLIB动态代理: 创建当前类的子类的代理对象, 用此对象去增强;
以JDK动态代理为例, 举例说明实现原理:
创建待实现接口 UserDao.java:
public interface UserDao { int add(int a, int b); String update(String id); }
创建待增强类 UserDaoImpl.java 实现 UserDao.java接口:
public class UserDaoImpl implements UserDao { @Override public int add(int a, int b) { System.out.println("正在执行 add 方法..."); return a+b; } @Override public String update(String id) { return id; } }
创建增强类 JDKProxy.java:
public class JDKProxy { public static void main(String[] args) { //通过Proxy.newProxyInstance方法创建接口实现类代理对象, 该方法需要三个参数 //创建 newProxyInstance 方法的第二个参数 Class[] interfaces = {UserDao.class}; UserDaoImpl userDao = new UserDaoImpl(); UserDao dao = (UserDao)Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao)); //测试 int result = dao.add(3, 5); System.out.println("result: " + result); } //创建 newProxyInstance 方法的第三个参数, 也是在这里写代理对象的代码(第三个参数必须是 InvocationHandler 接口的对象) static 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: " + obj + " args: " + args); return res; } } }
测试结果: