动态代理:(个人理解)就是为了在已经固有的代码的基础上,在方法已经完整的基础上。通过不直接修改类的方法,无侵入地为包装好的类的方法添加其他成分。
为什么需要动态代理:无侵入地给对象增加功能。
应用场景:在团队合作中无法修改别人地代码地时候,开闭原则(对增加开放,对修改闭合)或者是在已经完整地项目上,防止无意修改掉正确地部分。
简述动态代理中地各个要素:
目的对象(目的类):也是就需要往这个要素上添加一些功能(目前认为是往方法中添加功能)
接口:目的类中需要代理地方法抽象化放在接口中。
JavaBean类:主要作用是包含生成代理对象地(静态)方法。
测试类:测试动态代理是否成功。
难点:1.理解整个动态代理地过程。2.理解创建代理对象的静态方法:Proxy.newProxyInstance( 1 2 3);
代码示例:
JavaBean类:(代理的目标类)
public class Kun implements Myinterface{
String name;
public String sing (String name){
System.out.println("开始唱歌");
return "开始唱"+name;
}
public String dance(String name){
System.out.println("开始跳舞");
return "开始条"+name;
}
public Kun() {
}
public Kun(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "Kun{name = " + name + "}";
}
}
自定义接口:
public interface Myinterface {
public String sing(String name);
public String dance(String name);
}
生成代理对象的所在类:(主要类,难点类)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Myproxy {
public static Myinterface creatproxy(Kun k){
//注意返回的是代理对象,但是可以强制转换成接口对象
Myinterface mp= (Myinterface) Proxy.newProxyInstance(Myproxy.class.getClassLoader(),//类加载器
new Class[]{Myinterface.class}, //接口的class放在数组中作为参数
new InvocationHandler() {//匿名内部类,主要是代理的方法和参数
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("sing".equals(method.getName())){
System.out.println("准备唱歌");
}
if("dance".equals(method.getName()))
System.out.println("准备跳舞");
return method.invoke(k,args);
}
});
return mp;//整个方法返回一个接口对象
}
}
测试类:
public class Main {
public static void main(String[] args) {
Kun k = new Kun();//创建目的类对象
Myinterface mp = Myproxy.creatproxy(k);//将目的类对象传入创建代理对象,多态化地形式用接口地类型接收
String 五星红旗 = mp.sing("五星红旗");//调用方法,调用地时候,发生了动态代理
System.out.println(五星红旗);
String 篮球操 = mp.dance("篮球操");
System.out.println(篮球操);
}
}
完整的过程展示(截图,帮助理解)