Wicket 应用程序、序列化和 Java 计时器 [英] Wicket Application, Serialization and Java Timers

查看:32
本文介绍了Wicket 应用程序、序列化和 Java 计时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在序列化、Wicket 和多线程项目方面的经验有些有限,所以请耐心等待.

So I have somewhat limited experience with serialization, Wicket, and multi thread projects so bear with me.

本质上,我的 Web 应用程序类正在实例化一个 POJ(父对象),它创建一个启动新计时器并实例化几个也有计时器的子对象.这些 childObject 存储在 parentObject 类中的列表中.我的 wicket 应用程序中的页面需要访问 parentObject,因此我将其设为可访问:

Essentially my web application class is instantiating a POJ (parentObject) which creates a starts a new timer and instantiates several childObjects that also have timers in them. These childObjects are stored in a list in the parentObject class. Pages in my wicket application need to access parentObject, so I made it accessible as so:

public Object getParentObject
{
   return this.parentObject;
}

它在每个页面中都像这样检索:

And it is retrieved in each page like so:

((MyApplication)Application.get()).getParentObject()

目前的问题是 parentObject 和 childObjects 的 timertask 不再像它们应该的那样每分钟被调用一次.我的日志记录了父对象的第一次启动,但是日志消息再也没有输出,表明父对象的 timertask 的 run() 方法不是每分钟都在执行.

The problem currently is that the timertask for both the parentObject and childObjects are no longer being called every minute as they should be. My logs pick up the first start of the parentObject, but the logging message is never outputted again signalling that the run() method of parent Object's timertask is not being executed every minute.

添加了更多代码以更清楚地说明问题

Added some more code to make it more clear the issue

public class childObject implements Serializable
{
    private transient NamedParameterJdbcTemplate njt;
    private transient Timer timer;

    public childObject(DataSource ds)
    {
        this.njt = new NamedParamterJdbcTemplate(ds);
    }

    public void start()
    {
        timer = new Timer();

        timer.schedule(new TimerTask(){

            public void run()
            {
                //do some stuff that is never happening
            }

        }, 0, 60000);
    }
}

public class ParentObject implements Serializable
{
    private DataSource ds;
    private List<ChildObject> childObjects;
    private transient Timer;

    public ParentObject(DataSource ds)
    {
        this.ds = ds;
        //add some stuff to childObjects

        timer = new Timer();

        timer.schedule(new TimerTask(){

            public void run()
            {
                for(some condition)
                {
                    //Do some stuff

                    if(/*condition is met*/)
                    {
                        childObjects.get(i).start();
                    }
                }
            }

        }, 0, 60000);
    }
}

public MyApplication extends WebApplication
{
    private ParentObject object;
    private DataSource ds;

    public void init()
    {
        super.init();

        ApplicationContext context = new ClassPathXmlApplicationContext("/applicationContext.xml");
        ds = (DataSource) context.getBean("dataSource");

        parentObject = new ParentObject(ds);
    }
}

推荐答案

根据您的问题描述,我认为您将 ParentObject 直接绑定到您的组件,而不是绑定到 ParentObject 的引用.会话范围对象(所有页面、组件和模型实际上都是如此)的序列化/反序列化会创建这些新"实例(即使它们是原始父对象的反序列化副本).

Given your problem description I figure you bind your ParentObject directly to your components instead of binding a reference to the ParentObject. The serialization/deserialization of session scoped objects (which all pages, components and models in effect are) creates these 'new' instances (even though they are deserialized copies of the original parent object).

虽然你没有展示太多代码,但我怀疑你做了这样的事情:

While you have not shown much code, I suspect you do something like this:

public MyPage() {
    Object parentObject = ((MyApplication)Application.get()).getParentObject();
    add(new Label("timer", new PropertyModel(parentObject, "time")));
}

这将父对象绑定到属性模型,并将父对象绑定到页面(通过标签组件).你应该做的是:

This binds the parent object to the property model, and that binds the parent object to the page (through the label component). What you should do instead is:

public MyPage() {
    add(new Label("timer", new PropertyModel(this, "application.parentObject.time")));
}

这会将页面绑定到自身,并指示属性模型动态检索应用程序,从应用程序获取父对象,并从中获取时间.这样您就不会将对象绑定到页面层次结构,而是动态检索它们.

This binds the page to itself, and instructs the property model to retrieve the application dynamically, and from the application the parent object, and from that the time. This way you don't bind your objects to the page hierarchy, but retrieve them dynamically.

另一种选择是使用 LoadableDetachableModel 从应用程序中检索父对象,并在呈现页面后将其分离.

Another option is to use a LoadableDetachableModel that retrieves the parent object from the application, and detaches it after rendering the page.

public class ParentObjectModel extends LoadableDetachableModel<ParentObject> {
    @Override public ParentObject load() {
        return ((MyApplication)Application.get()).getParentObject();
    }
}

有关模型的更多信息,请参阅 Wicket wiki.

See the Wicket wiki for more information on Models.

这篇关于Wicket 应用程序、序列化和 Java 计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆