jdk代理
- 通常说的动态代理就是指jdk代理。
- 通过jdk的api在运行期间,动态生成代理对象。
- 目标对象一定要实现接口。
JDK代理的API:
Proxy
static newProxyInstance()
//接口
interface IDao{
void save();
void find();
}
//实现类
class Dao implements IDao{
@Override
public void save(){
System.out.println("模拟存储数据");
}
@Override
public void find(){
System.out.println("模拟查询数据");
}
}
//代理工厂
class ProxyFactory {
//返回目标对象的代理对象
public static Object getProxyInstance(Object target) {
Object newProxyInstance = Proxy.newProxyInstance(
target.getClass().getClassLoader(),//类加载器
target.getClass().getInterfaces(),//类实现的接口
new InvocationHandler() {//触发器,执行代理对象的方法时触发
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//获取执行方法的方法名(用于判断)
String methodName = method.getName();
System.out.println("[---前置代理操作---]");
Object invoke = method.invoke(target, args);
System.out.println("[---后置代理操作---]");
return invoke;
}
}
);
return newProxyInstance;
}
}
//测试
public class test {
@Test
public void test(){
IDao dao = new Dao();
IDao proxyInstance =(IDao)ProxyFactory.getProxyInstance(dao);
proxyInstance.save();
}
}
cglib代理
也叫“子类代理”
当目标对象没有实现接口,就不能使用jdk代理,可以以子类的方式实现。
//目标类
class Dao{
public void save(){
System.out.println("模拟存储数据");
}
public void find(){
System.out.println("模拟查询数据");
}
}
//代理工厂
class ProxyFactory {
//返回目标对象的代理对象
public static Object getProxyInstance(Object target) {
//多目标对象生成代理对象
//1.字节码生成工具
Enhancer enhancer = new Enhancer();
//2.设置代理对象的类型
enhancer.setSuperclass(target.getClass());
//3.设置回调方法(调用目标方法时触发)
enhancer.setCallback(
new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//获取执行方法的方法名(用于判断)
String methodName = method.getName();
System.out.println("[---前置代理操作---]");
Object invoke = method.invoke(target, objects);
System.out.println("[---后置代理操作---]");
return invoke;
}
}
);
//4.创建对象并返回
return enhancer.create();
}
}
//测试
public class test {
@Test
public void test(){
Dao dao = new Dao();
Dao proxyInstance = (Dao)ProxyFactory.getProxyInstance(dao);
proxyInstance.save();
}
}