动态代理的两种实现方式
1、动态代理介绍
动态代理:在不改变目标对象方法的情况下对方法进行增强
组成:
-
被代理对象:真实的对象 代理对象:内存中的对象
要求:代理对象必须和被代理对象实现相同的接口
代理的实现方式有两种:(1)jdk动态代理;(2)CGLIB动态代理(这个是第三方实现的,所以使用这种方式,我们要引入jar包)
2、代码准备
StudentInterface接口代码
public interface StudentInterface {
void eat(String name);
void study();
}
Student代码
public class Student implements StudentInterface{
public void eat(String name) {
System.out.println("学生吃" + name);
}
public void study() {
System.out.println("在家自学");
}
}
Test代码
public class Test {
public static void main(String[] args) {
Student stu = new Student();
stu.eat("米饭");
stu.study();
}
}
3、要求
要求:在不改动Student类中任何的代码的前提下,通过study方法输出一句话:来大学学习。
4、方法一:使用jdk动态代理
public class Test {
public static void main(String[] args) {
Student stu = new Student();
/*stu.eat("米饭");
stu.study();*/
/*
类加载器:和被代理对象使用相同的类加载器
接口类型Class数组:和被代理对象使用相同接口
代理规则:完成代理增强的功能
*/
StudentInterface proxyStu = (StudentInterface) Proxy.newProxyInstance(stu.getClass().getClassLoader(), new Class[]{StudentInterface.class}, new InvocationHandler() {
/*
执行Student类中所有的方法都会经过invoke方法
对method方法进行判断
如果是study,则对其增强
如果不是,还调用学生对象原有的功能即可
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("study")) {
System.out.println("来大学学习");
return null;
}else {
return method.invoke(stu,args);
}
}
});
proxyStu.eat("米饭");
proxyStu.study();
}
}
5、方式二:使用CGLIB动态代理
CGLIB jar的maven坐标
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.1_2</version> </dependency>
public class Test {
public static void main(String[] args) {
Student stu = new Student();
/*stu.eat("米饭");
stu.study();*/
Object proxyStu = Enhancer.create(stu.getClass(), new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
if (method.getName().equals("study")) {
System.out.println("来大学学习");
return null;
} else {
return method.invoke(stu, args);
}
}
}
proxyStu.eat("米饭");
proxyStu.study();
}
}
与jdk动态代理相比,CGLIB不要求必须要实现接口StudentInterface ,就能直接对目标对象就行代理增强,更加的简单方便。
