Package org.springframework.scripting.support

# Class ScriptFactoryPostProcessor

java.lang.Object
org.springframework.scripting.support.ScriptFactoryPostProcessor

All Implemented Interfaces:
  `org.springframework.beans.factory.Aware`, `org.springframework.beans.factory.BeanClassLoaderAware`, `org.springframework.beans.factory.BeanFactoryAware`, `org.springframework.beans.factory.config.BeanPostProcessor`, `org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor`, `org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor`, `org.springframework.beans.factory.DisposableBean`, `ResourceLoaderAware`, `org.springframework.core.Ordered`

public class ScriptFactoryPostProcessor extends Object implements org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor, org.springframework.beans.factory.BeanClassLoaderAware, org.springframework.beans.factory.BeanFactoryAware, ResourceLoaderAware, org.springframework.beans.factory.DisposableBean, org.springframework.core.Ordered
`BeanPostProcessor` that handles `ScriptFactory` definitions, replacing each factory with the actual scripted Java object generated by it.

This is similar to the `FactoryBean` mechanism, but is specifically tailored for scripts and not built into Spring's core container itself but rather implemented as an extension.

NOTE: The most important characteristic of this post-processor is that constructor arguments are applied to the `ScriptFactory` instance while bean property values are applied to the generated scripted object. Typically, constructor arguments include a script source locator and potentially script interfaces, while bean property values include references and config values to inject into the scripted object itself.

The following `ScriptFactoryPostProcessor` will automatically be applied to the two `ScriptFactory` definitions below. At runtime, the actual scripted objects will be exposed for "bshMessenger" and "groovyMessenger", rather than the `ScriptFactory` instances. Both of those are supposed to be castable to the example's `Messenger` interfaces here.

    <bean class="org.springframework.scripting.support.ScriptFactoryPostProcessor"/>

     <bean id="bshMessenger" class="org.springframework.scripting.bsh.BshScriptFactory">
       <constructor-arg value="classpath:mypackage/Messenger.bsh"/>
       <constructor-arg value="mypackage.Messenger"/>
       <property name="message" value="Hello World!"/>
     </bean>

     <bean id="groovyMessenger" class="org.springframework.scripting.groovy.GroovyScriptFactory">
       <constructor-arg value="classpath:mypackage/Messenger.groovy"/>
       <property name="message" value="Hello World!"/>
     </bean>

NOTE: Please note that the above excerpt from a Spring XML bean definition file uses just the <bean/>-style syntax (in an effort to illustrate using the `ScriptFactoryPostProcessor` itself). In reality, you would never create a <bean/> definition for a `ScriptFactoryPostProcessor` explicitly; rather you would import the tags from the `'lang'` namespace and simply create scripted beans using the tags in that namespace... as part of doing so, a `ScriptFactoryPostProcessor` will implicitly be created for you.

The Spring reference documentation contains numerous examples of using tags in the `'lang'` namespace; by way of an example, find below a Groovy-backed bean defined using the `'lang:groovy'` tag.

     <?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:lang="http://www.springframework.org/schema/lang">

       <!-- this is the bean definition for the Groovy-backed Messenger implementation -->
       <lang:groovy id="messenger" script-source="classpath:Messenger.groovy">
         <lang:property name="message" value="I Can Do The Frug" />
       </lang:groovy>

       <!-- an otherwise normal bean that will be injected by the Groovy-backed Messenger -->
       <bean id="bookingService" class="x.y.DefaultBookingService">
         <property name="messenger" ref="messenger" />
       </bean>

     </beans>

Since:
  2.0
Author:
  Juergen Hoeller, Rob Harrop, Rick Evans, Mark Fisher, Sam Brannen

## Field Summary

Fields
Modifier and Type
Field
Description
`static final String`
`INLINE_SCRIPT_PREFIX`
The `Resource`-style prefix that denotes an inline script.
`static final String`
`LANGUAGE_ATTRIBUTE`
The `language` attribute.
`protected final org.apache.commons.logging.Log`
`logger`
Logger available to subclasses.
`static final String`
`PROXY_TARGET_CLASS_ATTRIBUTE`
The `proxyTargetClass` attribute.
`static final String`
`REFRESH_CHECK_DELAY_ATTRIBUTE`
The `refreshCheckDelay` attribute.

### Fields inherited from interface org.springframework.core.Ordered

`HIGHEST_PRECEDENCE, LOWEST_PRECEDENCE`

## Constructor Summary

Constructors
Constructor
Description
`ScriptFactoryPostProcessor()`

## Method Summary

Modifier and Type
Method
Description
`protected ScriptSource`
`convertToScriptSource(String beanName, String scriptSourceLocator, org.springframework.core.io.ResourceLoader resourceLoader)`
Convert the given script source locator to a ScriptSource instance.
`protected Class<?>`
`createCompositeInterface(Class<?>[] interfaces)`
Create a composite interface Class for the given interfaces, implementing the given interfaces in one single Class.
`protected Class<?>`
`createConfigInterface(org.springframework.beans.factory.config.BeanDefinition bd, Class<?>[] interfaces)`
Create a config interface for the given bean definition, defining setter methods for the defined property values as well as an init method and a destroy method (if defined).
`protected Object`
`createRefreshableProxy(org.springframework.aop.TargetSource ts, Class<?>[] interfaces, boolean proxyTargetClass)`
Create a refreshable proxy for the given AOP TargetSource.
`protected org.springframework.beans.factory.config.BeanDefinition`
`createScriptedObjectBeanDefinition(org.springframework.beans.factory.config.BeanDefinition bd, String scriptFactoryBeanName, ScriptSource scriptSource, Class<?>[] interfaces)`
Create a bean definition for the scripted object, based on the given script definition, extracting the definition data that is relevant for the scripted object (that is, everything but bean class and constructor arguments).
`protected org.springframework.beans.factory.config.BeanDefinition`
`createScriptFactoryBeanDefinition(org.springframework.beans.factory.config.BeanDefinition bd)`
Create a ScriptFactory bean definition based on the given script definition, extracting only the definition data that is relevant for the ScriptFactory (that is, only bean class and constructor arguments).
`void`
`destroy()`
Destroy the inner bean factory (used for scripts) on shutdown.
`int`
`getOrder()`
`protected ScriptSource`
`getScriptSource(String beanName, String scriptSourceLocator)`
Obtain a ScriptSource for the given bean, lazily creating it if not cached already.
`Object`
`postProcessBeforeInstantiation(Class<?> beanClass, String beanName)`
`org.springframework.beans.PropertyValues`
`postProcessProperties(org.springframework.beans.PropertyValues pvs, Object bean, String beanName)`
`Class<?>`
`predictBeanType(Class<?> beanClass, String beanName)`
`protected void`
`prepareScriptBeans(org.springframework.beans.factory.config.BeanDefinition bd, String scriptFactoryBeanName, String scriptedObjectBeanName)`
Prepare the script beans in the internal BeanFactory that this post-processor uses.
`protected boolean`
`resolveProxyTargetClass(org.springframework.beans.factory.config.BeanDefinition beanDefinition)`
`protected long`
`resolveRefreshCheckDelay(org.springframework.beans.factory.config.BeanDefinition beanDefinition)`
Get the refresh check delay for the given `ScriptFactory` `BeanDefinition`.
`void`
`setBeanClassLoader(ClassLoader classLoader)`
`void`
`setBeanFactory(org.springframework.beans.factory.BeanFactory beanFactory)`
`void`
`setDefaultProxyTargetClass(boolean defaultProxyTargetClass)`
Flag to signal that refreshable proxies should be created to proxy the target class not its interfaces.
`void`
`setDefaultRefreshCheckDelay(long defaultRefreshCheckDelay)`
Set the delay between refresh checks, in milliseconds.
`void`
`setResourceLoader(org.springframework.core.io.ResourceLoader resourceLoader)`
Set the ResourceLoader that this object runs in.

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Methods inherited from interface org.springframework.beans.factory.config.BeanPostProcessor

`postProcessAfterInitialization, postProcessBeforeInitialization`

### Methods inherited from interface org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor

`postProcessAfterInstantiation`

### Methods inherited from interface org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor

`determineBeanType, determineCandidateConstructors, getEarlyBeanReference`

## Field Details

### INLINE_SCRIPT_PREFIX

public static final String INLINE_SCRIPT_PREFIX
The `Resource`-style prefix that denotes an inline script.

An inline script is a script that is defined right there in the (typically XML) configuration, as opposed to being defined in an external file.

See Also:
  - Constant Field Values

### REFRESH_CHECK_DELAY_ATTRIBUTE

public static final String REFRESH_CHECK_DELAY_ATTRIBUTE
The `refreshCheckDelay` attribute.

### PROXY_TARGET_CLASS_ATTRIBUTE

public static final String PROXY_TARGET_CLASS_ATTRIBUTE
The `proxyTargetClass` attribute.

### LANGUAGE_ATTRIBUTE

public static final String LANGUAGE_ATTRIBUTE
The `language` attribute.

### logger

protected final org.apache.commons.logging.Log logger
Logger available to subclasses.

## Constructor Details

### ScriptFactoryPostProcessor

public ScriptFactoryPostProcessor()

## Method Details

### setDefaultRefreshCheckDelay

public void setDefaultRefreshCheckDelay(long defaultRefreshCheckDelay)
Set the delay between refresh checks, in milliseconds. Default is -1, indicating no refresh checks at all.

Note that an actual refresh will only happen when the `ScriptSource` indicates that it has been modified.

See Also:
  - `ScriptSource.isModified()`

### setDefaultProxyTargetClass

public void setDefaultProxyTargetClass(boolean defaultProxyTargetClass)
Flag to signal that refreshable proxies should be created to proxy the target class not its interfaces.

Parameters:
  `defaultProxyTargetClass` - the flag value to set

### setBeanClassLoader

public void setBeanClassLoader(ClassLoader classLoader)

Specified by:
  `setBeanClassLoader` in interface `org.springframework.beans.factory.BeanClassLoaderAware`

### setBeanFactory

public void setBeanFactory(org.springframework.beans.factory.BeanFactory beanFactory)

Specified by:
  `setBeanFactory` in interface `org.springframework.beans.factory.BeanFactoryAware`

### setResourceLoader

public void setResourceLoader(org.springframework.core.io.ResourceLoader resourceLoader)
Description copied from interface: `ResourceLoaderAware`
Set the ResourceLoader that this object runs in.

This might be a ResourcePatternResolver, which can be checked through `instanceof ResourcePatternResolver`. See also the `ResourcePatternUtils.getResourcePatternResolver` method.

Invoked after population of normal bean properties but before an init callback like InitializingBean's `afterPropertiesSet` or a custom init-method. Invoked before ApplicationContextAware's `setApplicationContext`.

Specified by:
  `setResourceLoader` in interface `ResourceLoaderAware`
Parameters:
  `resourceLoader` - the ResourceLoader object to be used by this object
See Also:
  - `ResourcePatternResolver`
  - `ResourcePatternUtils.getResourcePatternResolver(org.springframework.core.io.ResourceLoader)`

### getOrder

public int getOrder()

Specified by:
  `getOrder` in interface `org.springframework.core.Ordered`

### predictBeanType

@Nullable public Class<?> predictBeanType(Class<?> beanClass, String beanName)

Specified by:
  `predictBeanType` in interface `org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor`

### postProcessProperties

public org.springframework.beans.PropertyValues postProcessProperties(org.springframework.beans.PropertyValues pvs, Object bean, String beanName)

Specified by:
  `postProcessProperties` in interface `org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor`

### postProcessBeforeInstantiation

@Nullable public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)

Specified by:
  `postProcessBeforeInstantiation` in interface `org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor`

### prepareScriptBeans

protected void prepareScriptBeans(org.springframework.beans.factory.config.BeanDefinition bd, String scriptFactoryBeanName, String scriptedObjectBeanName)
Prepare the script beans in the internal BeanFactory that this post-processor uses. Each original bean definition will be split into a ScriptFactory definition and a scripted object definition.

Parameters:
  `bd` - the original bean definition in the main BeanFactory
  `scriptFactoryBeanName` - the name of the internal ScriptFactory bean
  `scriptedObjectBeanName` - the name of the internal scripted object bean

### resolveRefreshCheckDelay

protected long resolveRefreshCheckDelay(org.springframework.beans.factory.config.BeanDefinition beanDefinition)
Get the refresh check delay for the given `ScriptFactory` `BeanDefinition`. If the `BeanDefinition` has a `metadata attribute` under the key `REFRESH_CHECK_DELAY_ATTRIBUTE` which is a valid `Number` type, then this value is used. Otherwise, the `defaultRefreshCheckDelay` value is used.

Parameters:
  `beanDefinition` - the BeanDefinition to check
Returns:
  the refresh check delay

### resolveProxyTargetClass

protected boolean resolveProxyTargetClass(org.springframework.beans.factory.config.BeanDefinition beanDefinition)

### createScriptFactoryBeanDefinition

protected org.springframework.beans.factory.config.BeanDefinition createScriptFactoryBeanDefinition(org.springframework.beans.factory.config.BeanDefinition bd)
Create a ScriptFactory bean definition based on the given script definition, extracting only the definition data that is relevant for the ScriptFactory (that is, only bean class and constructor arguments).

Parameters:
  `bd` - the full script bean definition
Returns:
  the extracted ScriptFactory bean definition
See Also:
  - `ScriptFactory`

### getScriptSource

protected ScriptSource getScriptSource(String beanName, String scriptSourceLocator)
Obtain a ScriptSource for the given bean, lazily creating it if not cached already.

Parameters:
  `beanName` - the name of the scripted bean
  `scriptSourceLocator` - the script source locator associated with the bean
Returns:
  the corresponding ScriptSource instance
See Also:
  - `convertToScriptSource(java.lang.String, java.lang.String, org.springframework.core.io.ResourceLoader)`

### convertToScriptSource

protected ScriptSource convertToScriptSource(String beanName, String scriptSourceLocator, org.springframework.core.io.ResourceLoader resourceLoader)
Convert the given script source locator to a ScriptSource instance.

By default, supported locators are Spring resource locations (such as "file:C:/myScript.bsh" or "classpath:myPackage/myScript.bsh") and inline scripts ("inline:myScriptText...").

Parameters:
  `beanName` - the name of the scripted bean
  `scriptSourceLocator` - the script source locator
  `resourceLoader` - the ResourceLoader to use (if necessary)
Returns:
  the ScriptSource instance

### createConfigInterface

protected Class<?> createConfigInterface(org.springframework.beans.factory.config.BeanDefinition bd, @Nullable Class<?>[] interfaces)
Create a config interface for the given bean definition, defining setter methods for the defined property values as well as an init method and a destroy method (if defined).

This implementation creates the interface via CGLIB's InterfaceMaker, determining the property types from the given interfaces (as far as possible).

Parameters:
  `bd` - the bean definition (property values etc) to create a config interface for
  `interfaces` - the interfaces to check against (might define getters corresponding to the setters we're supposed to generate)
Returns:
  the config interface
See Also:
  - `InterfaceMaker`
  - `BeanUtils.findPropertyType(java.lang.String, java.lang.Class<?>...)`

### createCompositeInterface

protected Class<?> createCompositeInterface(Class<?>[] interfaces)
Create a composite interface Class for the given interfaces, implementing the given interfaces in one single Class.

The default implementation builds a JDK proxy class for the given interfaces.

Parameters:
  `interfaces` - the interfaces to merge
Returns:
  the merged interface as Class
See Also:
  - `Proxy.getProxyClass(java.lang.ClassLoader, java.lang.Class<?>...)`

### createScriptedObjectBeanDefinition

protected org.springframework.beans.factory.config.BeanDefinition createScriptedObjectBeanDefinition(org.springframework.beans.factory.config.BeanDefinition bd, String scriptFactoryBeanName, ScriptSource scriptSource, @Nullable Class<?>[] interfaces)
Create a bean definition for the scripted object, based on the given script definition, extracting the definition data that is relevant for the scripted object (that is, everything but bean class and constructor arguments).

Parameters:
  `bd` - the full script bean definition
  `scriptFactoryBeanName` - the name of the internal ScriptFactory bean
  `scriptSource` - the ScriptSource for the scripted bean
  `interfaces` - the interfaces that the scripted bean is supposed to implement
Returns:
  the extracted ScriptFactory bean definition
See Also:
  - `ScriptFactory.getScriptedObject(org.springframework.scripting.ScriptSource, java.lang.Class<?>...)`

### createRefreshableProxy

protected Object createRefreshableProxy(org.springframework.aop.TargetSource ts, @Nullable Class<?>[] interfaces, boolean proxyTargetClass)
Create a refreshable proxy for the given AOP TargetSource.

Parameters:
  `ts` - the refreshable TargetSource
  `interfaces` - the proxy interfaces (may be `null` to indicate proxying of all interfaces implemented by the target class)
Returns:
  the generated proxy
See Also:
  - `RefreshableScriptTargetSource`

### destroy

public void destroy()
Destroy the inner bean factory (used for scripts) on shutdown.

Specified by:
  `destroy` in interface `org.springframework.beans.factory.DisposableBean`