Singleton class to be shared among multiple portle

2019-02-14 23:57发布

问题:

I have a couple of Singleton classes in a Liferay application that hold several configuration parameters and a ServiceLocator with instances to WebServices I need to consume.

I have put these classes in a jar that is declared as a dependency on all my portlets.

The thing is, I have put some logging lines for initialization in theses singleton classes, and when I deploy my portlets I can see these lines multiple times, once for every portlet, since each portlet has its own class context.

For the AppConfig class it might not be such a big deal but my ServiceLocator does actually hold a bunch of references that take a good bit of memory.

Is there any way that I can put these Singleton references in some kind of Shared context in my Liferay Portal?

回答1:

The problem is that every Portlet runs in its own WAR file and aech war file has its own classloader.

Usually when I had to achieve a requirement like this, I had to put the Singleton classen in a JAR file and this JAR file in the common class loader library instead of packing it into each WAR. (In Tomcat: <tomcatHome>/common/lib or something like that)

Then you'll also have to put all dependent libraries into that common lib dir, too. Don't know how to do that in Liferay, though. For tomcat see this thread: stackoverflow.com/questions/267953/ and this documentation: http://tomcat.apache.org/tomcat-7.0-doc/class-loader-howto.html. Depends on the Servlet container.



回答2:

Alexander's answer gives the general answer that's true with or without Liferay in mind.

Liferay (as you mention it) adds another option to this: ServiceBuilder. You'll end up with the actual instances contained in exactly one web application, and you'll have an interfacing jar that you can distribute with every dependent application. This way you can more easily update your implementation: It's easy to hot-deploy new and updated web applications to your application server - it's harder to update code that's living on the global classpath.

The global classpath (Alexander's answer) however brings you immediate success while ServiceBuilder comes with its own learning curve and introduces some more dependencies. I don't mind those dependencies, but your mileage might vary. Decide for yourself



回答3:

With maven portlet you can make a common Spring component and import in the pom of each portlet. Another solution is to use service builder. Spring MVC portlet would be the most recommended for this.



标签: java liferay