Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Spring as a dependency injection framework with play 2.4.x?

I am exploring play-scala 2.4.2 and trying to get the spring DI working with it. I see there are a lot of changes in play 2.4.x and old way of overriding the GlobalSettings.getControllerInstance seems to be no more an option.

I came across this project https://github.com/jroper/play-spring, but it seems to be more of a POC proving that Spring DI is possible but does not seems to be as easy as in earlier play versions. Will this be the spring integration mechanism for current and future play versions or a simpler mechanism or framework can be expected sometime soon from the play community?

like image 278
Gaurav Abbi Avatar asked Jul 11 '15 18:07

Gaurav Abbi


2 Answers

Please follow the following steps:

Step1: Add the spring dependencies in build.sbt file.

libraryDependencies += "org.springframework" % "spring-context" % "4.1.6.RELEASE"
libraryDependencies += "org.springframework" % "spring-core" % "4.1.6.RELEASE"
libraryDependencies += "org.springframework" % "spring-beans" % "4.1.6.RELEASE"
libraryDependencies += "org.springframework" % "spring-aop" % "4.1.6.RELEASE"

Step2: Create a new class (ApplicationGlobalSettings.java) and that implements with GlobalSettings class.

package com.ranga.global.settings;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import play.Application;
import play.GlobalSettings;
public class ApplicationGlobalSettings extends GlobalSettings { 


private static final String APPLICATION_CONTEXT_XML = "applicationContext.xml";
private ConfigurableApplicationContext applicationContext;

@Override
public void beforeStart(Application application) {      
    super.beforeStart(application);
}

@Override
public void onStart(Application application) {      
    super.onStart(application);     
    applicationContext = new ClassPathXmlApplicationContext(APPLICATION_CONTEXT_XML);           
}

@Override
public void onStop(Application application) {       
    super.onStop(application);
    if(applicationContext != null) {
        applicationContext.close();
    }
}

}

Step3: Create a new spring configuration file under conf folder (applicationContext.xml) conf\applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

   <context:component-scan base-package="com.ranga.services, com.ranga.daos"/>

</beans>

Step4: Add the newly created GlobalSettings file location to the application configuration file (conf/application.conf).

.....some more configuration here.....
# Global Objects class
application.global=com.ranga.global.settings.ApplicationGlobalSettings

Step5: Create a new service class under com.ranga.service package (HelloWorldService.java).

package com.ranga.services;
import javax.inject.Inject;
import org.springframework.stereotype.Service;

import com.ranga.daos.HelloWorldDAO;
@Service
public class HelloWorldService {

    @Inject
    private HelloWorldDAO helloWorldDAO;

    public String sayHello() {
        return helloWorldDAO.sayHello();
    }
}

Step6: Create a new dao class under com.ranga.daos package (HelloWorldDAO.java).

package com.ranga.daos;

import org.springframework.stereotype.Repository;
@Repository
public class HelloWorldDAO {
    public String sayHello() {
        return "Hello Ranga!";
    }
}

Step7: Finally inject the HelloWorldService in Application.java file.

package com.ranga.controllers;

import javax.inject.Inject;

import org.springframework.beans.factory.annotation.Autowired;

import com.ranga.services.HelloWorldService;

import play.*;
import play.mvc.*;

import views.html.*;

public class Application extends Controller {

    @Inject
    private HelloWorldService helloWorldService;

    public Result index() {         
        return ok(index.render(helloWorldService.sayHello()));
    }
}

Step8: Finally modify the index.scala.html file code.

@(message: String)

<h1>@message</h1>

Now done.. run the application.

like image 104
Ranga Reddy Avatar answered Nov 18 '22 17:11

Ranga Reddy


The latest version of Play:

Create the class Global (Old Global than extended GlobaSettings):

@Singleton
public class Global {

    private static final String APPLICATION_CONTEXT = "applicationContext.xml";

    private ConfigurableApplicationContext applicationContext;

    @Inject
    public Global( ApplicationLifecycle lifecycle ) {
        applicationContext = new ClassPathXmlApplicationContext(APPLICATION_CONTEXT_XML);
        lifecycle.addStopHook( () -> {
            applicationContext.close();
            return F.Promise.pure( null );
        });
    }

}

Create the class ConfigurableApplicationContextModule:

public class ApplicationContextModule extends AbstractModule {

    @Override
    protected void configure() {
        bind( Global.class ).asEagerSingleton();
    }

}

In application.conf add this:

play.modules.enabled += "config.ApplicationContextModule"

Create file applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

       <context:component-scan base-package="services, dao"/>

</beans>

After creating what stated above by Ranga

like image 20
Alfaville Avatar answered Nov 18 '22 16:11

Alfaville