diff --git a/framework-docs/modules/ROOT/nav.adoc b/framework-docs/modules/ROOT/nav.adoc index d1706fe3626..e51cc221fa3 100644 --- a/framework-docs/modules/ROOT/nav.adoc +++ b/framework-docs/modules/ROOT/nav.adoc @@ -456,7 +456,6 @@ *** xref:languages/kotlin/getting-started.adoc[] *** xref:languages/kotlin/resources.adoc[] ** xref:languages/groovy.adoc[] -** xref:languages/dynamic.adoc[] * xref:appendix.adoc[] * {spring-framework-docs-root}/{spring-version}/javadoc-api/[Java API,window=_blank, role=link-external] * {spring-framework-api-kdoc}/[Kotlin API,window=_blank, role=link-external] diff --git a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc index ea79cbfb22f..2becb1d7eed 100644 --- a/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc +++ b/framework-docs/modules/ROOT/pages/core/beans/factory-extension.adoc @@ -194,8 +194,7 @@ The following `beans` element uses the `InstantiationTracingBeanPostProcessor`: Notice how the `InstantiationTracingBeanPostProcessor` is merely defined. It does not even have a name, and, because it is a bean, it can be dependency-injected as you would any other bean. (The preceding configuration also defines a bean that is backed by a Groovy -script. The Spring dynamic language support is detailed in the chapter entitled -xref:languages/dynamic.adoc[Dynamic Language Support].) +script.) The following Java application runs the preceding code and configuration: diff --git a/framework-docs/modules/ROOT/pages/languages/dynamic.adoc b/framework-docs/modules/ROOT/pages/languages/dynamic.adoc deleted file mode 100644 index fd43782cea0..00000000000 --- a/framework-docs/modules/ROOT/pages/languages/dynamic.adoc +++ /dev/null @@ -1,830 +0,0 @@ -[[dynamic-language]] -= Dynamic Language Support - -Spring provides comprehensive support for using classes and objects that have been -defined by using a dynamic language (such as Groovy) with Spring. This support lets -you write any number of classes in a supported dynamic language and have the Spring -container transparently instantiate, configure, and dependency inject the resulting -objects. - -Spring's scripting support primarily targets Groovy and BeanShell. Beyond those -specifically supported languages, the JSR-223 scripting mechanism is supported -for integration with any JSR-223 capable language provider, for example, JRuby. - -You can find fully working examples of where this dynamic language support can be -immediately useful in xref:languages/dynamic.adoc#dynamic-language-scenarios[Scenarios]. - - -[[dynamic-language-a-first-example]] -== A First Example - -The bulk of this chapter is concerned with describing the dynamic language support in -detail. Before diving into all of the ins and outs of the dynamic language support, -we look at a quick example of a bean defined in a dynamic language. The dynamic -language for this first bean is Groovy. (The basis of this example was taken from the -Spring test suite. If you want to see equivalent examples in any of the other -supported languages, take a look at the source code). - -The next example shows the `Messenger` interface, which the Groovy bean is going to -implement. Note that this interface is defined in plain Java. Dependent objects that -are injected with a reference to the `Messenger` do not know that the underlying -implementation is a Groovy script. The following listing shows the `Messenger` interface: - -[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"] ----- - package org.springframework.scripting; - - public interface Messenger { - - String getMessage(); - } ----- - -The following example defines a class that has a dependency on the `Messenger` interface: - -[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"] ----- - package org.springframework.scripting; - - public class DefaultBookingService implements BookingService { - - private Messenger messenger; - - public void setMessenger(Messenger messenger) { - this.messenger = messenger; - } - - public void processBooking() { - // use the injected Messenger object... - } - } ----- - -The following example implements the `Messenger` interface in Groovy: - -[source,groovy,indent=0,subs="verbatim,quotes",chomp="-packages",fold="none"] ----- - package org.springframework.scripting.groovy - - // Import the Messenger interface (written in Java) that is to be implemented - import org.springframework.scripting.Messenger - - // Define the implementation in Groovy in file 'Messenger.groovy' - class GroovyMessenger implements Messenger { - - String message - } ----- - -[NOTE] -==== -To use the custom dynamic language tags to define dynamic-language-backed beans, you -need to have the XML Schema preamble at the top of your Spring XML configuration file. -You also need to use a Spring `ApplicationContext` implementation as your IoC -container. Using the dynamic-language-backed beans with a plain `BeanFactory` -implementation is supported, but you have to manage the plumbing of the Spring internals -to do so. - -For more information on schema-based configuration, see xref:languages/dynamic.adoc#xsd-schemas-lang[XML Schema-based Configuration] -. -==== - -Finally, the following example shows the bean definitions that effect the injection of the -Groovy-defined `Messenger` implementation into an instance of the -`DefaultBookingService` class: - -[source,xml,indent=0,subs="verbatim,quotes"] ----- - - - - - - - - - - - - - - ----- - -The `bookingService` bean (a `DefaultBookingService`) can now use its private `messenger` -member variable as normal, because the `Messenger` instance that was injected into it is -a `Messenger` instance. There is nothing special going on here -- just plain Java and -plain Groovy. - -Hopefully, the preceding XML snippet is self-explanatory, but do not worry unduly if it is not. -Keep reading for the in-depth detail on the whys and wherefores of the preceding configuration. - - -[[dynamic-language-beans]] -== Defining Beans that Are Backed by Dynamic Languages - -This section describes exactly how you define Spring-managed beans in any of the -supported dynamic languages. - -Note that this chapter does not attempt to explain the syntax and idioms of the supported -dynamic languages. For example, if you want to use Groovy to write certain of the classes -in your application, we assume that you already know Groovy. If you need further details -about the dynamic languages themselves, see -xref:languages/dynamic.adoc#dynamic-language-resources[Further Resources] at the end of -this chapter. - -[[dynamic-language-beans-concepts]] -=== Common Concepts - -The steps involved in using dynamic-language-backed beans are as follows: - -. Write the test for the dynamic language source code (naturally). -. Then write the dynamic language source code itself. -. Define your dynamic-language-backed beans by using the appropriate `` - element in the XML configuration (you can define such beans programmatically by - using the Spring API, although you will have to consult the source code for - directions on how to do this, as this chapter does not cover this type of advanced configuration). - Note that this is an iterative step. You need at least one bean definition for each dynamic - language source file (although multiple bean definitions can reference the same source file). - -The first two steps (testing and writing your dynamic language source files) are beyond -the scope of this chapter. See the language specification and reference manual -for your chosen dynamic language and crack on with developing your dynamic language -source files. You first want to read the rest of this chapter, though, as -Spring's dynamic language support does make some (small) assumptions about the contents -of your dynamic language source files. - -[[dynamic-language-beans-concepts-xml-language-element]] -==== The element - -The final step in the list in the xref:languages/dynamic.adoc#dynamic-language-beans-concepts[preceding section] -involves defining dynamic-language-backed bean definitions, one for each bean that you -want to configure (this is no different from normal JavaBean configuration). However, -instead of specifying the fully qualified class name of the class that is to be -instantiated and configured by the container, you can use the `` -element to define the dynamic language-backed bean. - -Each of the supported languages has a corresponding `` element: - -* `` (Groovy) -* `` (BeanShell) -* `` (JSR-223, for example, with JRuby) - -The exact attributes and child elements that are available for configuration depends on -exactly which language the bean has been defined in (the language-specific sections -later in this chapter detail this). - -[[dynamic-language-refreshable-beans]] -==== Refreshable Beans - -One of the (and perhaps the single) most compelling value adds of the dynamic language -support in Spring is the "`refreshable bean`" feature. - -A refreshable bean is a dynamic-language-backed bean. With a small amount of -configuration, a dynamic-language-backed bean can monitor changes in its underlying -source file resource and then reload itself when the dynamic language source file is -changed (for example, when you edit and save changes to the file on the file system). - -This lets you deploy any number of dynamic language source files as part of an -application, configure the Spring container to create beans backed by dynamic -language source files (using the mechanisms described in this chapter), and (later, -as requirements change or some other external factor comes into play) edit a dynamic -language source file and have any change they make be reflected in the bean that is -backed by the changed dynamic language source file. There is no need to shut down a -running application (or redeploy in the case of a web application). The -dynamic-language-backed bean so amended picks up the new state and logic from the -changed dynamic language source file. - -NOTE: This feature is off by default. - -Now we can take a look at an example to see how easy it is to start using refreshable -beans. To turn on the refreshable beans feature, you have to specify exactly one -additional attribute on the `` element of your bean definition. So, -if we stick with xref:languages/dynamic.adoc#dynamic-language-a-first-example[the example] from earlier in -this chapter, the following example shows what we would change in the Spring XML -configuration to effect refreshable beans: - -[source,xml,indent=0,subs="verbatim,quotes"] ----- - - - - - script-source="classpath:Messenger.groovy"> - - - - - - - - ----- - -That really is all you have to do. The `refresh-check-delay` attribute defined on the -`messenger` bean definition is the number of milliseconds after which the bean is -refreshed with any changes made to the underlying dynamic language source file. -You can turn off the refresh behavior by assigning a negative value to the -`refresh-check-delay` attribute. Remember that, by default, the refresh behavior is -disabled. If you do not want the refresh behavior, do not define the attribute. - -If we then run the following application, we can exercise the refreshable feature. -(Please excuse the "`jumping-through-hoops-to-pause-the-execution`" shenanigans -in this next slice of code.) The `System.in.read()` call is only there so that the -execution of the program pauses while you (the developer in this scenario) go off -and edit the underlying dynamic language source file so that the refresh triggers -on the dynamic-language-backed bean when the program resumes execution. - -The following listing shows this sample application: - -[source,java,indent=0,subs="verbatim,quotes"] ----- - import org.springframework.context.ApplicationContext; - import org.springframework.context.support.ClassPathXmlApplicationContext; - import org.springframework.scripting.Messenger; - - public final class Boot { - - public static void main(final String[] args) throws Exception { - ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); - Messenger messenger = (Messenger) ctx.getBean("messenger"); - System.out.println(messenger.getMessage()); - // pause execution while I go off and make changes to the source file... - System.in.read(); - System.out.println(messenger.getMessage()); - } - } ----- - -Assume then, for the purposes of this example, that all calls to the `getMessage()` -method of `Messenger` implementations have to be changed such that the message is -surrounded by quotation marks. The following listing shows the changes that you -(the developer) should make to the `Messenger.groovy` source file when the -execution of the program is paused: - -[source,groovy,indent=0,subs="verbatim,quotes",chomp="-packages"] ----- - package org.springframework.scripting - - class GroovyMessenger implements Messenger { - - private String message = "Bingo" - - public String getMessage() { - // change the implementation to surround the message in quotes - return "'" + this.message + "'" - } - - public void setMessage(String message) { - this.message = message - } - } ----- - -When the program runs, the output before the input pause will be `I Can Do The Frug`. -After the change to the source file is made and saved and the program resumes execution, -the result of calling the `getMessage()` method on the dynamic-language-backed -`Messenger` implementation is `'I Can Do The Frug'` (notice the inclusion of the -additional quotation marks). - -Changes to a script do not trigger a refresh if the changes occur within the window of -the `refresh-check-delay` value. Changes to the script are not actually picked up until -a method is called on the dynamic-language-backed bean. It is only when a method is -called on a dynamic-language-backed bean that it checks to see if its underlying script -source has changed. Any exceptions that relate to refreshing the script (such as -encountering a compilation error or finding that the script file has been deleted) -results in a fatal exception being propagated to the calling code. - -The refreshable bean behavior described earlier does not apply to dynamic language -source files defined with the `` element notation (see -xref:languages/dynamic.adoc#dynamic-language-beans-inline[Inline Dynamic Language Source Files]). -Additionally, it applies only to beans where changes to the underlying source file can -actually be detected (for example, by code that checks the last modified date of a -dynamic language source file that exists on the file system). - -[[dynamic-language-beans-inline]] -==== Inline Dynamic Language Source Files - -The dynamic language support can also cater to dynamic language source files that are -embedded directly in Spring bean definitions. More specifically, the -`` element lets you define dynamic language source immediately -inside a Spring configuration file. An example might clarify how the inline script -feature works: - -[source,xml,indent=0,subs="verbatim,quotes"] ----- - - - - package org.springframework.scripting.groovy - - import org.springframework.scripting.Messenger - - class GroovyMessenger implements Messenger { - String message - } - - - - ----- - -If we put to one side the issues surrounding whether it is good practice to define -dynamic language source inside a Spring configuration file, the `` -element can be useful in some scenarios. For instance, we might want to quickly add a -Spring `Validator` implementation to a Spring MVC `Controller`. This is but a moment's -work using inline source. (See -xref:languages/dynamic.adoc#dynamic-language-scenarios-validators[Scripted Validators] -for such an example.) - -[[dynamic-language-beans-ctor-injection]] -==== Understanding Constructor Injection in the Context of Dynamic-language-backed Beans - -There is one very important thing to be aware of with regard to Spring's dynamic -language support. Namely, you can not (currently) supply constructor arguments -to dynamic-language-backed beans (and, hence, constructor-injection is not available for -dynamic-language-backed beans). In the interests of making this special handling of -constructors and properties 100% clear, the following mixture of code and configuration -does not work: - -.An approach that cannot work -[source,groovy,indent=0,subs="verbatim,quotes",chomp="-packages"] ----- - package org.springframework.scripting.groovy - - import org.springframework.scripting.Messenger - - // from the file 'Messenger.groovy' - class GroovyMessenger implements Messenger { - - GroovyMessenger() {} - - // this constructor is not available for Constructor Injection - GroovyMessenger(String message) { - this.message = message; - } - - String message - - String anotherMessage - } ----- - -[source,xml,indent=0,subs="verbatim,quotes"] ----- - - - - - - - - - ----- - -In practice this limitation is not as significant as it first appears, since setter -injection is the injection style favored by the overwhelming majority of developers -(we leave the discussion as to whether that is a good thing to another day). - -[[dynamic-language-beans-groovy]] -=== Groovy Beans - -This section describes how to use beans defined in Groovy in Spring. - -The Groovy homepage includes the following description: - -"`Groovy is an agile dynamic language for the Java 2 Platform that has many of the -features that people like so much in languages like Python, Ruby and Smalltalk, making -them available to Java developers using a Java-like syntax.`" - -If you have read this chapter straight from the top, you have already -xref:languages/dynamic.adoc#dynamic-language-a-first-example[seen an example] of a Groovy-dynamic-language-backed -bean. Now consider another example (again using an example from the Spring test suite): - -[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"] ----- - package org.springframework.scripting; - - public interface Calculator { - - int add(int x, int y); - } ----- - -The following example implements the `Calculator` interface in Groovy: - -[source,groovy,indent=0,subs="verbatim,quotes",chomp="-packages"] ----- - package org.springframework.scripting.groovy - - // from the file 'calculator.groovy' - class GroovyCalculator implements Calculator { - - int add(int x, int y) { - x + y - } - } ----- - -The following bean definition uses the calculator defined in Groovy: - -[source,xml,indent=0,subs="verbatim,quotes"] ----- - - - - ----- - -Finally, the following small application exercises the preceding configuration: - -[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"] ----- - package org.springframework.scripting; - - import org.springframework.context.ApplicationContext; - import org.springframework.context.support.ClassPathXmlApplicationContext; - - public class Main { - - public static void main(String[] args) { - ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); - Calculator calc = ctx.getBean("calculator", Calculator.class); - System.out.println(calc.add(2, 8)); - } - } ----- - -The resulting output from running the above program is (unsurprisingly) `10`. -(For more interesting examples, see the dynamic language showcase project for a more -complex example or see the examples xref:languages/dynamic.adoc#dynamic-language-scenarios[Scenarios] later in this chapter). - -You must not define more than one class per Groovy source file. While this is perfectly -legal in Groovy, it is (arguably) a bad practice. In the interests of a consistent -approach, you should (in the opinion of the Spring team) respect the standard Java -conventions of one (public) class per source file. - -[[dynamic-language-beans-groovy-customizer]] -==== Customizing Groovy Objects by Using a Callback - -The `GroovyObjectCustomizer` interface is a callback that lets you hook additional -creation logic into the process of creating a Groovy-backed bean. For example, -implementations of this interface could invoke any required initialization methods, -set some default property values, or specify a custom `MetaClass`. The following listing -shows the `GroovyObjectCustomizer` interface definition: - -[source,java,indent=0,subs="verbatim,quotes"] ----- - public interface GroovyObjectCustomizer { - - void customize(GroovyObject goo); - } ----- - -The Spring Framework instantiates an instance of your Groovy-backed bean and then -passes the created `GroovyObject` to the specified `GroovyObjectCustomizer` (if one -has been defined). You can do whatever you like with the supplied `GroovyObject` -reference. We expect that most people want to set a custom `MetaClass` with this -callback, and the following example shows how to do so: - -[source,java,indent=0,subs="verbatim,quotes"] ----- - public final class SimpleMethodTracingCustomizer implements GroovyObjectCustomizer { - - public void customize(GroovyObject goo) { - DelegatingMetaClass metaClass = new DelegatingMetaClass(goo.getMetaClass()) { - - public Object invokeMethod(Object object, String methodName, Object[] arguments) { - System.out.println("Invoking '" + methodName + "'."); - return super.invokeMethod(object, methodName, arguments); - } - }; - metaClass.initialize(); - goo.setMetaClass(metaClass); - } - - } ----- - -A full discussion of meta-programming in Groovy is beyond the scope of the Spring -reference manual. See the relevant section of the Groovy reference manual or do a -search online. Plenty of articles address this topic. Actually, making use of a -`GroovyObjectCustomizer` is easy if you use the Spring namespace support, as the -following example shows: - -[source,xml,indent=0,subs="verbatim,quotes"] ----- - - - - - ----- - -If you do not use the Spring namespace support, you can still use the -`GroovyObjectCustomizer` functionality, as the following example shows: - -[source,xml,indent=0,subs="verbatim,quotes"] ----- - - - - - - - - - ----- - -NOTE: You may also specify a Groovy `CompilationCustomizer` (such as an `ImportCustomizer`) -or even a full Groovy `CompilerConfiguration` object in the same place as Spring's -`GroovyObjectCustomizer`. Furthermore, you may set a common `GroovyClassLoader` with custom -configuration for your beans at the `ConfigurableApplicationContext.setClassLoader` level; -this also leads to shared `GroovyClassLoader` usage and is therefore recommendable in case of -a large number of scripted beans (avoiding an isolated `GroovyClassLoader` instance per bean). - -[[dynamic-language-beans-bsh]] -=== BeanShell Beans - -This section describes how to use BeanShell beans in Spring. - -The https://beanshell.github.io/intro.html[BeanShell homepage] includes the following -description: - ----- -BeanShell is a small, free, embeddable Java source interpreter with dynamic language -features, written in Java. BeanShell dynamically runs standard Java syntax and -extends it with common scripting conveniences such as loose types, commands, and method -closures like those in Perl and JavaScript. ----- - -In contrast to Groovy, BeanShell-backed bean definitions require some (small) additional -configuration. The implementation of the BeanShell dynamic language support in Spring is -interesting, because Spring creates a JDK dynamic proxy that implements all of the -interfaces that are specified in the `script-interfaces` attribute value of the -`` element (this is why you must supply at least one interface in the value -of the attribute, and, consequently, program to interfaces when you use BeanShell-backed -beans). This means that every method call on a BeanShell-backed object goes through the -JDK dynamic proxy invocation mechanism. - -Now we can show a fully working example of using a BeanShell-based bean that implements -the `Messenger` interface that was defined earlier in this chapter. We again show the -definition of the `Messenger` interface: - -[source,java,indent=0,subs="verbatim,quotes",chomp="-packages"] ----- - package org.springframework.scripting; - - public interface Messenger { - - String getMessage(); - } ----- - -The following example shows the BeanShell "`implementation`" (we use the term loosely here) -of the `Messenger` interface: - -[source,java,indent=0,subs="verbatim,quotes"] ----- - String message; - - String getMessage() { - return message; - } - - void setMessage(String aMessage) { - message = aMessage; - } ----- - -The following example shows the Spring XML that defines an "`instance`" of the above -"`class`" (again, we use these terms very loosely here): - -[source,xml,indent=0,subs="verbatim,quotes"] ----- - - - - ----- - -See xref:languages/dynamic.adoc#dynamic-language-scenarios[Scenarios] for some scenarios -where you might want to use BeanShell-based beans. - - -[[dynamic-language-scenarios]] -== Scenarios - -The possible scenarios where defining Spring managed beans in a scripting language would -be beneficial are many and varied. This section describes two possible use cases for the -dynamic language support in Spring. - -[[dynamic-language-scenarios-controllers]] -=== Scripted Spring MVC Controllers - -One group of classes that can benefit from using dynamic-language-backed beans is that -of Spring MVC controllers. In pure Spring MVC applications, the navigational flow -through a web application is, to a large extent, determined by code encapsulated within -your Spring MVC controllers. As the navigational flow and other presentation layer logic -of a web application needs to be updated to respond to support issues or changing -business requirements, it may well be easier to effect any such required changes by -editing one or more dynamic language source files and seeing those changes being -immediately reflected in the state of a running application. - -Remember that, in the lightweight architectural model espoused by projects such as -Spring, you typically aim to have a really thin presentation layer, with all -the meaty business logic of an application being contained in the domain and service -layer classes. Developing Spring MVC controllers as dynamic-language-backed beans lets -you change presentation layer logic by editing and saving text files. Any -changes to such dynamic language source files is (depending on the configuration) -automatically reflected in the beans that are backed by dynamic language source files. - -NOTE: To effect this automatic "`pickup`" of any changes to dynamic-language-backed -beans, you have to enable the "`refreshable beans`" functionality. See -xref:languages/dynamic.adoc#dynamic-language-refreshable-beans[Refreshable Beans] for a full treatment of this feature. - -The following example shows an `org.springframework.web.servlet.mvc.Controller` implemented -by using the Groovy dynamic language: - -[source,groovy,indent=0,subs="verbatim,quotes",chomp="-packages"] ----- - package org.springframework.showcase.fortune.web - - import org.springframework.showcase.fortune.service.FortuneService - import org.springframework.showcase.fortune.domain.Fortune - import org.springframework.web.servlet.ModelAndView - import org.springframework.web.servlet.mvc.Controller - - import jakarta.servlet.http.HttpServletRequest - import jakarta.servlet.http.HttpServletResponse - - // from the file '/WEB-INF/groovy/FortuneController.groovy' - class FortuneController implements Controller { - - @Property FortuneService fortuneService - - ModelAndView handleRequest(HttpServletRequest request, - HttpServletResponse httpServletResponse) { - return new ModelAndView("tell", "fortune", this.fortuneService.tellFortune()) - } - } ----- - -[source,xml,indent=0,subs="verbatim,quotes"] ----- - - - ----- - -[[dynamic-language-scenarios-validators]] -=== Scripted Validators - -Another area of application development with Spring that may benefit from the -flexibility afforded by dynamic-language-backed beans is that of validation. It can -be easier to express complex validation logic by using a loosely typed dynamic language -(that may also have support for inline regular expressions) as opposed to regular Java. - -Again, developing validators as dynamic-language-backed beans lets you change -validation logic by editing and saving a simple text file. Any such changes is -(depending on the configuration) automatically reflected in the execution of a -running application and would not require the restart of an application. - -NOTE: To effect the automatic "`pickup`" of any changes to dynamic-language-backed -beans, you have to enable the 'refreshable beans' feature. See -xref:languages/dynamic.adoc#dynamic-language-refreshable-beans[Refreshable Beans] -for a full and detailed treatment of this feature. - -The following example shows a Spring `org.springframework.validation.Validator` -implemented by using the Groovy dynamic language (see -xref:core/validation/validator.adoc[Validation using Spring’s Validator interface] -for a discussion of the `Validator` interface): - -[source,groovy,indent=0,subs="verbatim,quotes"] ----- - import org.springframework.validation.Validator - import org.springframework.validation.Errors - import org.springframework.beans.TestBean - - class TestBeanValidator implements Validator { - - boolean supports(Class clazz) { - return TestBean.class.isAssignableFrom(clazz) - } - - void validate(Object bean, Errors errors) { - if(bean.name?.trim()?.size() > 0) { - return - } - errors.reject("whitespace", "Cannot be composed wholly of whitespace.") - } - } ----- - - -[[dynamic-language-final-notes]] -== Additional Details - -This last section contains some additional details related to the dynamic language support. - -[[dynamic-language-final-notes-aop]] -=== AOP -- Advising Scripted Beans - -You can use the Spring AOP framework to advise scripted beans. The Spring AOP -framework actually is unaware that a bean that is being advised might be a scripted -bean, so all of the AOP use cases and functionality that you use (or aim to use) -work with scripted beans. When you advise scripted beans, you cannot use class-based -proxies. You must use xref:core/aop/proxying.adoc[interface-based proxies]. - -You are not limited to advising scripted beans. You can also write aspects themselves -in a supported dynamic language and use such beans to advise other Spring beans. -This really would be an advanced use of the dynamic language support though. - -[[dynamic-language-final-notes-scopes]] -=== Scoping - -In case it is not immediately obvious, scripted beans can be scoped in the same way as -any other bean. The `scope` attribute on the various `` elements lets -you control the scope of the underlying scripted bean, as it does with a regular -bean. (The default scope is xref:core/beans/factory-scopes.adoc#beans-factory-scopes-singleton[singleton], -as it is with "`regular`" beans.) - -The following example uses the `scope` attribute to define a Groovy bean scoped as -a xref:core/beans/factory-scopes.adoc#beans-factory-scopes-prototype[prototype]: - -[source,xml,indent=0,subs="verbatim,quotes"] ----- - - - - - - - - - - - - ----- - -See xref:core/beans/factory-scopes.adoc[Bean Scopes] in -xref:web/webmvc-view/mvc-xslt.adoc#mvc-view-xslt-beandefs[The IoC Container] -for a full discussion of the scoping support in the Spring Framework. - -[[xsd-schemas-lang]] -=== The `lang` XML schema - -The `lang` elements in Spring XML configuration deal with exposing objects that have been -written in a dynamic language (such as Groovy or BeanShell) as beans in the Spring container. - -These elements (and the dynamic language support) are comprehensively covered in -xref:languages/dynamic.adoc[Dynamic Language Support]. See that section -for full details on this support and the `lang` elements. - -To use the elements in the `lang` schema, you need to have the following preamble at the -top of your Spring XML configuration file. The text in the following snippet references -the correct schema so that the tags in the `lang` namespace are available to you: - -[source,xml,indent=0,subs="verbatim,quotes"] ----- - - - - - - ----- - - -[[dynamic-language-resources]] -== Further Resources - -The following links go to further resources about the various dynamic languages referenced -in this chapter: - -* The https://www.groovy-lang.org/[Groovy] homepage -* The https://beanshell.github.io/intro.html[BeanShell] homepage -* The https://www.jruby.org[JRuby] homepage diff --git a/framework-docs/modules/ROOT/pages/languages/groovy.adoc b/framework-docs/modules/ROOT/pages/languages/groovy.adoc index e50f136b23b..ab86c3d0c22 100644 --- a/framework-docs/modules/ROOT/pages/languages/groovy.adoc +++ b/framework-docs/modules/ROOT/pages/languages/groovy.adoc @@ -9,6 +9,3 @@ existing Java application. The Spring Framework provides a dedicated `ApplicationContext` that supports a Groovy-based Bean Definition DSL. For more details, see xref:core/beans/basics.adoc#beans-factory-groovy[The Groovy Bean Definition DSL]. - -Further support for Groovy, including beans written in Groovy, refreshable script beans, -and more is available in xref:languages/dynamic.adoc[Dynamic Language Support]. diff --git a/spring-context/src/main/java/org/springframework/scripting/config/LangNamespaceHandler.java b/spring-context/src/main/java/org/springframework/scripting/config/LangNamespaceHandler.java index 5ecef5a6c68..2f25286b3ea 100644 --- a/spring-context/src/main/java/org/springframework/scripting/config/LangNamespaceHandler.java +++ b/spring-context/src/main/java/org/springframework/scripting/config/LangNamespaceHandler.java @@ -36,7 +36,9 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport; * @author Juergen Hoeller * @author Mark Fisher * @since 2.0 + * @deprecated with no replacement as not actively maintained anymore */ +@Deprecated(since = "7.0") public class LangNamespaceHandler extends NamespaceHandlerSupport { @Override diff --git a/spring-context/src/main/java/org/springframework/scripting/config/LangNamespaceUtils.java b/spring-context/src/main/java/org/springframework/scripting/config/LangNamespaceUtils.java index f3bdce9c1db..30607b0a955 100644 --- a/spring-context/src/main/java/org/springframework/scripting/config/LangNamespaceUtils.java +++ b/spring-context/src/main/java/org/springframework/scripting/config/LangNamespaceUtils.java @@ -27,7 +27,9 @@ import org.springframework.scripting.support.ScriptFactoryPostProcessor; * @author Rob Harrop * @author Mark Fisher * @since 2.5 + * @deprecated with no replacement as not actively maintained anymore */ +@Deprecated(since = "7.0") public abstract class LangNamespaceUtils { /** diff --git a/spring-context/src/main/java/org/springframework/scripting/config/ScriptBeanDefinitionParser.java b/spring-context/src/main/java/org/springframework/scripting/config/ScriptBeanDefinitionParser.java index 74b490e21e4..748961cf6c5 100644 --- a/spring-context/src/main/java/org/springframework/scripting/config/ScriptBeanDefinitionParser.java +++ b/spring-context/src/main/java/org/springframework/scripting/config/ScriptBeanDefinitionParser.java @@ -53,7 +53,9 @@ import org.springframework.util.xml.DomUtils; * @author Juergen Hoeller * @author Mark Fisher * @since 2.0 + * @deprecated with no replacement as not actively maintained anymore */ +@Deprecated(since = "7.0") class ScriptBeanDefinitionParser extends AbstractBeanDefinitionParser { private static final String ENGINE_ATTRIBUTE = "engine"; diff --git a/spring-context/src/main/java/org/springframework/scripting/config/ScriptingDefaultsParser.java b/spring-context/src/main/java/org/springframework/scripting/config/ScriptingDefaultsParser.java index 407c243e124..579d9d68867 100644 --- a/spring-context/src/main/java/org/springframework/scripting/config/ScriptingDefaultsParser.java +++ b/spring-context/src/main/java/org/springframework/scripting/config/ScriptingDefaultsParser.java @@ -30,7 +30,9 @@ import org.springframework.util.StringUtils; * * @author Mark Fisher * @since 2.5 + * @deprecated with no replacement as not actively maintained anymore */ +@Deprecated(since = "7.0") class ScriptingDefaultsParser implements BeanDefinitionParser { private static final String REFRESH_CHECK_DELAY_ATTRIBUTE = "refresh-check-delay"; diff --git a/spring-context/src/main/resources/org/springframework/scripting/config/spring-lang.xsd b/spring-context/src/main/resources/org/springframework/scripting/config/spring-lang.xsd index 09f690d4520..95bd671cdfa 100644 --- a/spring-context/src/main/resources/org/springframework/scripting/config/spring-lang.xsd +++ b/spring-context/src/main/resources/org/springframework/scripting/config/spring-lang.xsd @@ -11,7 +11,8 @@