1. 动态代理能干什么?
springAOP使用动态代理实现,利用切点与切面可以实现诸如:日志监控、性能监控、权限控制、事务管理的功能
2. 什么是动态代理?
动态代理的目的是为了保证不改变原代码的情况下,对原方法的功能进行扩展的行为方式,进而达到解耦的目的。
3. 动态代理有几种实现方式?
- jdk动态代理
- cglib实现动态代理
3.1 jdk动态代理
主要和InvocationHandler接口和Proxy类有关
- InvocationHandler:需要类来实现这个接口,重写invoke方法
- Proxy:用来根据类加载器、接口、实现InvocationHandler的类生成代理对象,调用代理对象的方法就可以调用真正需要调用类的方法。
package com.liu.proxy.jdk;
public interface Subject {
void select();
}
package com.liu.proxy.jdk;
public class SubjectImpl implements Subject{
@Override
public void select() {
System.out.println("真正的查询返回");
}
}
package com.liu.proxy.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocation implements InvocationHandler {
Object subject;
public ProxyInvocation(Object subject){
this.subject = subject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("查询前验证");
method.invoke(subject,args);
System.out.println("查询后处理");
return null;
}
public static void main(String[] args) {
Subject subject = new SubjectImpl();
Subject subject1 = (Subject)Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), new ProxyInvocation(subject));
subject1.select();
}
}
3.2 cglib动态代理
主要采用父子类方式实现
- MethodInterceptor:需要实现这个接口来实现动态代理
- Enhancer:增强类,需要设置要代理的类为其父类
package com.liu.proxy.cglib;
import com.liu.proxy.jdk.SubjectImpl;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.util.Arrays;
public class CglibProxy implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
// System.out.println(o);
System.out.println(method);
System.out.println(Arrays.toString(objects));
System.out.println(methodProxy);
System.out.println("执行前处理");
Object invoke = methodProxy.invokeSuper(o, objects);
System.out.println("执行后确认");
return null;
}
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SubjectImpl.class);
enhancer.setCallback(new CglibProxy());
SubjectImpl subject = (SubjectImpl) enhancer.create();
subject.select();
}
}