Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for dynamic languages refreshable beans in @Configuration classes [SPR-12300] #16906

Open
spring-issuemaster opened this issue Oct 6, 2014 · 7 comments

Comments

Projects
None yet
1 participant
@spring-issuemaster
Copy link
Collaborator

commented Oct 6, 2014

Baruch Sadogursky opened SPR-12300 and commented

As suggested by Artem, it makes sense to add @EnableScripting and @ScriptSource(refreshDelay = 1000) on the Resource @Bean method.


Affects: 4.1 GA

Reference URL: http://stackoverflow.com/questions/26208020/using-spring-dynamic-languages-support-from-java-configuration

Issue Links:

  • #14886 Refreshing annotated Groovy controllers cause ClassCastException
  • #9888 ScriptFactory for JSR-223
  • #12691 Unable to define a scripted bean as an inner bean of another bean
  • INTEXT-130 Provide support for dynamic scripts (Groovy, JRuby etc.) within the flow definition

8 votes, 12 watchers

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jan 23, 2015

Artem Bilan commented

The linked issue INTEXT-130 isn't related to the subject, but like a case to gather more info.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 14, 2015

Juergen Hoeller commented

I'm afraid this might not make it into 4.2 RC1... too much on the plate still, and a rather hard deadline towards the end of May.

Juergen

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Aug 24, 2015

Nick Grealy commented

Hi all, what's required in order to get this delivered (what's been done, what needs to be done)? I'm happy to contribute dev effort to get this into a release. (related? #14886 )

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Sep 16, 2015

Thomas Darimont commented

It would be helpful to have javaconfig support for this - currently you have to write quite a bit of boiler-plate to get this working with Java Config:
https://gist.github.com/thomasdarimont/f7f2ef6f4900b9f89d58

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Sep 22, 2015

Thomas Darimont commented

One approach could be to provide an easy to configure FactoryBean that would create Proxies backed by a AbstractRefreshableTargetSource which in turn (optionally) perform the reloading after a confgured time interval.

With this in place all the user would have to do to define a refreshable bean backed by a groovy script
would be something along the lines of:

@Bean
public GroovyScript myScriptBean() {
    return new GroovyScript("classpath:MyScriptBean.groovy", MyScriptInterface.class).refreshEvery(1, SECONDS);
}

A quick API sketch for this can be found here: https://gist.github.com/thomasdarimont/9fe86c61208c340e875a

With respect to the @EnableScripting idea.

I could imagine the following (with and without spring-boot):

@EnableScripting(lang=GROOVY, sourceSource="scripts", refreshCheckDelay=500, proxyTargetClass=false)
@SpringBootApplication
class App{
    ...
}

@EnableScripting could then some kind of "script-scanning" that
automatically picks up (groovy) scripts under the given "source" directory.
It could also automatically turn scripts like the one below into appropriate spring beans.
Note: one could also have special @EnableGroovyScripting via annotation composition - or even provide a spring-boot-starter-groovy with that enabled.

scripts/MyScript.groovy:

class MyScript implements MyInterface{
    def someOperation(){
    ...
       return someResult
    }
}

would result in a spring bean named "myScript" of type "MyInterface" with default refresh-settings and default-proxing applied.

For groovy it is easy to derive the expected interface that should be proxied iif the groovy class implements it directly. In other cases (e.g. for other script languages) one needs additional metadata for that, perhaps within the script itself, perhaps in the form of a special marker comment or within a separate file right next to it.
I think being able to explicitly define script (factory) beans via an API, similiar to what I sketched above, could be used to explicitly define the interface type to be proxied in a pragmatic way.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Sep 23, 2015

Artem Bilan commented

Hi Thomas Darimont!

Thank you for digging in this area.

Yes, I definitely agreed that some short FactoryBean definition is the best way to go. It is Java, it is Spring and it is obvious from the IDE code completion perspective.

My current idea for the @EnableScripting is around the Groovy ability to use annotations. With that we may get a gain from the same @ComponentScan which looks for the Groovy scripts as well, loads them as classes and populate appropriate beans with the desired refreshCheckDelay feature extracting some annotation on the Groovy class.

Looks like we can use annotations with Ruby as well: http://www.weblogism.com/item/342/java-annotations-with-jruby-a-spring-mvc-example. Although it doesn't mean that we will be able to parse its class

All others require further investigation, Although I'm not sure how this feature works with JavaScript... I mean the interface implementation.

So, having the long story for this JIRA, we really may just end up with the FactoryBean and that's all. Even without involving ScriptFactoryPostProcessor as it is in your PoC.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Jan 21, 2016

Juergen Hoeller commented

Let's turn this into a 5.0 feature theme. We have enough on our plate for 4.3, and this one should be done comprehensively... It would also benefit from a milestone phase which 4.3 doesn't have (we're going straight to RC1 in March there).

Juergen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.