AOP概念
AOP:面向切面编程
-
可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
-
通俗描述:不通过修改源代码方式,在主干功能里添加新功能
-
使用登录例子说明AOP
现在权限判断和登录功能是分离的,哪一天我不需要这个模块了,只需要移除这个模块就行了,不用修改源代码。
AOP底层原理
-
AOP底层使用动态代理
(1)有两种情况的动态代理
第一种:有接口情况, 使用JDK动态代理
创建接口实现类的代理对象,通过代理对象来增强方法
有个接口UserDao,想增强它的实现类UserDaoimpl的login方法
第二种:没有接口情况,使用CGLIB动态代理
创建子类的代理对象,增强类的方法
正在上传…重新上传取消
AOP(JDK动态代理)
代理模式的使用总结_ZYF-ZYF的博客-CSDN博客_代理模式有啥用
在java的java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过这个类和这个接口可以生成JDK动态代理类和动态代理对象。
-
使用 JDK 动态代理,使用 Proxy 类里面的方法创建代理对象
有个静态方法叫newProxyInstance方法
-
编写JDK动态代理编码
(1)创建接口,定义方法
public interface UserDao { public int add(int a,int b); public String update(String id); }
(2)创建接口实现类,实现方法
public class User implements UserDao{ @Override public int add(int a, intb){ return a+b; } public String update(String id){ return id; } }
(3)使用Proxy类创建接口类代理对象
原理:对某个对象某个方法进行增强处理,只需要通过InvocationHandler将这个对象代理,被代理的对象所有的方法调用都会被InvocationHandler的invoke方法拦截,invoke方法通过反射动态获取方法的调用者和调用的方法以及方法参数,再在invoke方法中通过反射调用方法,因为invoke方法是要重写的,所以可以在真正被调用方法执行前后进行一些额外的操作 也就是AOP中的在方法执行前后的那个切面织入一些额外的操作
用Proxy里的newProxyInstance创建接口实现类的代理对象
一定要implement InvocationHandler
newInstance中第一个参数应该为真实主题类的类加载器,第二个参数应该为真实主题类所实现的抽象主题类的接口,第三个参数是代理对象对真实主题类对象的业务接口进行调用处理的程序
public class JDKProxy{ public static void main(String[] args){ Class[] interfaces = {UserDao.class}; //创建一个UserDaoImpl实例:userDao UserDaooImpl userDao = new UserDaoInol(); //类加载器 增强方法所在的类实现的接口 实现接口的增强部分 UserDao dao = (UserDao) Proxy.newProxyInstance( JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy( userDao ) ); //它不是new出来的,它是用Proxy里的newProxyInstance方法创建出来的,它就是实现类的代理对象, int add = dao.add(1,2); //调的是add方法,它就增强add方法,调用的是updata方法,它就增强update方法 } } //创建代理对象代码 class UserDaoProxy implements InvocationHandler{ //把创建的是谁的代理对象,把谁传递过来,即传入被代理的对象 //有参数构造传递 这里也就是上面传进来的userDao private Object obj; public UserDaoProxy(Object obj){ this.obj = obj; } // 对象一创建,方法就会被调用 // 增强的逻辑 第一个参数proxy就是被代理的对象,invoke方法会在被生成的类中被调用。第二个参数就是方法,第三个参数就是传递的参数 在上面代码中调用dao.add(1,2)时,将add方法传入,参数1,2传入。 @Override public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{ //方法之前 System.out.println("方法之前执行...."+method.getName()+" :传递的参 数..."+ Arrays.toString(args)); //被增强的方法执行 //已经传进来obj了,用method.invoke传对象和参数执行方法 Object res = method.ivoke(obj,args); //当代理对象调用add方法时,method也就是add方法,这个invoke方法的两个参数:调用method的对象(userDao),method的参数(1,2),执行完之后会返回3,用res接收。即代表使用上面创建的UserDaoImpl实例:userDao的add方法。 //方法之后 System.out.println("方法之后执行...."+obj); return res; //把方法的值返回 } }