Using Spring in a standalone application - java

i am looking for samples or tutorials of using Spring in a standalone (desktop/swing) application, i searched a lot but couldn't get to something useful, all the examples and tutorials are for web applications, please advise.

Create the standalone application with maven, as pointed here:
Create a standalone application with Maven
Put the applicationContext in classpath, and load it in the main class as follows:
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext("applicationContext.xml");
See full article here:
http://www.devdaily.com/blog/post/java/load-spring-application-context-file-java-swing-application

Here's a simple example with 2 classes. Wrote in groovy for ease of reading, but will run for you in java too with proper syntax tweaks
Here's your main:
class Main {
static void main(String[] args) {
def ctx = new AnnotationConfigApplicationContext()
ctx.register(AppConfig.class)
ctx.refresh()
def runner = ctx.getBean("mainRunner")
runner.run()
}
void run() {
println "running from bean"
}
}
Here's your config bean:
#Configuration
class AppConfig {
#Bean
Main mainRunner() {
new Main()
}
}

AppFuse provides different demo applications, all the source code can be downloaded using maven. You can get the complete code of this demo application which is build using Spring MVC,Spring, Hibernate.
Yes this is a web application, you can dig into it and convert it to a stand alone one.

create a Maven project
it will create an Application class for your project
#Configuration
#ComponentScan
#EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
//SpringApplication.run(YourClass.class, args);
YourClass.main(args);
}
}
put YourClass main method in there instead of SpringApplication.run(YourClass.class,args);
it works that way just fine.

When I first started to learn spring I followed these tutorials:
tutorialspoint
They are fairly basic but will get you up and running quickly. After this is ultimately
comes down to what you are going to use it for. Are you looking for IOC, JMS, JDBC/Hibernate support etc etc?
As mentioned already:
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext");
will bring all your spring beans into your app regardless of what type it is.

This is the first thing I found on google. It looks fair good too.
http://www.mkyong.com/spring/maven-spring-hibernate-annotation-mysql-example/

Take a look at "Barebones Spring". I think it's a nice, up to date example of how to use Spring 3.

This is the tutorial of Spring which I found to be very useful. This explains Spring based on a Standalone application.
https://www.youtube.com/watch?v=GB8k2-Egfv0
Author of this videos also has updated the Maven and Struts videos and explained it in a simple but in an effective way.
I hope it helps.

I have managed to run a standalone Spring Boot application with Swing.
public static void main(String[] args) {
ConfigurableApplicationContext ctx = new SpringApplicationBuilder(SwingApp.class)
.headless(false).run(args);
EventQueue.invokeLater(() -> {
SwingApp ex = ctx.getBean(SwingApp.class);
ex.setVisible(true);
});
}
We need to use the SpringApplicationBuilder and turn off the headless mode.
#SpringBootApplication
public class SwingApp extends JFrame {
The SwingApp is decorated with #SpringBootApplication annotation.
See my Spring Boot Swing integration tutorial for a full working example.

So, to boil it down: what makes your application (any type) a Spring application is the presence and use of at least one BeanFactory, usually extended as an ApplicationContext. In a web application you'd likely declare in web.xml a servlet such as DispatcherServlet which takes care of instantiating and initializing the context; in a standalone application your own code just makes and initializes a context, as shown above. The web framework stuff that magically gives you a context is doing pretty much the same thing under the covers.

Following 4 libraries are needed for a minimal standalone Spring application :
commons-logging.jar (see http://commons.apache.org/logging)
org.springframework.core-2.5.6.A.jar (see
http://www.springsource.org/download)
org.springframework.beans-2.5.6.A.jar (see
http://www.springsource.org/download)
org.springframework.context-2.5.6.A.jar (see
http://www.springsource.org/download)
A good example is given here.

Related

Moving to the Spring Boot. Migration of logic from the old main class

I am very new to Spring Boot and development, so, I am stuck with a problem. I have an old project that needs to be migrated to Spring Boot. The original main method has super cool multi-threaded logic. In my understanding public static void main(String[] args) was entry point to the program, now after creating Spring Boot project #springbootapplication is entry point. How to access the original logic of a method? Should it somehow be transform? I spent hours looking for a suitable solution but no luck. Could you point me? Any help is appreciated :)
You have to use #SpringBootApplication, but also need to modify the main method something like:
#SpringBootApplication
public class YourMainApplicationClass {
public static void main(String[] args) {
SpringApplication.run(YourMainApplicationClass.class, args);
}
}
This will start your application.
Then move your original code of your main method to a new class, which has annotation #Component. Implement CommandLineRunner, and override the run method. So something like:
#Component
public class YourOldMainClass implements CommandLineRunner {
#Override
public void run(String... args) throws Exception {
//Your code here
}
}
When your application starts, spring will load 'near everything' with annotation into its container, so your #Component annotated class should be also loaded. The CommandLineRunner with overrode run method will auto call your method at startup.
Also, don't forget to include necessary spring boot jars next to your project, or to your build automation tool - like Maven - if you use it.

Spring Shell - usage and execution

I want to integrate Spring Shell within a spring boot application. I am able to execute the examples from the official git-repo. But when migrating the example code to my own project that is very very similar to this code, my individual shell is not shown or usable. Instead the default Spring Shell splash is shown is usable:
<SpringShell ASCII-Art>
1.1.0.RELEASE
Welcome to Spring Shell. For assistance press or type "hint" then hit ENTER
spring-shell>
Compilation gives no errors, but the individual sample #component marked classes are not used. All annotations are properly set. A standard loader outside is existent. I am not executing the code in an IDE.
Although the documentation (chapter 3.5) tells, that the components are automatically collected as far as i understood.
So my question is more or less how to setup the usage better than
this:
public class Main {
public static void main(String[] args) throws Exception {
Bootstrap.main(args);
}
}
And to defeat the default splash!
That comment in the documentation is a bit misleading (I'll change it).
For your components to be picked up, they need to be on the classpath AND you'll need to scan for them somehow.
See for example how in the Spring XD project, there is a scan for the org.springframework.xd.shell package. You need to do something similar for your own package.
SOLUTION:
ebottard's answer brought me to the point of creating a "spring-shell-plugin.xml" under resources\META-INF\spring\... Although the component scan was set externally already, this seems to be necessary. The following code shows how to start it up within an Spring Boot Application where CommandLineRunner is implemented. This should bridge starting problems.
#Component
public class CLIBean implements CommandLineRunner {
#Override
public void run(String... args) throws Exception {
Bootstrap bootstrap = new Bootstrap();
bootstrap.run();
}
}

How to use embedded openejb from a java SE application?

I am writing a little java library that is intended to be used in a web-application as well as by a java console-application.
In order to profit from CDI and other javaEE 6 features and not having to maintain two versions (java EE and java SE) of the library I'd like to use openejb (embedded) for the console-application.
So I've built a maven project in eclipse and added the openejb artifact.
Somehow I just don't get how to make the console program use the openejb-container, that is resolve my injections and other javaEE features.
Lets say I have two very simple classes:
#Stateless
Class A {
#Inject
public B member;
public A() {};
}
and
#Stateless
Class B {
public B() {};
public String getString () {
return "Hello";
}
}
So, how would I get a plain old java class with a main() method make instantiate a member of A using the embedded openejb? - in a way like:
public class TestOpenEJB {
public static void main(String[] args) {
Class A a = new A(); /*wrong of couse*/
System.out.println( a.member.getString() );
}
}
A working solution for this simple example would be helpful.
Finally, my aim here is to provide a java SE api for a library that uses an embedded javaEE container internally.
Thanks a lot!
Additional to my comments, I think your problem can be answered in this way:
Go on and model your library's behaviour with EJBs (as shown in your code example). This is a good approach, since the container cares about things like pooling, parallel access, transactions and such.
Then your web application (assuming it's in the same container) can just use those EJBs directly.
And for accessing it via a console application, you can either run it within an application client container (which is preferable than trying to embed a container in your application), or (which I would recommend) expose your business logic in an additional way (e.g. via REST) and use that in a standalone client application.
PS: For integration testing your business logic with DI mechanisms, use Arquillian.

Spring: how to get hold of Application context in Webapp and Standalone program

I'm new to the Spring Framework. We want to introduce it (3.1) in a web application, currently using struts in the web layer, service facades and business objects in the business layer and self-written JDBC DAOs in the persistence layer (all of it closely coupled!)
I created several .xml configurations, one for the servlet config, scanning the com.mydomain.web package only. Another one on the service layer appContext-service.xml which scans com.mydomain.bs and .bo packages and one for the DAO layer appContext-persistence.xml scanning the .dao package.
We have four Eclipse projects with appropriate project dependencies: Web, Business, Common (contains domain objects, DTOs, Exceptions, etc), DataAccess.
I want to use annotations where possible and already created a MVC controller, a new service with interface and a new dao with interface, using the JDBC template, which all works great.
Now my questions are:
We can't re-write all the code at once, we're talking about a larger code base here. But what do I do, when the newly created service is also needed from services and business objects that are not (yet) Spring aware? They're not beans or not being created by Spring. How would I get hold of my service bean?
We have several standalone applications for batch processing, cleaning up the file system and database tables periodically, etc. They're triggered by cron (UNIX cron) and therefore have their own JVM. How would I best use Spring services here, given the different .xml configurations?
Does my setup make any sense at all?
Thanks for any insight.
It's very common that one let spring handle the lifecycle of all the beans, otherwise it might get a bit tricky. The objects that are not spring beans are hopefully initialized somewhere. Make that initializer a spring bean and make it application context aware
public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public void init(){
ServiceBean1 srv1 = (ServiceBean1)applicationContext.getBean("serviceBean1");
myNonSpringObject.setService1(srv1); // Or something
}
}
Setting up a standalone spring app is very easy. Just create a Spring XML and wire your beans (either via scanning/annotations or XML). It is not really recommended to do this in the main method, but you could easily figure out how to get this setup in your standalone application. Keep in mind that your application itself should not really do much lifecycle logic but let Spring do that.
public class StandaloneSpringApp{
public static void main(String[] args){
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
SomeBeanType bean = (SomeBeanType)ctx.getBean("SomeBeanName");
bean.doProcessing(); // or whatever
}
}
Your setup makes perfect sense, even though I cannot visualize your entire scope, your approach is a good starting point for a large modularized spring application.

Designing a Java library with Spring

I am extracting some functionality from an existing program into a separate library.
This program uses Spring for dependency injection and other tasks and I'd like to keep using it in the library as well.
This library needs to monitor the filesystem for changes, so it will kick off some kind of separate thread to do this.
I don't really know what my options are for initialisation of the library:
How do I initialise the library's context? I cannot assume that library users will make use of Spring too, but I can distribute Spring with the library.
How do I manage my filesystem monitoring thread? Is it good design to expect the program to instantiate a main class of the library and the call init or something like that?
How do I initialise the library's context? I cannot assume that
library users will make use of Spring too, but I can distribute Spring
with the library.
I am writing a library using Spring context as well and I did something like that, assuming your library is called FooLib, has two services called FooService and BarService and a class called SpringContext that configures your spring context through java config:
public final class FooLib {
private static ApplicationContext applicationContext;
private FooLib() {
}
public static FooService getFooService() {
return getApplicationContext().getBean(FooService.class);
}
public static BarService getBarService() {
return getApplicationContext().getBean(BarService.class);
}
private static ApplicationContext getApplicationContext() {
if (applicationContext == null) {
applicationContext = new AnnotationConfigApplicationContext(SpringContext.class);
}
return applicationContext;
}
}
Then a client can use BarService this way:
BarService barService = FooLib.getBarService();
How do I manage my filesystem monitoring thread? Is it good design to
expect the program to instantiate a main class of the library and the
call init or something like that?
You can start your monitoring subsystem statically within Spring context, inside the SpringContext class, for example.
#Configuration
#ComponentScan(basePackages = "com.yourgroupid.foolib")
public class SpringContext {
#Bean
public MonitoringSystem monitoringSystem() {
MonitoringSystem monitoringSystem = new MonitoringSystem();
monitoringSystem.start();
return monitoringSystem;
}
}
That should be enough because Spring creates its beans eagerly by default.
Cheers
How do I initialise the library's context? I cannot assume that library users will make use of Spring too, but I can distribute Spring with the library.
It's up to your library to instantiate spring the way you need it. This is typically done in your interface entrypoint which delegates to a routine using e.g., ClassPathXmlApplicationContext to configure spring. A sample could be
public class SpringContextLoader {
private static ApplicationContext ctx = null;
public static void init() {
if (ctx == null) {
ctx = ClassPathXmlApplicationContext("classpath:/applicatonContext.xml");
}
}
}
How do I manage my filesystem monitoring thread? Is it good design to expect the program to instantiate a main class of the library and the call init or something like that?
In this case you will probably provide a non-daemon thread, e.g., a thread which must be terminated manually for the application to exit cleanly. Hence you should provide start and stop mechanisms. In your case these probably better be called registerEventListener and unregisterAllEventListener (since I'm guessing you want to pass filesystem events to the client ... ). Another alternative could be to use quartz scheduling with spring.
How do I initialise the library's context? I cannot assume that library users will make use of Spring too, but I can distribute Spring with the library.
You can use a PropertyPlaceholderConfigurer to read configuration settings from a (possibly external) property file, which can be edited by the users. This way users aren't exposed to the details of Spring, not even to XML config files.
How do I manage my filesystem monitoring thread? Is it good design to expect the program to instantiate a main class of the library and the call init or something like that?
I recommend using the Java concurrency framework, specifically a ScheduledExecutorService to run monitoring task(s) at specified intervals. However, you may want to hide this implementation detail from the users of your library, by only exposing some init method to pass in the desired timer interval.
As far as I know, it is not possible to configure your library to start a thread automatically, you have to define a class as starting point. Using Maven you can create an executable jar:
http://maven.apache.org/plugins/maven-shade-plugin/examples/executable-jar.html
In your main class, simple use:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:myspring-context.xml");
context.registerShutdownHook();
For threads, you can try either implementing the runnable interface, and initialize a bean which starts the threads using spring task executors. A more elegant solution that I can suggest is however creating your thread as a pojo and then using spring task scheduler, as follows:
<bean id="threadPojo" class="com.mydomain.ThreadPojo">
</bean>
<task:scheduled-tasks scheduler="mydomainTaskScheduler">
<task:scheduled ref="threadPojo" method="process" fixed-delay="${delay-pool}"/>
</task:scheduled-tasks>
<task:scheduler id="mydomainTaskScheduler" pool-size="${my-pool-size}" />
I hope it will be helpful.

Categories

Resources