Reference documentation for Groovy bean definition DSL
Issue: SPR-15153
This commit is contained in:
parent
54da4a8c8e
commit
2047f8d5ae
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -303,7 +303,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||||
Collection constructorArgs = null;
|
Collection constructorArgs = null;
|
||||||
if (!ObjectUtils.isEmpty(args)) {
|
if (!ObjectUtils.isEmpty(args)) {
|
||||||
int index = args.length;
|
int index = args.length;
|
||||||
Object lastArg = args[index-1];
|
Object lastArg = args[index - 1];
|
||||||
if (lastArg instanceof Closure) {
|
if (lastArg instanceof Closure) {
|
||||||
callable = (Closure) lastArg;
|
callable = (Closure) lastArg;
|
||||||
index--;
|
index--;
|
||||||
|
@ -456,14 +456,14 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||||
* @return the bean definition wrapper
|
* @return the bean definition wrapper
|
||||||
*/
|
*/
|
||||||
private GroovyBeanDefinitionWrapper invokeBeanDefiningMethod(String beanName, Object[] args) {
|
private GroovyBeanDefinitionWrapper invokeBeanDefiningMethod(String beanName, Object[] args) {
|
||||||
boolean hasClosureArgument = args[args.length - 1] instanceof Closure;
|
boolean hasClosureArgument = (args[args.length - 1] instanceof Closure);
|
||||||
if (args[0] instanceof Class) {
|
if (args[0] instanceof Class) {
|
||||||
Class<?> beanClass = (args[0] instanceof Class ? (Class<?>) args[0] : args[0].getClass());
|
Class<?> beanClass = (Class<?>) args[0];
|
||||||
if (args.length >= 1) {
|
if (args.length >= 1) {
|
||||||
if (hasClosureArgument) {
|
if (hasClosureArgument) {
|
||||||
if (args.length-1 != 1) {
|
if (args.length - 1 != 1) {
|
||||||
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(
|
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(
|
||||||
beanName, beanClass, resolveConstructorArguments(args,1,args.length-1));
|
beanName, beanClass, resolveConstructorArguments(args, 1, args.length - 1));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, beanClass);
|
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, beanClass);
|
||||||
|
@ -471,7 +471,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(
|
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(
|
||||||
beanName, beanClass, resolveConstructorArguments(args,1,args.length));
|
beanName, beanClass, resolveConstructorArguments(args, 1, args.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -483,7 +483,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||||
else if (args[0] instanceof Map) {
|
else if (args[0] instanceof Map) {
|
||||||
// named constructor arguments
|
// named constructor arguments
|
||||||
if (args.length > 1 && args[1] instanceof Class) {
|
if (args.length > 1 && args[1] instanceof Class) {
|
||||||
List constructorArgs = resolveConstructorArguments(args, 2, hasClosureArgument ? args.length-1 : args.length);
|
List constructorArgs = resolveConstructorArguments(args, 2, hasClosureArgument ? args.length - 1 : args.length);
|
||||||
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, (Class)args[1], constructorArgs);
|
this.currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, (Class)args[1], constructorArgs);
|
||||||
Map namedArgs = (Map)args[0];
|
Map namedArgs = (Map)args[0];
|
||||||
for (Object o : namedArgs.keySet()) {
|
for (Object o : namedArgs.keySet()) {
|
||||||
|
@ -519,12 +519,12 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
|
||||||
this.currentBeanDefinition.getBeanDefinition().setAbstract(true);
|
this.currentBeanDefinition.getBeanDefinition().setAbstract(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
List constructorArgs = resolveConstructorArguments(args, 0, hasClosureArgument ? args.length-1 : args.length);
|
List constructorArgs = resolveConstructorArguments(args, 0, hasClosureArgument ? args.length - 1 : args.length);
|
||||||
currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, null, constructorArgs);
|
currentBeanDefinition = new GroovyBeanDefinitionWrapper(beanName, null, constructorArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasClosureArgument) {
|
if (hasClosureArgument) {
|
||||||
Closure callable = (Closure)args[args.length-1];
|
Closure callable = (Closure) args[args.length - 1];
|
||||||
callable.setDelegate(this);
|
callable.setDelegate(this);
|
||||||
callable.setResolveStrategy(Closure.DELEGATE_FIRST);
|
callable.setResolveStrategy(Closure.DELEGATE_FIRST);
|
||||||
callable.call(new Object[]{currentBeanDefinition});
|
callable.call(new Object[]{currentBeanDefinition});
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
[[beans-introduction]]
|
[[beans-introduction]]
|
||||||
== Introduction to the Spring IoC container and beans
|
== Introduction to the Spring IoC container and beans
|
||||||
|
|
||||||
This chapter covers the Spring Framework implementation of the Inversion of Control
|
This chapter covers the Spring Framework implementation of the Inversion of Control
|
||||||
(IoC) footnote:[See pass:specialcharacters,macros[<<background-ioc>>] ] principle. IoC
|
(IoC) footnote:[See pass:specialcharacters,macros[<<background-ioc>>] ] principle. IoC
|
||||||
is also known as __dependency injection__ (DI). It is a process whereby objects define
|
is also known as __dependency injection__ (DI). It is a process whereby objects define
|
||||||
|
@ -44,6 +45,7 @@ among them, are reflected in the __configuration metadata__ used by a container.
|
||||||
|
|
||||||
[[beans-basics]]
|
[[beans-basics]]
|
||||||
== Container overview
|
== Container overview
|
||||||
|
|
||||||
The interface `org.springframework.context.ApplicationContext` represents the Spring IoC
|
The interface `org.springframework.context.ApplicationContext` represents the Spring IoC
|
||||||
container and is responsible for instantiating, configuring, and assembling the
|
container and is responsible for instantiating, configuring, and assembling the
|
||||||
aforementioned beans. The container gets its instructions on what objects to
|
aforementioned beans. The container gets its instructions on what objects to
|
||||||
|
@ -290,6 +292,44 @@ locations, for example, through "${...}" placeholders that are resolved against
|
||||||
system properties at runtime.
|
system properties at runtime.
|
||||||
====
|
====
|
||||||
|
|
||||||
|
The import directive is a feature provided by the beans namespace itself. Further
|
||||||
|
configuration features beyond plain bean definitions are available in a selection
|
||||||
|
of XML namespaces provided by Spring, e.g. the "context" and the "util" namespace.
|
||||||
|
|
||||||
|
|
||||||
|
[[groovy-bean-definition-dsl]]
|
||||||
|
==== The Groovy Bean Definition DSL
|
||||||
|
|
||||||
|
As a further example for externalized configuration metadata, bean definitions can also
|
||||||
|
be expressed in Spring's Groovy Bean Definition DSL, as known from the Grails framework.
|
||||||
|
Typically, such configuration will live in a ".groovy" file with a structure as follows:
|
||||||
|
|
||||||
|
[source,java,indent=0]
|
||||||
|
[subs="verbatim,quotes"]
|
||||||
|
----
|
||||||
|
beans {
|
||||||
|
dataSource(BasicDataSource) {
|
||||||
|
driverClassName = "org.hsqldb.jdbcDriver"
|
||||||
|
url = "jdbc:hsqldb:mem:grailsDB"
|
||||||
|
username = "sa"
|
||||||
|
password = ""
|
||||||
|
settings = [mynew:"setting"]
|
||||||
|
}
|
||||||
|
sessionFactory(SessionFactory) {
|
||||||
|
dataSource = dataSource
|
||||||
|
}
|
||||||
|
myService(MyService) {
|
||||||
|
nestedBean = { AnotherBean bean ->
|
||||||
|
dataSource = dataSource
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
This configuration style is largely equivalent to XML bean definitions and even
|
||||||
|
supports Spring's XML configuration namespaces. It also allows for importing XML
|
||||||
|
bean definition files through an "importBeans" directive.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[beans-factory-client]]
|
[[beans-factory-client]]
|
||||||
|
@ -305,8 +345,7 @@ The `ApplicationContext` enables you to read bean definitions and access them as
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
// create and configure beans
|
// create and configure beans
|
||||||
ApplicationContext context =
|
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
|
||||||
new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
|
|
||||||
|
|
||||||
// retrieve configured instance
|
// retrieve configured instance
|
||||||
PetStoreService service = context.getBean("petStore", PetStoreService.class);
|
PetStoreService service = context.getBean("petStore", PetStoreService.class);
|
||||||
|
@ -315,12 +354,46 @@ The `ApplicationContext` enables you to read bean definitions and access them as
|
||||||
List<String> userList = service.getUsernameList();
|
List<String> userList = service.getUsernameList();
|
||||||
----
|
----
|
||||||
|
|
||||||
You use `getBean()` to retrieve instances of your beans. The `ApplicationContext`
|
With Groovy configuration, bootstrapping looks very similar, just a different context
|
||||||
|
implementation class which is Groovy-aware (but also understands XML bean definitions):
|
||||||
|
|
||||||
|
[source,java,indent=0]
|
||||||
|
[subs="verbatim,quotes"]
|
||||||
|
----
|
||||||
|
ApplicationContext context = new GenericGroovyApplicationContext("services.groovy", "daos.groovy");
|
||||||
|
----
|
||||||
|
|
||||||
|
The most flexible variant is `GenericApplicationContext` in combination with reader
|
||||||
|
delegates, e.g. with `XmlBeanDefinitionReader` for XML files:
|
||||||
|
|
||||||
|
[source,java,indent=0]
|
||||||
|
[subs="verbatim,quotes"]
|
||||||
|
----
|
||||||
|
GenericApplicationContext context = new GenericApplicationContext();
|
||||||
|
new XmlBeanDefinitionReader(ctx).loadBeanDefinitions("services.xml", "daos.xml");
|
||||||
|
context.refresh();
|
||||||
|
----
|
||||||
|
|
||||||
|
Or with `GroovyBeanDefinitionReader` for Groovy files:
|
||||||
|
|
||||||
|
[source,java,indent=0]
|
||||||
|
[subs="verbatim,quotes"]
|
||||||
|
----
|
||||||
|
GenericApplicationContext context = new GenericApplicationContext();
|
||||||
|
new GroovyBeanDefinitionReader(ctx).loadBeanDefinitions("services.groovy", "daos.groovy");
|
||||||
|
context.refresh();
|
||||||
|
----
|
||||||
|
|
||||||
|
Such reader delegates can be mixed and matched on the same `ApplicationContext`,
|
||||||
|
reading bean definitions from diverse configuration sources, if desired.
|
||||||
|
|
||||||
|
You can then use `getBean` to retrieve instances of your beans. The `ApplicationContext`
|
||||||
interface has a few other methods for retrieving beans, but ideally your application
|
interface has a few other methods for retrieving beans, but ideally your application
|
||||||
code should never use them. Indeed, your application code should have no calls to the
|
code should never use them. Indeed, your application code should have no calls to the
|
||||||
`getBean()` method at all, and thus no dependency on Spring APIs at all. For example,
|
`getBean()` method at all, and thus no dependency on Spring APIs at all. For example,
|
||||||
Spring's integration with web frameworks provides for dependency injection for various
|
Spring's integration with web frameworks provides dependency injection for various web
|
||||||
web framework classes such as controllers and JSF-managed beans.
|
framework components such as controllers and JSF-managed beans, allowing you to declare
|
||||||
|
a dependency on a specific bean through metadata (e.g. an autowiring annotation).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -497,6 +570,8 @@ If you are using Java-configuration, the `@Bean` annotation can be used to provi
|
||||||
see <<beans-java-bean-annotation>> for details.
|
see <<beans-java-bean-annotation>> for details.
|
||||||
****
|
****
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[beans-factory-class]]
|
[[beans-factory-class]]
|
||||||
=== Instantiating beans
|
=== Instantiating beans
|
||||||
|
|
||||||
|
@ -7100,6 +7175,7 @@ method that returns `true` or `false`. For example, here is the actual
|
||||||
See the {api-spring-framework}/context/annotation/Conditional.html[
|
See the {api-spring-framework}/context/annotation/Conditional.html[
|
||||||
`@Conditional` javadocs] for more detail.
|
`@Conditional` javadocs] for more detail.
|
||||||
|
|
||||||
|
|
||||||
[[beans-java-combining]]
|
[[beans-java-combining]]
|
||||||
==== Combining Java and XML configuration
|
==== Combining Java and XML configuration
|
||||||
|
|
||||||
|
@ -7372,6 +7448,7 @@ certain profile of bean definitions in situation A, and a different profile in
|
||||||
situation B. Let's first see how we can update our configuration to reflect
|
situation B. Let's first see how we can update our configuration to reflect
|
||||||
this need.
|
this need.
|
||||||
|
|
||||||
|
|
||||||
[[beans-definition-profiles-java]]
|
[[beans-definition-profiles-java]]
|
||||||
==== @Profile
|
==== @Profile
|
||||||
|
|
||||||
|
@ -7541,6 +7618,7 @@ The `spring-bean.xsd` has been constrained to allow such elements only as the
|
||||||
last ones in the file. This should help provide flexibility without incurring
|
last ones in the file. This should help provide flexibility without incurring
|
||||||
clutter in the XML files.
|
clutter in the XML files.
|
||||||
|
|
||||||
|
|
||||||
[[beans-definition-profiles-enable]]
|
[[beans-definition-profiles-enable]]
|
||||||
==== Activating a profile
|
==== Activating a profile
|
||||||
|
|
||||||
|
@ -7587,6 +7665,7 @@ Declaratively, `spring.profiles.active` may accept a comma-separated list of pro
|
||||||
-Dspring.profiles.active="profile1,profile2"
|
-Dspring.profiles.active="profile1,profile2"
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
[[beans-definition-profiles-default]]
|
[[beans-definition-profiles-default]]
|
||||||
==== Default profile
|
==== Default profile
|
||||||
|
|
||||||
|
@ -7617,6 +7696,8 @@ profile is enabled, the _default_ profile will not apply.
|
||||||
The name of the default profile can be changed using `setDefaultProfiles()` on
|
The name of the default profile can be changed using `setDefaultProfiles()` on
|
||||||
the `Environment` or declaratively using the `spring.profiles.default` property.
|
the `Environment` or declaratively using the `spring.profiles.default` property.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[beans-property-source-abstraction]]
|
[[beans-property-source-abstraction]]
|
||||||
=== PropertySource abstraction
|
=== PropertySource abstraction
|
||||||
|
|
||||||
|
@ -7692,6 +7773,8 @@ any `foo` property in any other `PropertySource`. The
|
||||||
API exposes a number of methods that allow for precise manipulation of the set of
|
API exposes a number of methods that allow for precise manipulation of the set of
|
||||||
property sources.
|
property sources.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=== @PropertySource
|
=== @PropertySource
|
||||||
|
|
||||||
The {api-spring-framework}/context/annotation/PropertySource.html[`@PropertySource`]
|
The {api-spring-framework}/context/annotation/PropertySource.html[`@PropertySource`]
|
||||||
|
@ -7749,6 +7832,7 @@ as a default. If no default is specified and a property cannot be resolved, an
|
||||||
`IllegalArgumentException` will be thrown.
|
`IllegalArgumentException` will be thrown.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=== Placeholder resolution in statements
|
=== Placeholder resolution in statements
|
||||||
|
|
||||||
Historically, the value of placeholders in elements could be resolved only against
|
Historically, the value of placeholders in elements could be resolved only against
|
||||||
|
@ -7771,6 +7855,8 @@ property is defined, as long as it is available in the `Environment`:
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[context-load-time-weaver]]
|
[[context-load-time-weaver]]
|
||||||
== Registering a LoadTimeWeaver
|
== Registering a LoadTimeWeaver
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue