静态代理通产的实现方式是被代理类实现了某个接口,然后创建一个代理类也实现该接口,然后在代理类构造器中传入被代理类的一个实例对代理类的内部接口引用初始化,然后通过代理类对象在调用接口中的方法的时候实质执行的是被代理类的方法;
缺点:一个被代理类就需要创建一个代理类,当代理类过多的时候,代码量冗余量很大且很多重复代码,也不利于后期的维护;
jdk静态代理的目的是在主业务代码的前后新增一些非业务处理,如:记录日志,事务处理等。
实现静态代理的前提:
1、代理类和被代理类实现了同一接口
2、被代理类需要实现具体继承接口中的方法
3、代理类调用的是具体类中的方法(也就是说代理类中需要接受一个被代理类的对象)
代理类不实现同一个接口,就没有代理类的意义了,跟普通函数调用有什么区别呢。代理类只有继承了接口,在加载的时候,程序才能知道代理类和被代理类之间的对应关系。才能做出相应的处理。
动态代理应用而生,是java反射的很好的应用,也是Spring AOP的核心,体现了Java语言的动态性;
1.2 引入动态代理动态代理不像静态代理一样,每个代理类在编译阶段已经确定,动态代理的代理类是在运行阶段才根据传入的被代理类对象被动态创建的
实现动态代理必须解决的问题:
- 如何根据加载到内存的被代理类动态的创建一个代理类对象
- 如何通过调用被代理类对象的方法进而去调用被代理类的方法?
//动态代理的实现,运行时根据动态传入的对象动态创建类
class MyInvocationHandler implements InvocationHandler{
public Object obj;
//bind方法进行绑定,传入的是被代理类的对象,告知你要动态的去代理哪个被代理类,执行谁的方法
void bind(Object obj){
this.obj = obj;
}
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
//通过反射拿到代理类要执行的被代理类中的同名同参方法,调用代理类的方法实质会跳转执行被代理类的方法——这就是动态代理
return method.invoke(obj, objects);
}
}
class ProxyFactory{
public static Object getProxyInstance(Object obj){
MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
myInvocationHandler.bind(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), myInvocationHandler);
}
}
class Test11{
public static void main(String[] args) {
//动态的创建一个学生类的代理类,执行代理类的方法默认转去执行被代理类学生的对应方法
Person studentProxy = (Person)ProxyFactory.getProxyInstance(new Student());
studentProxy.eat();
studentProxy.sing();
System.out.println("*************分割线*************");
//现在我们想要代理老师,执行老师的方法,只需将被代理类的对象传给动态代理工厂的创建代理类对象的方法,即可生成一个代理老师的代理类
Person teacherProxy = (Person) ProxyFactory.getProxyInstance(new Teacher());
teacherProxy.eat();
teacherProxy.sing();
}
}
执行结果图:
自己的简单理解,但是自己还有一个疑问:就是InvovationHandler接口的实现类中的方法invoke的第一个参数Object o
他为什么没有使用?是代理类proxy么?
如果有看到的大佬希望不吝赐教!小弟感激涕零!!!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)