静态代理:
一个新的类,想要代理那个类,那个类里面的方法,然后加自己的逻辑,然后再调用被代理的那个类的方法,因为两个类实现了同一个接口。 实现代理互相嵌套。
动态代理:
JDK动态代理:通过proxy这个类来实现,一个newproxyinstance方法来生成动态代理对象。这个方法的三个参数,第一个是被代理类的类加载器,第二个是被代理对象应该实现的哪个接口(可以实现多个接口),第三个参数,指的是被代理的对象里面的那个方法怎么做处理,比如再这个方法前后做操作。
生成$ proxy0一个字节码文件,生成一个$proxy0对象,去调用方法,是调用的生成代理对象的那个方法
接口
public interface StudentDao {
public abstract void login();
}
实现类
public class StudentDaoImpl implements StudentDao {
@Override
public void login() {
System.out.println("登陆功能");
}
}
测试
public class Test {
public static void main(String[] args) {
StudentDao studentDao = new StudentDaoImpl();
StudentDao proxyInstance = (StudentDao) Proxy.newProxyInstance(
studentDao.getClass().getClassLoader(),
//studentDao.getClass().getInterfaces(),
//第二种获取接口的方式
new Class[]{StudentDao.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("权限校验");
Object invoke = method.invoke(studentDao, args);
System.out.println("日志记录");
return invoke;
}
}
);
proxyInstance.login();
}
}
cglib动态代理:
不需要接口,我们动态生成被代理的类的子类,如果是final就不能生成了
(听说ASM是final还是能改变)
JDK代理要求被代理的类必须实现接口,有很强的局限性。而CGLIB动态代理则没有此类强制性要求。简单的说,CGLIB会让生成的代理类继承被代理类,并在代理类中对代理方法进行强化处理(前置处理、后置处理等)。在CGLIB底层,其实是借助了ASM这个非常强大的Java字节码生成框架。在CGLIB中,方法的调用并不是通过反射来完成的,而是直接对方法进行调用:FastClass对Class对象进行特别的处理,比如将会用数组保存method的引用,每次调用方法的时候都是通过一个index下标来保持对方法的引用
两个动态代理底层都是用的ASM