Java的回调

来源:互联网 发布:淘宝小样四大靠谱店 编辑:程序博客网 时间:2024/06/14 13:54

Java回调机制
先解释一下回调:回调是在使用时才能确定调用的是那一个函数的函数,体现最明显的应该就是框架,在设计中声明这个方法但是却不实现这个方法,由框架的使用者去实现这个方法,在程序运行中当用到这个方法时框架自己去调用框架使用者提供的这个方法。实现手段一般是声明一个接口,那么这个接口的实现类就能实现某些功能,在调用时将调用这个接口实现类中的方法,在C++中使用函数指针可以实现,C#中使用委托可以实现,而在Java中则是使用java多态性,在运行期间传一个实现类对象的引用,然后根据Java多态性去掉用实现类对象的接口实现方法。
直接上代码

public interface CallBack {    //接口的方法,实现该接口的类将是回调的对象    void callBack();}public class CallBackImpl implements CallBack {    @Override    public void callBack() {        System.out.println("call Back Test");    }}public class UseCallBack {    static CallBack call;    public static void main(String[] args) {        useCallBack(new CallBackImpl());    }    /*     * Java中使用回调的时候将CallBack接口的一个实现的类传入方法中实现回调,     * Java根据多态的特性去掉用CallBackImpl类中的CallBack接口的实现方法     */    public static void useCallBack(CallBack callBack){        call = callBack;        call.callBack();    }}

回调的原理已经说完了,现在就该说如何才能让程序自动调用接口的实现类,在Java也就是说如何传一个接口实现类的对象进去,毕竟写了一个接口的实现类总要让程序能够自动的去实现这个功能,总不能向上面的代码那样手动去调用方法并且传递一个接口实现类的参数把。现在的问题就变成了如何让程序知道那些类实现了回调接口,并自动去掉用其中的方法。
经过我的思考和查找,发现有两种方法:
1.第一种是进行配置,在程序启动的时候读取配置,在使用时通过反射创建对象进行回调。这种方法需要配置,麻烦但是程序启动速度快并且占用系统资源少,适用于大型的项目。
2.第二种是在程序启动的时候扫描程序路径下所有的类找到实现回调接口的类并将其保存起来,在需要的时候进行实例化。这种方法便洁不用进行特殊的配置但是相对的程序启动的速度就慢,占用系统资源多,适用于小型的项目。

Spring框架中的做法:
举例:在Spring框架中,有一个接口是ApplicationListener,它可以实现对Spring容器的监听,而实现了触发事件为ContextRefreshedEvent事件的该接口可以在Spring容器初始化之后进行一些操作。在写完操作的方法后将其配置到Spring的配置文件中就可以看到效果

public class InitTask implements ApplicationListener<ContextRefreshedEvent> {    public void onApplicationEvent(ContextRefreshedEvent event) {        System.out.println(123);    }}

在Spring的BeanFactory初始化Bean的过程中会发现他实现了接口并将其保存起来,在容器初始化完毕后进行回调。但是这样也有一个弊端,就是这个类会被一直保存到内存中,一直存放在spring的BeanFactory中,会占用内存资源,如果想要其不占资源还得获取BeanFactory对象进行removeRegister的操作或者继承初始化配置文件的类重写方法或者新创建一个类内容为修改这个类后的内容,并使用自己修改后的类进行容器的初始化。

原创粉丝点击