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