Merge 3.1.0 development branch into trunk

Branch in question is 'env' branch from git://git.springsource.org/sandbox/cbeams.git; merged into
git-svn repository with:

    git merge -s recursive -Xtheirs --no-commit env

No merge conflicts, but did need to

    git rm spring-build

prior to committing.

With this change, Spring 3.1.0 development is now happening on SVN
trunk. Further commits to the 3.0.x line will happen in an as-yet
uncreated SVN branch.  3.1.0 snapshots will be available
per the usual nightly CI build from trunk.
This commit is contained in:
Chris Beams 2010-10-25 19:48:20 +00:00
parent b0ea2b13d2
commit f480333d31
211 changed files with 9876 additions and 623 deletions

6
.gitignore vendored
View File

@ -1,7 +1,11 @@
target
integration-repo
ivy-cache
spring-build
jmx.log
.springBeans
.DS_Store
*.sw*
org.springframework.test/test-output/
build.sh
org.springframework.beans/.settings/org.springframework.ide.eclipse.beans.core.prefs
org.springframework.beans/.settings/org.springframework.ide.eclipse.core.prefs

View File

@ -1,4 +1,4 @@
version=3.0.5
version=3.1.0
# osgi ranges
spring.osgi.range.nq=${version:[=.=.=, =.=.+1)}
spring.osgi.range="${spring.osgi.range.nq}"

View File

@ -1,15 +1,15 @@
#Wed Jul 15 00:01:31 PDT 2009
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.compiler.source=1.5
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16

View File

@ -4,12 +4,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<packaging>jar</packaging>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.1.0.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.1.0.BUILD-SNAPSHOT</version>
</parent>
<dependencies>

View File

@ -1,4 +1,5 @@
http\://www.springframework.org/schema/aop/spring-aop-2.0.xsd=org/springframework/aop/config/spring-aop-2.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-2.5.xsd=org/springframework/aop/config/spring-aop-2.5.xsd
http\://www.springframework.org/schema/aop/spring-aop-3.0.xsd=org/springframework/aop/config/spring-aop-3.0.xsd
http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-3.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-3.1.xsd=org/springframework/aop/config/spring-aop-3.1.xsd
http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-3.1.xsd

View File

@ -0,0 +1,407 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/aop"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://www.springframework.org/schema/aop"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd"/>
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines the configuration elements for the Spring Framework's AOP support.
]]></xsd:documentation>
</xsd:annotation>
<xsd:element name="config">
<xsd:annotation>
<xsd:documentation><![CDATA[
A section (compartmentalization) of AOP-specific configuration (including
aspects, pointcuts, etc).
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="pointcut" type="pointcutType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
A named pointcut definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="advisor" type="advisorType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.aop.Advisor"><![CDATA[
A named advisor definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="aspect" type="aspectType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
A named aspect definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="proxy-target-class" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Are class-based (CGLIB) proxies to be created? By default, standard
Java interface-based proxies are created.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicate that the proxy should be exposed by the AOP framework as a
ThreadLocal for retrieval via the AopContext class. Off by default,
i.e. no guarantees that AopContext access will work.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="aspectj-autoproxy">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"><![CDATA[
Enables the use of the @AspectJ style of Spring AOP.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="include" type="includeType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates that only @AspectJ beans with names matched by the (regex)
pattern will be considered as defining aspects to use for Spring autoproxying.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="proxy-target-class" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Are class-based (CGLIB) proxies to be created? By default, standard
Java interface-based proxies are created.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expose-proxy" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicate that the proxy should be exposed by the AOP framework as a
ThreadLocal for retrieval via the AopContext class. Off by default,
i.e. no guarantees that AopContext access will work.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="scoped-proxy">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation source="java:org.springframework.aop.scope.ScopedProxyFactoryBean"><![CDATA[
Marks a bean definition as being a scoped proxy.
A bean marked as such will be exposed via a proxy, with the 'real'
bean instance being retrieved from some other source (such as a
HttpSession) as and when required.
]]></xsd:documentation>
</xsd:annotation>
<xsd:attribute name="proxy-target-class" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Are class-based (CGLIB) proxies to be created? This is the default; in order to
switch to standard Java interface-based proxies, turn this flag to "false".
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="aspectType">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="pointcut" type="pointcutType">
<xsd:annotation>
<xsd:documentation><![CDATA[
A named pointcut definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="declare-parents" type="declareParentsType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Allows this aspect to introduce additional interfaces that the advised
object will transparently implement.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="before" type="basicAdviceType">
<xsd:annotation>
<xsd:documentation><![CDATA[
A before advice definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="after" type="basicAdviceType">
<xsd:annotation>
<xsd:documentation><![CDATA[
An after advice definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="after-returning" type="afterReturningAdviceType">
<xsd:annotation>
<xsd:documentation><![CDATA[
An after-returning advice definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="after-throwing" type="afterThrowingAdviceType">
<xsd:annotation>
<xsd:documentation><![CDATA[
An after-throwing advice definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="around" type="basicAdviceType">
<xsd:annotation>
<xsd:documentation><![CDATA[
An around advice definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:choice>
<xsd:attribute name="id" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The unique identifier for an aspect.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ref" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the (backing) bean that encapsulates the aspect.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="order" type="xsd:int">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.core.Ordered"><![CDATA[
Controls the ordering of the execution of this aspect when multiple
advice executes at a specific joinpoint.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="includeType">
<xsd:attribute name="name" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:java.util.regex.Pattern"><![CDATA[
The regular expression defining which beans are to be included in the
list of @AspectJ beans; beans with names matched by the pattern will
be included.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="pointcutType">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="org.springframework.aop.Pointcut"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:attribute name="id" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The unique identifier for a pointcut.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expression" use="required" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The pointcut expression.
For example : 'execution(* com.xyz.myapp.service.*.*(..))'
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="declareParentsType">
<xsd:attribute name="types-matching" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.aop.aspectj.TypePatternClassFilter"><![CDATA[
The AspectJ type expression that defines what types (classes) the
introduction is restricted to.
An example would be 'org.springframework.beans.ITestBean+'.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="implement-interface" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation source="java:java.lang.Class"><![CDATA[
The fully qualified name of the interface that will be introduced.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="default-impl" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:java.lang.Class"><![CDATA[
The fully qualified name of the class that will be instantiated to serve
as the default implementation of the introduced interface.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="delegate-ref" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
A reference to the bean that will serve
as the default implementation of the introduced interface.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="basicAdviceType">
<xsd:attribute name="pointcut" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The associated pointcut expression.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pointcut-ref" type="pointcutRefType">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of an associated pointcut definition.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.aop.Pointcut"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="method" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the method that defines the logic of the advice.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="arg-names" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The comma-delimited list of advice method argument (parameter) names
that will be matched from pointcut parameters.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="afterReturningAdviceType">
<xsd:complexContent>
<xsd:extension base="basicAdviceType">
<xsd:attribute name="returning" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the method parameter to which the return value must
be passed.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="afterThrowingAdviceType">
<xsd:complexContent>
<xsd:extension base="basicAdviceType">
<xsd:attribute name="throwing" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the method parameter to which the thrown exception must
be passed.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="advisorType">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="org.springframework.aop.Advisor"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="advice-ref" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
A reference to an advice bean.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.aopalliance.aop.Advice"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pointcut" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
A pointcut expression.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pointcut-ref" type="pointcutRefType">
<xsd:annotation>
<xsd:documentation><![CDATA[
A reference to a pointcut definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="order" type="xsd:int">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.core.Ordered"><![CDATA[
Controls the ordering of the execution of this advice when multiple
advice executes at a specific joinpoint.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:simpleType name="pointcutRefType">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.aop.Pointcut"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
</xsd:schema>

View File

@ -1,15 +1,15 @@
#Wed Jul 15 00:01:30 PDT 2009
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.compiler.source=1.5
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16

View File

@ -4,12 +4,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-asm</artifactId>
<packaging>jar</packaging>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.1.0.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.1.0.BUILD-SNAPSHOT</version>
</parent>

View File

View File

View File

@ -1,12 +1,12 @@
#Wed Jul 15 00:01:30 PDT 2009
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.compiler.source=1.5

View File

@ -1,90 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<packaging>jar</packaging>
<version>3.0.5.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.5.BUILD-SNAPSHOT</version>
</parent>
<dependencies>
<!-- commons logging dependency is in spring-core -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
<scope>test</scope>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<junitArtifactName>junit:junit</junitArtifactName>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<packaging>jar</packaging>
<version>3.1.0.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.1.0.BUILD-SNAPSHOT</version>
</parent>
<dependencies>
<!-- common logging dependency is in spring-core -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
<scope>test</scope>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<junitArtifactName>junit:junit</junitArtifactName>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -12,6 +12,7 @@
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.2.0/com.springsource.net.sf.cglib-2.2.0.jar" sourcepath="/IVY_CACHE/net.sourceforge.cglib/com.springsource.net.sf.cglib/2.1.3/com.springsource.net.sf.cglib-sources-2.1.3.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-1.2.15.jar" sourcepath="/IVY_CACHE/org.apache.log4j/com.springsource.org.apache.log4j/1.2.15/com.springsource.org.apache.log4j-sources-1.2.15.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-4.7.0.jar" sourcepath="/IVY_CACHE/org.junit/com.springsource.org.junit/4.7.0/com.springsource.org.junit-sources-4.6.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.hamcrest/com.springsource.org.hamcrest/1.1.0/com.springsource.org.hamcrest-1.1.0.jar" sourcepath="/IVY_CACHE/org.hamcrest/com.springsource.org.hamcrest/1.1.0/com.springsource.org.hamcrest-sources-1.1.0.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-2.5.1.jar" sourcepath="/IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-sources-2.5.1.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -1,15 +1,15 @@
#Wed Jul 15 00:01:31 PDT 2009
#Mon Sep 06 21:54:17 CEST 2010
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.compiler.source=1.5
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16

View File

@ -17,6 +17,7 @@
<orderEntry type="library" name="EasyMock" level="project" />
<orderEntry type="library" name="javax.el" level="project" />
<orderEntry type="library" name="javax.inject" level="project" />
<orderEntry type="library" name="Hamcrest" level="project" />
<orderEntry type="library" name="JUnit" level="project" />
<orderEntry type="library" name="Log4j" level="project" />
</component>

View File

@ -31,6 +31,7 @@
<!-- test dependencies -->
<dependency org="org.apache.log4j" name="com.springsource.org.apache.log4j" rev="1.2.15" conf="test->runtime"/>
<dependency org="org.junit" name="com.springsource.org.junit" rev="${org.junit.version}" conf="test->runtime"/>
<dependency org="org.hamcrest" name="com.springsource.org.hamcrest" rev="1.1.0" conf="test->runtime"/>
<dependency org="org.easymock" name="com.springsource.org.easymock" rev="2.5.1" conf="test->compile"/>
<dependency org="org.springframework" name="org.springframework.asm" rev="latest.integration" conf="compile->compile"/>
</dependencies>

View File

@ -4,12 +4,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<packaging>jar</packaging>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.1.0.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.1.0.BUILD-SNAPSHOT</version>
</parent>
<dependencies>

View File

@ -87,6 +87,7 @@ import org.springframework.beans.BeansException;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Chris Beams
* @since 13 April 2001
* @see BeanNameAware#setBeanName
* @see BeanClassLoaderAware#setBeanClassLoader
@ -113,7 +114,6 @@ public interface BeanFactory {
*/
String FACTORY_BEAN_PREFIX = "&";
/**
* Return an instance, which may be shared or independent, of the specified bean.
* <p>This method allows a Spring BeanFactory to be used as a replacement for the
@ -240,7 +240,7 @@ public interface BeanFactory {
* @see #getBean
* @see #getType
*/
boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
/**
* Determine the type of the bean with the given name. More specifically,

View File

@ -110,7 +110,7 @@ public interface ListableBeanFactory extends BeanFactory {
* @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class)
*/
String[] getBeanNamesForType(Class type);
String[] getBeanNamesForType(Class<?> type);
/**
* Return the names of beans matching the given type (including subclasses),
@ -123,7 +123,7 @@ public interface ListableBeanFactory extends BeanFactory {
* FactoryBean doesn't match, the raw FactoryBean itself will be matched against the
* type. If "allowEagerInit" is not set, only raw FactoryBeans will be checked
* (which doesn't require initialization of each FactoryBean).
$ * <p>Does not consider any hierarchy this factory may participate in.
* <p>Does not consider any hierarchy this factory may participate in.
* Use BeanFactoryUtils' <code>beanNamesForTypeIncludingAncestors</code>
* to include beans in ancestor factories too.
* <p>Note: Does <i>not</i> ignore singleton beans that have been registered
@ -143,7 +143,7 @@ $ * <p>Does not consider any hierarchy this factory may participate in.
* @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean)
*/
String[] getBeanNamesForType(Class type, boolean includeNonSingletons, boolean allowEagerInit);
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
/**
* Return the bean instances that match the given object type (including

View File

@ -432,6 +432,7 @@ public class SingletonBeanFactoryLocator implements BeanFactoryLocator {
protected BeanFactory createDefinition(String resourceLocation, String factoryKey) {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
// TODO SPR-7508: consider whether to allow for setEnvironment() here (where would it come from?)
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
try {

View File

@ -0,0 +1,191 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.config;
import java.util.Properties;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.util.PropertyPlaceholderHelper;
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
import org.springframework.util.StringValueResolver;
/**
* TODO SPR-7508: document.
*
* @author Chris Beams
* @author Juergen Hoeller
* @since 3.1
*/
public abstract class AbstractPropertyPlaceholderConfigurer extends PropertyResourceConfigurer
implements BeanNameAware, BeanFactoryAware {
/** Default placeholder prefix: "${" */
public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";
/** Default placeholder suffix: "}" */
public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";
/** Default value separator: ":" */
public static final String DEFAULT_VALUE_SEPARATOR = ":";
protected String placeholderPrefix = DEFAULT_PLACEHOLDER_PREFIX;
protected String placeholderSuffix = DEFAULT_PLACEHOLDER_SUFFIX;
protected String valueSeparator = DEFAULT_VALUE_SEPARATOR;
protected boolean ignoreUnresolvablePlaceholders = false;
private String nullValue;
private String beanName;
private BeanFactory beanFactory;
protected abstract PlaceholderResolver getPlaceholderResolver(Properties props);
/**
* Set the prefix that a placeholder string starts with.
* The default is "${".
* @see #DEFAULT_PLACEHOLDER_PREFIX
*/
public void setPlaceholderPrefix(String placeholderPrefix) {
this.placeholderPrefix = placeholderPrefix;
}
/**
* Set the suffix that a placeholder string ends with.
* The default is "}".
* @see #DEFAULT_PLACEHOLDER_SUFFIX
*/
public void setPlaceholderSuffix(String placeholderSuffix) {
this.placeholderSuffix = placeholderSuffix;
}
/**
* Specify the separating character between the placeholder variable
* and the associated default value, or <code>null</code> if no such
* special character should be processed as a value separator.
* The default is ":".
*/
public void setValueSeparator(String valueSeparator) {
this.valueSeparator = valueSeparator;
}
/**
* Set a value that should be treated as <code>null</code> when
* resolved as a placeholder value: e.g. "" (empty String) or "null".
* <p>Note that this will only apply to full property values,
* not to parts of concatenated values.
* <p>By default, no such null value is defined. This means that
* there is no way to express <code>null</code> as a property
* value unless you explictly map a corresponding value here.
*/
public void setNullValue(String nullValue) {
this.nullValue = nullValue;
}
/**
* Set whether to ignore unresolvable placeholders.
* <p>Default is "false": An exception will be thrown if a placeholder fails
* to resolve. Switch this flag to "true" in order to preserve the placeholder
* String as-is in such a case, leaving it up to other placeholder configurers
* to resolve it.
*/
public void setIgnoreUnresolvablePlaceholders(boolean ignoreUnresolvablePlaceholders) {
this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
}
/**
* Only necessary to check that we're not parsing our own bean definition,
* to avoid failing on unresolvable placeholders in properties file locations.
* The latter case can happen with placeholders for system properties in
* resource locations.
* @see #setLocations
* @see org.springframework.core.io.ResourceEditor
*/
public void setBeanName(String beanName) {
this.beanName = beanName;
}
/**
* Only necessary to check that we're not parsing our own bean definition,
* to avoid failing on unresolvable placeholders in properties file locations.
* The latter case can happen with placeholders for system properties in
* resource locations.
* @see #setLocations
* @see org.springframework.core.io.ResourceEditor
*/
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
throws BeansException {
StringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(props);
BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);
String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
for (String curName : beanNames) {
// Check that we're not parsing our own bean definition,
// to avoid failing on unresolvable placeholders in properties file locations.
if (!(curName.equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) {
BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(curName);
try {
visitor.visitBeanDefinition(bd);
}
catch (Exception ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), curName, ex.getMessage());
}
}
}
// New in Spring 2.5: resolve placeholders in alias target names and aliases as well.
beanFactoryToProcess.resolveAliases(valueResolver);
// New in Spring 3.0: resolve placeholders in embedded values such as annotation attributes.
beanFactoryToProcess.addEmbeddedValueResolver(valueResolver);
}
private class PlaceholderResolvingStringValueResolver implements StringValueResolver {
private final PropertyPlaceholderHelper helper;
private final PlaceholderResolver resolver;
public PlaceholderResolvingStringValueResolver(Properties props) {
this.helper = new PropertyPlaceholderHelper(
placeholderPrefix, placeholderSuffix, valueSeparator, ignoreUnresolvablePlaceholders);
this.resolver = getPlaceholderResolver(props);
}
public String resolveStringValue(String strVal) throws BeansException {
String value = this.helper.replacePlaceholders(strVal, this.resolver);
return (value.equals(nullValue) ? null : value);
}
}
}

View File

@ -173,7 +173,7 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
* @param requiredType type of the property
* @param propertyEditorClass the {@link PropertyEditor} class to register
*/
void registerCustomEditor(Class requiredType, Class<? extends PropertyEditor> propertyEditorClass);
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
/**
* Initialize the given PropertyEditorRegistry with the custom editors

View File

@ -44,7 +44,7 @@ public interface ConfigurableListableBeanFactory
* for example, String. Default is none.
* @param type the dependency type to ignore
*/
void ignoreDependencyType(Class type);
void ignoreDependencyType(Class<?> type);
/**
* Ignore the given dependency interface for autowiring.
@ -57,7 +57,7 @@ public interface ConfigurableListableBeanFactory
* @see org.springframework.beans.factory.BeanFactoryAware
* @see org.springframework.context.ApplicationContextAware
*/
void ignoreDependencyInterface(Class ifc);
void ignoreDependencyInterface(Class<?> ifc);
/**
* Register a special dependency type with corresponding autowired value.
@ -75,7 +75,7 @@ public interface ConfigurableListableBeanFactory
* implementation of the {@link org.springframework.beans.factory.ObjectFactory}
* interface, which allows for lazy resolution of the actual target value.
*/
void registerResolvableDependency(Class dependencyType, Object autowiredValue);
void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);
/**
* Determine whether the specified bean qualifies as an autowire candidate,

View File

@ -19,15 +19,12 @@ package org.springframework.beans.factory.config;
import java.util.Properties;
import java.util.Set;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.core.Constants;
import org.springframework.util.PropertyPlaceholderHelper;
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
import org.springframework.util.StringValueResolver;
/**
* A property resource configurer that resolves placeholders in bean property values of
@ -81,6 +78,7 @@ import org.springframework.util.StringValueResolver;
* be detected and decrypted accordingly before processing them.
*
* @author Juergen Hoeller
* @author Chris Beams
* @since 02.10.2003
* @see #setLocations
* @see #setProperties
@ -91,19 +89,9 @@ import org.springframework.util.StringValueResolver;
* @see #convertPropertyValue
* @see PropertyOverrideConfigurer
*/
public class PropertyPlaceholderConfigurer extends PropertyResourceConfigurer
public class PropertyPlaceholderConfigurer extends AbstractPropertyPlaceholderConfigurer
implements BeanNameAware, BeanFactoryAware {
/** Default placeholder prefix: "${" */
public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";
/** Default placeholder suffix: "}" */
public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";
/** Default value separator: ":" */
public static final String DEFAULT_VALUE_SEPARATOR = ":";
/** Never check system properties. */
public static final int SYSTEM_PROPERTIES_MODE_NEVER = 0;
@ -122,52 +110,10 @@ public class PropertyPlaceholderConfigurer extends PropertyResourceConfigurer
private static final Constants constants = new Constants(PropertyPlaceholderConfigurer.class);
private String placeholderPrefix = DEFAULT_PLACEHOLDER_PREFIX;
private String placeholderSuffix = DEFAULT_PLACEHOLDER_SUFFIX;
private String valueSeparator = DEFAULT_VALUE_SEPARATOR;
private int systemPropertiesMode = SYSTEM_PROPERTIES_MODE_FALLBACK;
private boolean searchSystemEnvironment = true;
private boolean ignoreUnresolvablePlaceholders = false;
private String nullValue;
private String beanName;
private BeanFactory beanFactory;
/**
* Set the prefix that a placeholder string starts with.
* The default is "${".
* @see #DEFAULT_PLACEHOLDER_PREFIX
*/
public void setPlaceholderPrefix(String placeholderPrefix) {
this.placeholderPrefix = placeholderPrefix;
}
/**
* Set the suffix that a placeholder string ends with.
* The default is "}".
* @see #DEFAULT_PLACEHOLDER_SUFFIX
*/
public void setPlaceholderSuffix(String placeholderSuffix) {
this.placeholderSuffix = placeholderSuffix;
}
/**
* Specify the separating character between the placeholder variable
* and the associated default value, or <code>null</code> if no such
* special character should be processed as a value separator.
* The default is ":".
*/
public void setValueSeparator(String valueSeparator) {
this.valueSeparator = valueSeparator;
}
/**
* Set the system property mode by the name of the corresponding constant,
@ -218,84 +164,6 @@ public class PropertyPlaceholderConfigurer extends PropertyResourceConfigurer
this.searchSystemEnvironment = searchSystemEnvironment;
}
/**
* Set whether to ignore unresolvable placeholders.
* <p>Default is "false": An exception will be thrown if a placeholder fails
* to resolve. Switch this flag to "true" in order to preserve the placeholder
* String as-is in such a case, leaving it up to other placeholder configurers
* to resolve it.
*/
public void setIgnoreUnresolvablePlaceholders(boolean ignoreUnresolvablePlaceholders) {
this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
}
/**
* Set a value that should be treated as <code>null</code> when
* resolved as a placeholder value: e.g. "" (empty String) or "null".
* <p>Note that this will only apply to full property values,
* not to parts of concatenated values.
* <p>By default, no such null value is defined. This means that
* there is no way to express <code>null</code> as a property
* value unless you explictly map a corresponding value here.
*/
public void setNullValue(String nullValue) {
this.nullValue = nullValue;
}
/**
* Only necessary to check that we're not parsing our own bean definition,
* to avoid failing on unresolvable placeholders in properties file locations.
* The latter case can happen with placeholders for system properties in
* resource locations.
* @see #setLocations
* @see org.springframework.core.io.ResourceEditor
*/
public void setBeanName(String beanName) {
this.beanName = beanName;
}
/**
* Only necessary to check that we're not parsing our own bean definition,
* to avoid failing on unresolvable placeholders in properties file locations.
* The latter case can happen with placeholders for system properties in
* resource locations.
* @see #setLocations
* @see org.springframework.core.io.ResourceEditor
*/
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
throws BeansException {
StringValueResolver valueResolver = new PlaceholderResolvingStringValueResolver(props);
BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);
String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
for (String curName : beanNames) {
// Check that we're not parsing our own bean definition,
// to avoid failing on unresolvable placeholders in properties file locations.
if (!(curName.equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) {
BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(curName);
try {
visitor.visitBeanDefinition(bd);
}
catch (Exception ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), curName, ex.getMessage());
}
}
}
// New in Spring 2.5: resolve placeholders in alias target names and aliases as well.
beanFactoryToProcess.resolveAliases(valueResolver);
// New in Spring 3.0: resolve placeholders in embedded values such as annotation attributes.
beanFactoryToProcess.addEmbeddedValueResolver(valueResolver);
}
/**
* Resolve the given placeholder using the given properties, performing
* a system properties check according to the given mode.
@ -379,30 +247,16 @@ public class PropertyPlaceholderConfigurer extends PropertyResourceConfigurer
* Only retained for compatibility with Spring 2.5 extensions.
*/
@Deprecated
protected String parseStringValue(String strVal, Properties props, Set visitedPlaceholders) {
protected String parseStringValue(String strVal, Properties props, Set<?> visitedPlaceholders) {
PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper(
placeholderPrefix, placeholderSuffix, valueSeparator, ignoreUnresolvablePlaceholders);
PlaceholderResolver resolver = new PropertyPlaceholderConfigurerResolver(props);
return helper.replacePlaceholders(strVal, resolver);
}
private class PlaceholderResolvingStringValueResolver implements StringValueResolver {
private final PropertyPlaceholderHelper helper;
private final PlaceholderResolver resolver;
public PlaceholderResolvingStringValueResolver(Properties props) {
this.helper = new PropertyPlaceholderHelper(
placeholderPrefix, placeholderSuffix, valueSeparator, ignoreUnresolvablePlaceholders);
this.resolver = new PropertyPlaceholderConfigurerResolver(props);
}
public String resolveStringValue(String strVal) throws BeansException {
String value = this.helper.replacePlaceholders(strVal, this.resolver);
return (value.equals(nullValue) ? null : value);
}
@Override
protected PlaceholderResolver getPlaceholderResolver(Properties props) {
return new PropertyPlaceholderConfigurerResolver(props);
}
@ -419,4 +273,5 @@ public class PropertyPlaceholderConfigurer extends PropertyResourceConfigurer
}
}
}

View File

@ -166,7 +166,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
setParentBeanFactory(parentBeanFactory);
}
/**
* Set the instantiation strategy to use for creating bean instances.
* Default is CglibSubclassingInstantiationStrategy.

View File

@ -21,8 +21,10 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
@ -40,7 +42,7 @@ import org.springframework.util.Assert;
* @since 11.12.2003
* @see BeanDefinitionReaderUtils
*/
public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader {
public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable, BeanDefinitionReader {
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
@ -51,6 +53,8 @@ public abstract class AbstractBeanDefinitionReader implements BeanDefinitionRead
private ClassLoader beanClassLoader;
private Environment environment = new DefaultEnvironment();
private BeanNameGenerator beanNameGenerator = new DefaultBeanNameGenerator();
@ -62,9 +66,14 @@ public abstract class AbstractBeanDefinitionReader implements BeanDefinitionRead
* {@link org.springframework.context.ApplicationContext} implementations.
* <p>If given a plain BeanDefinitionRegistry, the default ResourceLoader will be a
* {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver}.
* <p>If the the passed-in bean factory also implements {@link EnvironmentCapable} its
* environment will be used by this reader. Otherwise, the reader will initialize and
* use a {@link DefaultEnvironment}. All ApplicationContext implementations are
* EnvironmentCapable, while normal BeanFactory implementations are not.
* @param registry the BeanFactory to load bean definitions into,
* in the form of a BeanDefinitionRegistry
* @see #setResourceLoader
* @see #setEnvironment
*/
protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
@ -77,6 +86,14 @@ public abstract class AbstractBeanDefinitionReader implements BeanDefinitionRead
else {
this.resourceLoader = new PathMatchingResourcePatternResolver();
}
// Inherit Environment if possible
if (this.registry instanceof EnvironmentCapable) {
this.environment = ((EnvironmentCapable)this.registry).getEnvironment();
}
else {
this.environment = new DefaultEnvironment();
}
}
@ -122,6 +139,21 @@ public abstract class AbstractBeanDefinitionReader implements BeanDefinitionRead
return this.beanClassLoader;
}
/**
* TODO SPR-7508: document
* @param environment
*/
public void setEnvironment(Environment environment) {
this.environment = environment;
}
/**
* TODO SPR-7508: document
*/
public Environment getEnvironment() {
return this.environment;
}
/**
* Set the BeanNameGenerator to use for anonymous beans
* (without explicit bean name specified).

View File

@ -68,6 +68,9 @@ import org.springframework.beans.factory.config.Scope;
import org.springframework.core.DecoratingClassLoader;
import org.springframework.core.NamedThreadLocal;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
@ -100,6 +103,7 @@ import org.springframework.util.StringValueResolver;
* @author Rod Johnson
* @author Juergen Hoeller
* @author Costin Leau
* @author Chris Beams
* @since 15 April 2001
* @see #getBeanDefinition
* @see #createBean
@ -166,6 +170,9 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
new NamedThreadLocal<Object>("Prototype beans currently in creation");
private ConfigurableEnvironment environment = new DefaultEnvironment();
/**
* Create a new AbstractBeanFactory.
*/
@ -189,7 +196,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@ -682,7 +689,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return this.propertyEditorRegistrars;
}
public void registerCustomEditor(Class requiredType, Class<? extends PropertyEditor> propertyEditorClass) {
public void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass) {
Assert.notNull(requiredType, "Required type must not be null");
Assert.isAssignable(PropertyEditor.class, propertyEditorClass);
this.customEditors.put(requiredType, propertyEditorClass);
@ -1253,7 +1260,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
}
}
private Class doResolveBeanClass(RootBeanDefinition mbd, Class... typesToMatch) throws ClassNotFoundException {
if (!ObjectUtils.isEmpty(typesToMatch)) {
ClassLoader tempClassLoader = getTempClassLoader();

View File

@ -203,6 +203,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
*/
public void setAutowireCandidateResolver(final AutowireCandidateResolver autowireCandidateResolver) {
Assert.notNull(autowireCandidateResolver, "AutowireCandidateResolver must not be null");
// TODO SPR-7515: should also do EnvironmentAware injection here?
if (autowireCandidateResolver instanceof BeanFactoryAware) {
if (System.getSecurityManager() != null) {
final BeanFactory target = this;
@ -460,7 +461,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
// Implementation of ConfigurableListableBeanFactory interface
//---------------------------------------------------------------------
public void registerResolvableDependency(Class dependencyType, Object autowiredValue) {
public void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue) {
Assert.notNull(dependencyType, "Type must not be null");
if (autowiredValue != null) {
Assert.isTrue((autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue)),

View File

@ -43,6 +43,6 @@ public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
* @param beanType the actual type of the managed bean instance
* @param beanName the name of the bean
*/
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName);
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
}

View File

@ -33,6 +33,8 @@ import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.SmartFactoryBean;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.util.StringUtils;
/**
@ -59,6 +61,9 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
/** Map from bean name to bean instance */
private final Map<String, Object> beans = new HashMap<String, Object>();
/** TODO SPR-7508: document */
private ConfigurableEnvironment environment = new DefaultEnvironment();
/**
* Add a new singleton bean.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -63,7 +63,7 @@ public abstract class AbstractSingleBeanDefinitionParser extends AbstractBeanDef
if (parentName != null) {
builder.getRawBeanDefinition().setParentName(parentName);
}
Class beanClass = getBeanClass(element);
Class<?> beanClass = getBeanClass(element);
if (beanClass != null) {
builder.getRawBeanDefinition().setBeanClass(beanClass);
}
@ -111,7 +111,7 @@ public abstract class AbstractSingleBeanDefinitionParser extends AbstractBeanDef
* the supplied <code>Element</code>, or <code>null</code> if none
* @see #getBeanClassName
*/
protected Class getBeanClass(Element element) {
protected Class<?> getBeanClass(Element element) {
return null;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2006 the original author or authors.
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -42,7 +42,7 @@ public interface BeanDefinitionParser {
/**
* Parse the specified {@link Element} and register the resulting
* {@link BeanDefinition BeanDefinition(s)} with the
* {@link org.springframework.beans.factory.xml.ParserContext#getRegistry()} BeanDefinitionRegistry}
* {@link org.springframework.beans.factory.xml.ParserContext#getRegistry() BeanDefinitionRegistry}
* embedded in the supplied {@link ParserContext}.
* <p>Implementations must return the primary {@link BeanDefinition} that results
* from the parse if they will ever be used in a nested fashion (for example as
@ -50,7 +50,8 @@ public interface BeanDefinitionParser {
* <code>null</code> if they will <strong>not</strong> be used in a nested fashion.
* @param element the element that is to be parsed into one or more {@link BeanDefinition BeanDefinitions}
* @param parserContext the object encapsulating the current state of the parsing process;
* provides access to a {@link org.springframework.beans.factory.support.BeanDefinitionRegistry}
* provides access to a {@link org.springframework.beans.factory.support.BeanDefinitionRegistry
* BeanDefinitionRegistry}.
* @return the primary {@link BeanDefinition}
*/
BeanDefinition parse(Element element, ParserContext parserContext);

View File

@ -58,6 +58,7 @@ import org.springframework.beans.factory.support.ManagedProperties;
import org.springframework.beans.factory.support.ManagedSet;
import org.springframework.beans.factory.support.MethodOverrides;
import org.springframework.beans.factory.support.ReplaceOverride;
import org.springframework.core.env.Environment;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
@ -92,10 +93,14 @@ public class BeanDefinitionParserDelegate {
*/
public static final String TRUE_VALUE = "true";
public static final String FALSE_VALUE = "false";
public static final String DEFAULT_VALUE = "default";
public static final String DESCRIPTION_ELEMENT = "description";
public static final String AUTOWIRE_NO_VALUE = "no";
public static final String AUTOWIRE_BY_NAME_VALUE = "byName";
public static final String AUTOWIRE_BY_TYPE_VALUE = "byType";
@ -239,19 +244,25 @@ public class BeanDefinitionParserDelegate {
private final ParseState parseState = new ParseState();
private Environment environment;
/**
* Stores all used bean names so we can enforce uniqueness on a per file basis.
* Stores all used bean names so we can enforce uniqueness on a per
* beans-element basis. Duplicate bean ids/names may not exist within the
* same level of beans element nesting, but may be duplicated across levels.
*/
private final Set<String> usedNames = new HashSet<String>();
/**
* Create a new BeanDefinitionParserDelegate associated with the
* supplied {@link XmlReaderContext}.
* supplied {@link XmlReaderContext} and {@link Environment}.
*/
public BeanDefinitionParserDelegate(XmlReaderContext readerContext) {
public BeanDefinitionParserDelegate(XmlReaderContext readerContext, Environment environment) {
Assert.notNull(readerContext, "XmlReaderContext must not be null");
Assert.notNull(readerContext, "Environment must not be null");
this.readerContext = readerContext;
this.environment = environment;
}
/**
@ -261,6 +272,12 @@ public class BeanDefinitionParserDelegate {
return this.readerContext;
}
/**
* Get the {@link Environment} associated with this helper instance.
*/
public final Environment getEnvironment() {
return this.environment;
}
/**
* Invoke the {@link org.springframework.beans.factory.parsing.SourceExtractor} to pull the
@ -294,33 +311,69 @@ public class BeanDefinitionParserDelegate {
/**
* Initialize the default lazy-init, autowire, dependency check settings,
* init-method, destroy-method and merge settings.
* @see #populateDefaults(DocumentDefaultsDefinition, org.w3c.dom.Element)
* init-method, destroy-method and merge settings. Support nested 'beans'
* element use cases by falling back to <literal>parent</literal> in case the
* defaults are not explicitly set locally.
* @see #populateDefaults(DocumentDefaultsDefinition, DocumentDefaultsDefinition, org.w3c.dom.Element)
* @see #getDefaults()
*/
public void initDefaults(Element root) {
populateDefaults(this.defaults, root);
public void initDefaults(Element root, BeanDefinitionParserDelegate parent) {
populateDefaults(this.defaults, (parent != null ? parent.defaults : null), root);
this.readerContext.fireDefaultsRegistered(this.defaults);
}
/**
* Populate the given DocumentDefaultsDefinition instance with the default lazy-init,
* autowire, dependency check settings, init-method, destroy-method and merge settings.
* Support nested 'beans' element use cases by falling back to
* <literal>parentDefaults</literal> in case the defaults are not explicitly set
* locally.
* @param defaults the defaults to populate
* @param defaults the parent BeanDefinitionParserDelegate (if any) defaults to fall back to
* @param root the root element of the current bean definition document (or nested beans element)
*/
protected void populateDefaults(DocumentDefaultsDefinition defaults, Element root) {
defaults.setLazyInit(root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE));
defaults.setMerge(root.getAttribute(DEFAULT_MERGE_ATTRIBUTE));
defaults.setAutowire(root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE));
protected void populateDefaults(DocumentDefaultsDefinition defaults, DocumentDefaultsDefinition parentDefaults, Element root) {
String lazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
if (DEFAULT_VALUE.equals(lazyInit)) {
lazyInit = parentDefaults != null ? parentDefaults.getLazyInit() : FALSE_VALUE;
}
defaults.setLazyInit(lazyInit);
String merge = root.getAttribute(DEFAULT_MERGE_ATTRIBUTE);
if (DEFAULT_VALUE.equals(merge)) {
merge = parentDefaults != null ? parentDefaults.getMerge() : FALSE_VALUE;
}
defaults.setMerge(merge);
String autowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
if (DEFAULT_VALUE.equals(autowire)) {
autowire = parentDefaults != null ? parentDefaults.getAutowire() : AUTOWIRE_NO_VALUE;
}
defaults.setAutowire(autowire);
// don't fall back to parentDefaults for dependency-check as it's no
// longer supported in <beans> as of 3.0. Therefore, no nested <beans>
// would ever need to fall back to it.
defaults.setDependencyCheck(root.getAttribute(DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE));
if (root.hasAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE)) {
defaults.setAutowireCandidates(root.getAttribute(DEFAULT_AUTOWIRE_CANDIDATES_ATTRIBUTE));
} else if (parentDefaults != null) {
defaults.setAutowireCandidates(parentDefaults.getAutowireCandidates());
}
if (root.hasAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE)) {
defaults.setInitMethod(root.getAttribute(DEFAULT_INIT_METHOD_ATTRIBUTE));
} else if (parentDefaults != null) {
defaults.setInitMethod(parentDefaults.getInitMethod());
}
if (root.hasAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE)) {
defaults.setDestroyMethod(root.getAttribute(DEFAULT_DESTROY_METHOD_ATTRIBUTE));
} else if (parentDefaults != null) {
defaults.setDestroyMethod(parentDefaults.getDestroyMethod());
}
defaults.setSource(this.readerContext.extractSource(root));
}
@ -431,7 +484,8 @@ public class BeanDefinitionParserDelegate {
}
/**
* Validate that the specified bean name and aliases have not been used already.
* Validate that the specified bean name and aliases have not been used already
* within the current level of beans element nesting.
*/
protected void checkNameUniqueness(String beanName, List<String> aliases, Element beanElement) {
String foundName = null;
@ -443,7 +497,7 @@ public class BeanDefinitionParserDelegate {
foundName = (String) CollectionUtils.findFirstMatch(this.usedNames, aliases);
}
if (foundName != null) {
error("Bean name '" + foundName + "' is already used in this file", beanElement);
error("Bean name '" + foundName + "' is already used in this <beans> element", beanElement);
}
this.usedNames.add(beanName);

View File

@ -16,6 +16,9 @@
package org.springframework.beans.factory.xml;
import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
import static org.springframework.util.StringUtils.trimAllWhitespace;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.LinkedHashSet;
@ -32,11 +35,11 @@ import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.SystemPropertyUtils;
/**
* Default implementation of the {@link BeanDefinitionDocumentReader} interface.
@ -59,6 +62,8 @@ public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocume
public static final String BEAN_ELEMENT = BeanDefinitionParserDelegate.BEAN_ELEMENT;
public static final String NESTED_BEANS_ELEMENT = "beans";
public static final String ALIAS_ELEMENT = "alias";
public static final String NAME_ATTRIBUTE = "name";
@ -69,14 +74,29 @@ public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocume
public static final String RESOURCE_ATTRIBUTE = "resource";
/** @see org.springframework.context.annotation.Profile */
public static final String PROFILE_ATTRIBUTE = "profile";
protected final Log logger = LogFactory.getLog(getClass());
private XmlReaderContext readerContext;
private Environment environment;
private BeanDefinitionParserDelegate delegate;
/**
* Parses bean definitions according to the "spring-beans" DTD.
* TODO SPR-7508: document
* @param environment
*/
public void setEnvironment(Environment environment) {
this.environment = environment;
}
/**
* Parses bean definitions according to the "spring-beans" DTD. TODO SPR-7508 XSD
* <p>Opens a DOM Document; then initializes the default settings
* specified at <code>&lt;beans&gt;</code> level; then parses
* the contained bean definitions.
@ -87,16 +107,49 @@ public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocume
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
BeanDefinitionParserDelegate delegate = createHelper(readerContext, root);
preProcessXml(root);
parseBeanDefinitions(root, delegate);
postProcessXml(root);
doRegisterBeanDefinitions(root);
}
protected BeanDefinitionParserDelegate createHelper(XmlReaderContext readerContext, Element root) {
BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext);
delegate.initDefaults(root);
protected void doRegisterBeanDefinitions(Element root) {
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
boolean isCandidate = false;
if (profileSpec == null || profileSpec.equals("")) {
isCandidate = true;
} else {
String[] profiles = commaDelimitedListToStringArray(trimAllWhitespace(profileSpec));
for (String profile : profiles) {
if (this.environment.getActiveProfiles().contains(profile)) {
isCandidate = true;
break;
}
}
}
if (!isCandidate) {
// TODO SPR-7508 logging
// logger.debug(format("XML is targeted for environment [%s], but current environment is [%s]. Skipping", targetEnvironment, environment == null ? null : environment.getName()));
return;
}
// any nested <beans> elements will cause recursion in this method. in
// order to propagate and preserve <beans> default-* attributes correctly,
// keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback purposes,
// then ultimately reset this.delegate back to its original (parent) reference.
// this behavior emulates a stack of delegates without actually necessitating one.
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createHelper(readerContext, root, parent);
preProcessXml(root);
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);
this.delegate = parent;
}
protected BeanDefinitionParserDelegate createHelper(XmlReaderContext readerContext, Element root, BeanDefinitionParserDelegate parentDelegate) {
BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext, environment);
delegate.initDefaults(root, parentDelegate);
return delegate;
}
@ -152,6 +205,10 @@ public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocume
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
/**
@ -166,7 +223,7 @@ public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocume
}
// Resolve system properties: e.g. "${user.dir}"
location = SystemPropertyUtils.resolvePlaceholders(location);
location = environment.resolveRequiredPlaceholders(location);
Set<Resource> actualResources = new LinkedHashSet<Resource>(4);

View File

@ -65,6 +65,7 @@ import org.springframework.util.xml.XmlValidationModeDetector;
*
* @author Juergen Hoeller
* @author Rob Harrop
* @author Chris Beams
* @since 26.11.2003
* @see #setDocumentReaderClass
* @see BeanDefinitionDocumentReader
@ -103,7 +104,7 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
private boolean namespaceAware = false;
private Class documentReaderClass = DefaultBeanDefinitionDocumentReader.class;
private Class<?> documentReaderClass = DefaultBeanDefinitionDocumentReader.class;
private ProblemReporter problemReporter = new FailFastProblemReporter();
@ -134,7 +135,6 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
super(registry);
}
/**
* Set whether to use XML validation. Default is <code>true</code>.
* <p>This method switches namespace awareness on if validation is turned off,
@ -283,7 +283,7 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
* <p>The default is {@link DefaultBeanDefinitionDocumentReader}.
* @param documentReaderClass the desired BeanDefinitionDocumentReader implementation class
*/
public void setDocumentReaderClass(Class documentReaderClass) {
public void setDocumentReaderClass(Class<?> documentReaderClass) {
if (documentReaderClass == null || !BeanDefinitionDocumentReader.class.isAssignableFrom(documentReaderClass)) {
throw new IllegalArgumentException(
"documentReaderClass must be an implementation of the BeanDefinitionDocumentReader interface");
@ -487,8 +487,12 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
* @see BeanDefinitionDocumentReader#registerBeanDefinitions
*/
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
// Read document based on new BeanDefinitionDocumentReader SPI.
// Read document based on new BeanDefinitionDocumentReader SPI. // TODO SPR-7508: polish - remove comment
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
// TODO SPR-7508: remove ugly cast
if (documentReader instanceof DefaultBeanDefinitionDocumentReader) {
((DefaultBeanDefinitionDocumentReader)documentReader).setEnvironment(this.getEnvironment());
}
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
@ -500,7 +504,6 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
* <p>The default implementation instantiates the specified "documentReaderClass".
* @see #setDocumentReaderClass
*/
@SuppressWarnings("unchecked")
protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
return BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass));
}

View File

@ -19,6 +19,7 @@ package org.springframework.beans.factory.xml;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.Resource;
/**
@ -34,7 +35,7 @@ import org.springframework.core.io.Resource;
* <p>This class registers each bean definition with the {@link DefaultListableBeanFactory}
* superclass, and relies on the latter's implementation of the {@link BeanFactory} interface.
* It supports singletons, prototypes, and references to either of these kinds of bean.
* See "spring-beans-2.0.dtd" for details on options and configuration style.
* See "spring-beans-2.0.dtd" for details on options and configuration style. // TODO SPR-7508 polish - s/dtd/xsd/
*
* <p><b>For advanced needs, consider using a {@link DefaultListableBeanFactory} with
* an {@link XmlBeanDefinitionReader}.</b> The latter allows for reading from multiple XML
@ -42,10 +43,14 @@ import org.springframework.core.io.Resource;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Chris Beams
* @since 15 April 2001
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory
* @see XmlBeanDefinitionReader
* @deprecated as of Spring 3.1 in favor of {@link DefaultListableBeanFactory} and
* {@link XmlBeanDefinitionReader}
*/
@Deprecated
public class XmlBeanFactory extends DefaultListableBeanFactory {
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
@ -58,7 +63,7 @@ public class XmlBeanFactory extends DefaultListableBeanFactory {
* @throws BeansException in case of loading or parsing errors
*/
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
this(resource, (BeanFactory)null);
}
/**

View File

@ -34,6 +34,8 @@ import org.springframework.beans.propertyeditors.InputSourceEditor;
import org.springframework.beans.propertyeditors.InputStreamEditor;
import org.springframework.beans.propertyeditors.URIEditor;
import org.springframework.beans.propertyeditors.URLEditor;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceEditor;
import org.springframework.core.io.ResourceLoader;
@ -53,9 +55,26 @@ import org.springframework.core.io.support.ResourcePatternResolver;
*/
public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
private final Environment environment;
private final ResourceLoader resourceLoader;
/**
* Create a new ResourceEditorRegistrar for the given {@link ResourceLoader}
* using a {@link DefaultEnvironment}.
* @param resourceLoader the ResourceLoader (or ResourcePatternResolver)
* to create editors for (usually an ApplicationContext)
* @see org.springframework.core.io.support.ResourcePatternResolver
* @see org.springframework.context.ApplicationContext
* @deprecated as of Spring 3.1 in favor of
* {@link ResourceEditorRegistrar#ResourceEditorRegistrar(ResourceLoader, Environment)}
*/
@Deprecated
public ResourceEditorRegistrar(ResourceLoader resourceLoader) {
this(resourceLoader, new DefaultEnvironment());
}
/**
* Create a new ResourceEditorRegistrar for the given ResourceLoader
* @param resourceLoader the ResourceLoader (or ResourcePatternResolver)
@ -63,8 +82,9 @@ public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
* @see org.springframework.core.io.support.ResourcePatternResolver
* @see org.springframework.context.ApplicationContext
*/
public ResourceEditorRegistrar(ResourceLoader resourceLoader) {
public ResourceEditorRegistrar(ResourceLoader resourceLoader, Environment environment) {
this.resourceLoader = resourceLoader;
this.environment = environment;
}
@ -82,7 +102,7 @@ public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
* @see org.springframework.core.io.support.ResourceArrayPropertyEditor
*/
public void registerCustomEditors(PropertyEditorRegistry registry) {
ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader);
ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.environment);
doRegisterEditor(registry, Resource.class, baseEditor);
doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
@ -96,7 +116,7 @@ public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
if (this.resourceLoader instanceof ResourcePatternResolver) {
doRegisterEditor(registry, Resource[].class,
new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader));
new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader, this.environment));
}
}

View File

@ -1,12 +1,15 @@
http\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd
http\://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd
http\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.1.xsd=org/springframework/beans/factory/xml/spring-beans-3.1.xsd
http\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans-3.1.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.0.xsd=org/springframework/beans/factory/xml/spring-tool-2.0.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.5.xsd=org/springframework/beans/factory/xml/spring-tool-2.5.xsd
http\://www.springframework.org/schema/tool/spring-tool-3.0.xsd=org/springframework/beans/factory/xml/spring-tool-3.0.xsd
http\://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool-3.0.xsd
http\://www.springframework.org/schema/tool/spring-tool-3.1.xsd=org/springframework/beans/factory/xml/spring-tool-3.1.xsd
http\://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool-3.1.xsd
http\://www.springframework.org/schema/util/spring-util-2.0.xsd=org/springframework/beans/factory/xml/spring-util-2.0.xsd
http\://www.springframework.org/schema/util/spring-util-2.5.xsd=org/springframework/beans/factory/xml/spring-util-2.5.xsd
http\://www.springframework.org/schema/util/spring-util-3.0.xsd=org/springframework/beans/factory/xml/spring-util-3.0.xsd
http\://www.springframework.org/schema/util/spring-util.xsd=org/springframework/beans/factory/xml/spring-util-3.0.xsd
http\://www.springframework.org/schema/util/spring-util-3.1.xsd=org/springframework/beans/factory/xml/spring-util-3.1.xsd
http\://www.springframework.org/schema/util/spring-util.xsd=org/springframework/beans/factory/xml/spring-util-3.1.xsd

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/tool"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.springframework.org/schema/tool"
elementFormDefault="qualified">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines the tool support annotations for Spring's configuration namespaces.
Used in other namespace XSD files; not intended for direct use in config files.
]]></xsd:documentation>
</xsd:annotation>
<xsd:element name="annotation">
<xsd:complexType>
<xsd:sequence minOccurs="0">
<xsd:element name="expected-type" type="typedParameterType" minOccurs="0" maxOccurs="1"/>
<xsd:element name="assignable-to" type="assignableToType" minOccurs="0" maxOccurs="1"/>
<xsd:element name="exports" type="exportsType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="registers-scope" type="registersScopeType" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="expected-method" type="expectedMethodType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="kind" default="direct">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ref"/>
<xsd:enumeration value="direct"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="typedParameterType">
<xsd:attribute name="type" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="assignableToType">
<xsd:attribute name="type" type="xsd:string"/>
<xsd:attribute name="restriction" default="both">
<xsd:simpleType>
<xsd:restriction base="xsd:NMTOKEN">
<xsd:enumeration value="both"/>
<xsd:enumeration value="interface-only"/>
<xsd:enumeration value="class-only"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="expectedMethodType">
<xsd:attribute name="type" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines an XPath query that can be executed against the node annotated with this
type to determine the class for which the this method is valid
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="type-ref" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines an XPath query that can be executed against the node annotated with this
type to determine a referenced bean (by id or alias) for which the given method is valid
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expression" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines an AspectJ method execution pointcut expressions that matches valid methods
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="exportsType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates that an annotated type exports an application visible component.
]]></xsd:documentation>
</xsd:annotation>
<xsd:attribute name="type" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The type of the exported component. May be null if the type is not known until runtime.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="identifier" type="xsd:string" default="@id">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines an XPath query that can be executed against the node annotated with this
type to determine the identifier of any exported component.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="registersScopeType">
<xsd:attribute name="name" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines the name of a custom bean scope that the annotated type registers, e.g. "conversation".
Such a scope will be available in addition to the standard "singleton" and "prototype" scopes
(plus "request", "session" and "globalSession" in a web application environment).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:schema>

View File

@ -0,0 +1,212 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/util"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://www.springframework.org/schema/util"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd"/>
<xsd:element name="constant">
<xsd:annotation>
<xsd:documentation>
Reference a public, static field on a type and expose its value as
a bean. For example <code>&lt;util:constant static-field=&quot;java.lang.Integer.MAX_VALUE&quot;/&gt;</code>.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="static-field" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="property-path">
<xsd:annotation>
<xsd:documentation>
Reference a property on a bean (or as a nested value) and expose its values as
a bean. For example &lt;util:property-path path=&quot;order.customer.name&quot;/&gt;.
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="path" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="list">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.beans.factory.config.ListFactoryBean">
Builds a List instance of the specified type, populated with the specified content.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="java.util.List"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:listOrSetType">
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="list-class" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-type type="java.lang.Class"/>
<tool:assignable-to type="java.util.List"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="scope" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The scope of this collection bean: typically "singleton" (one shared instance,
which will be returned by all calls to getBean with the given id), or
"prototype" (independent instance resulting from each call to getBean).
Default is "singleton". Further scopes, such as "request" or "session",
might be supported by extended bean factories (e.g. in a web environment).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="set">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.beans.factory.config.SetFactoryBean">
Builds a Set instance of the specified type, populated with the specified content.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="java.util.Set"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:listOrSetType">
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="set-class" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-type type="java.lang.Class"/>
<tool:assignable-to type="java.util.Set"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="scope" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The scope of this collection bean: typically "singleton" (one shared instance,
which will be returned by all calls to getBean with the given id), or
"prototype" (independent instance resulting from each call to getBean).
Default is "singleton". Further scopes, such as "request" or "session",
might be supported by extended bean factories (e.g. in a web environment).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="map">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.beans.factory.config.MapFactoryBean">
Builds a Map instance of the specified type, populated with the specified content.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="java.util.Map"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:mapType">
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="map-class" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-type type="java.lang.Class"/>
<tool:assignable-to type="java.util.Map"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="scope" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The scope of this collection bean: typically "singleton" (one shared instance,
which will be returned by all calls to getBean with the given id), or
"prototype" (independent instance resulting from each call to getBean).
Default is "singleton". Further scopes, such as "request" or "session",
might be supported by extended bean factories (e.g. in a web environment).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="properties">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.beans.factory.config.PropertiesFactoryBean">
Loads a Properties instance from the resource location specified by the '<code>location</code>' attribute.
</xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="java.util.Properties"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:propsType">
<xsd:attribute name="id" type="xsd:string"/>
<xsd:attribute name="location" type="xsd:string">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-type type="org.springframework.core.io.Resource"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="local-override" type="xsd:boolean">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies whether local properties override properties from files.
Default is "false": properties from files override local defaults.
If set to "true", local properties will override defaults from files.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="scope" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The scope of this collection bean: typically "singleton" (one shared instance,
which will be returned by all calls to getBean with the given id), or
"prototype" (independent instance resulting from each call to getBean).
Default is "singleton". Further scopes, such as "request" or "session",
might be supported by extended bean factories (e.g. in a web environment).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@ -1,44 +1,281 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.config;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
import static org.springframework.beans.factory.support.BeanDefinitionReaderUtils.registerWithGeneratedName;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.io.ByteArrayResource;
import test.beans.TestBean;
/**
* Tests cornering SPR-7547.
* Unit tests for {@link EnvironmentAwarePropertyPlaceholderConfigurer}.
*
* @see PropertyResourceConfigurerTests
* @author Chris Beams
*/
public class PropertyPlaceholderConfigurerTests {
private static final String P1 = "p1";
private static final String P1_LOCAL_PROPS_VAL = "p1LocalPropsVal";
private static final String P1_SYSTEM_PROPS_VAL = "p1SystemPropsVal";
private static final String P1_SYSTEM_ENV_VAL = "p1SystemEnvVal";
private DefaultListableBeanFactory bf;
private AbstractPropertyPlaceholderConfigurer ppc;
private Properties ppcProperties;
private AbstractBeanDefinition p1BeanDef;
@Before
public void setUp() {
p1BeanDef = rootBeanDefinition(TestBean.class)
.addPropertyValue("name", "${"+P1+"}")
.getBeanDefinition();
bf = new DefaultListableBeanFactory();
ppcProperties = new Properties();
ppcProperties.setProperty(P1, P1_LOCAL_PROPS_VAL);
System.setProperty(P1, P1_SYSTEM_PROPS_VAL);
getModifiableSystemEnvironment().put(P1, P1_SYSTEM_ENV_VAL);
ppc = new PropertyPlaceholderConfigurer();
ppc.setProperties(ppcProperties);
}
@After
public void tearDown() {
System.clearProperty(P1);
getModifiableSystemEnvironment().remove(P1);
}
// -------------------------------------------------------------------------
// Tests to ensure backward-compatibility for Environment refactoring
// -------------------------------------------------------------------------
@Test
public void resolveFromSystemProperties() {
getModifiableSystemEnvironment().put("otherKey", "systemValue");
p1BeanDef = rootBeanDefinition(TestBean.class)
.addPropertyValue("name", "${"+P1+"}")
.addPropertyValue("sex", "${otherKey}")
.getBeanDefinition();
registerWithGeneratedName(p1BeanDef, bf);
ppc.postProcessBeanFactory(bf);
TestBean bean = bf.getBean(TestBean.class);
assertThat(bean.getName(), equalTo(P1_LOCAL_PROPS_VAL));
assertThat(bean.getSex(), equalTo("systemValue"));
getModifiableSystemEnvironment().remove("otherKey");
}
@Test
public void resolveFromLocalProperties() {
tearDown(); // eliminate entries from system props/environment
registerWithGeneratedName(p1BeanDef, bf);
ppc.postProcessBeanFactory(bf);
TestBean bean = bf.getBean(TestBean.class);
assertThat(bean.getName(), equalTo(P1_LOCAL_PROPS_VAL));
}
@Test
public void setSystemPropertiesMode_defaultIsFallback() {
registerWithGeneratedName(p1BeanDef, bf);
ppc.postProcessBeanFactory(bf);
TestBean bean = bf.getBean(TestBean.class);
assertThat(bean.getName(), equalTo(P1_LOCAL_PROPS_VAL));
}
/*
@Test
public void setSystemSystemPropertiesMode_toOverride_andResolveFromSystemProperties() {
registerWithGeneratedName(p1BeanDef, bf);
ppc.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_OVERRIDE);
ppc.postProcessBeanFactory(bf);
TestBean bean = bf.getBean(TestBean.class);
assertThat(bean.getName(), equalTo(P1_SYSTEM_PROPS_VAL));
}
@Test
public void setSystemSystemPropertiesMode_toOverride_andResolveFromSystemEnvironment() {
registerWithGeneratedName(p1BeanDef, bf);
System.clearProperty(P1); // will now fall all the way back to system environment
ppc.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_OVERRIDE);
ppc.postProcessBeanFactory(bf);
TestBean bean = bf.getBean(TestBean.class);
assertThat(bean.getName(), equalTo(P1_SYSTEM_ENV_VAL));
}
@Test
public void setSystemSystemPropertiesMode_toOverride_andSetSearchSystemEnvironment_toFalse() {
registerWithGeneratedName(p1BeanDef, bf);
System.clearProperty(P1); // will now fall all the way back to system environment
ppc.setSearchSystemEnvironment(false);
ppc.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_OVERRIDE);
ppc.postProcessBeanFactory(bf);
TestBean bean = bf.getBean(TestBean.class);
assertThat(bean.getName(), equalTo(P1_LOCAL_PROPS_VAL)); // has to resort to local props
}
*/
/**
* Prior to the fix for SPR-7547, the following would throw
* IllegalStateException because the PropertiesLoaderSupport base class
* assumed ByteArrayResource implements Resource.getFilename(). It does
* not, and AbstractResource.getFilename() is called instead, raising the
* exception. The following now works, as getFilename() is called in a
* try/catch to check whether the resource is actually file-based or not.
*
* See SPR-7552, which suggests paths to address the root issue rather than
* just patching the problem.
* Creates a scenario in which two PPCs are configured, each with different
* settings regarding resolving properties from the environment.
*/
@Test
public void repro() {
public void twoPlacholderConfigurers_withConflictingSettings() {
String P2 = "p2";
String P2_LOCAL_PROPS_VAL = "p2LocalPropsVal";
String P2_SYSTEM_PROPS_VAL = "p2SystemPropsVal";
String P2_SYSTEM_ENV_VAL = "p2SystemEnvVal";
AbstractBeanDefinition p2BeanDef = rootBeanDefinition(TestBean.class)
.addPropertyValue("name", "${"+P1+"}")
.addPropertyValue("country", "${"+P2+"}")
.getBeanDefinition();
bf.registerBeanDefinition("p1Bean", p1BeanDef);
bf.registerBeanDefinition("p2Bean", p2BeanDef);
ppc.setIgnoreUnresolvablePlaceholders(true);
ppc.postProcessBeanFactory(bf);
System.setProperty(P2, P2_SYSTEM_PROPS_VAL);
getModifiableSystemEnvironment().put(P2, P2_SYSTEM_ENV_VAL);
Properties ppc2Properties = new Properties();
ppc2Properties.put(P2, P2_LOCAL_PROPS_VAL);
PropertyPlaceholderConfigurer ppc2 = new PropertyPlaceholderConfigurer();
ppc2.setSystemPropertiesMode(PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_OVERRIDE);
ppc2.setProperties(ppc2Properties);
ppc2Properties = new Properties();
ppc2Properties.setProperty(P2, P2_LOCAL_PROPS_VAL);
ppc2.postProcessBeanFactory(bf);
TestBean p1Bean = bf.getBean("p1Bean", TestBean.class);
assertThat(p1Bean.getName(), equalTo(P1_LOCAL_PROPS_VAL));
TestBean p2Bean = bf.getBean("p2Bean", TestBean.class);
assertThat(p2Bean.getName(), equalTo(P1_LOCAL_PROPS_VAL));
assertThat(p2Bean.getCountry(), equalTo(P2_SYSTEM_PROPS_VAL));
System.clearProperty(P2);
getModifiableSystemEnvironment().remove(P2);
}
@Test
public void customPlaceholderPrefixAndSuffix() {
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setPlaceholderPrefix("@<");
ppc.setPlaceholderSuffix(">");
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerBeanDefinition("testBean",
rootBeanDefinition(TestBean.class)
.addPropertyValue("name", "${my.name}").getBeanDefinition());
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setLocation(new ByteArrayResource("my.name=Inigo Montoya".getBytes()));
ppc.postProcessBeanFactory(bf);
.addPropertyValue("name", "@<key1>")
.addPropertyValue("sex", "${key2}")
.getBeanDefinition());
TestBean testBean = bf.getBean(TestBean.class);
assertThat(testBean.getName(), equalTo("Inigo Montoya"));
System.setProperty("key1", "systemKey1Value");
System.setProperty("key2", "systemKey2Value");
ppc.postProcessBeanFactory(bf);
System.clearProperty("key1");
System.clearProperty("key2");
assertThat(bf.getBean(TestBean.class).getName(), is("systemKey1Value"));
assertThat(bf.getBean(TestBean.class).getSex(), is("${key2}"));
}
@Test
public void nullValueIsPreserved() {
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setNullValue("customNull");
getModifiableSystemEnvironment().put("my.name", "customNull");
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.registerBeanDefinition("testBean", rootBeanDefinition(TestBean.class)
.addPropertyValue("name", "${my.name}")
.getBeanDefinition());
ppc.postProcessBeanFactory(bf);
assertThat(bf.getBean(TestBean.class).getName(), nullValue());
getModifiableSystemEnvironment().remove("my.name");
}
// -------------------------------------------------------------------------
// Tests for functionality not possible prior to Environment refactoring
// -------------------------------------------------------------------------
/**
* Tests that properties against a BeanFactory's Environment are used by
* PropertyPlaceholderConfigurer during placeholder resolution.
@Test @SuppressWarnings({ "unchecked", "rawtypes", "serial" })
public void replacePlaceholdersFromBeanFactoryEnvironmentPropertySources() {
System.setProperty("key1", "systemValue");
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
bf.getEnvironment().addPropertySource("psCustom", new HashMap() {{ put("key1", "customValue"); }});
bf.registerBeanDefinition("testBean",
rootBeanDefinition(TestBean.class).addPropertyValue("name", "${key1}").getBeanDefinition());
new PropertyPlaceholderConfigurer().postProcessBeanFactory(bf);
assertThat(bf.getBean(TestBean.class).getName(), is("customValue"));
System.clearProperty("key1");
}
*/
// -------------------------------------------------------------------------
// Utilities
// -------------------------------------------------------------------------
// TODO SPR-7508: duplicated from EnvironmentPropertyResolutionSearchTests
@SuppressWarnings("unchecked")
private static Map<String, String> getModifiableSystemEnvironment() {
Class<?>[] classes = Collections.class.getDeclaredClasses();
Map<String, String> env = System.getenv();
for (Class<?> cl : classes) {
if ("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
try {
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Object obj = field.get(env);
return (Map<String, String>) obj;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
throw new IllegalStateException();
}
}

View File

@ -16,6 +16,14 @@
package org.springframework.beans.factory.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition;
import static test.util.TestResourceUtils.qualifiedResource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -23,18 +31,12 @@ import java.util.Properties;
import java.util.Set;
import java.util.prefs.Preferences;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import test.beans.IndexedTestBean;
import test.beans.TestBean;
import static test.util.TestResourceUtils.*;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.*;
import org.springframework.beans.factory.support.ChildBeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.ManagedList;
@ -43,11 +45,15 @@ import org.springframework.beans.factory.support.ManagedSet;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.io.Resource;
import test.beans.IndexedTestBean;
import test.beans.TestBean;
/**
* Unit tests for various {@link PropertyResourceConfigurer} implementations including:
* {@link PropertyPlaceholderConfigurer}, {@link PropertyOverrideConfigurer} and
* {@link PreferencesPlaceholderConfigurer}.
*
* @see PropertyPlaceholderConfigurerTests
* @since 02.10.2003
* @author Juergen Hoeller
* @author Chris Beams
@ -794,6 +800,39 @@ public final class PropertyResourceConfigurerTests {
Preferences.systemRoot().node("mySystemPath/mypath").remove("myName");
}
/* TODO SPR-7508: uncomment after EnvironmentAwarePropertyPlaceholderConfigurer implementation
@Test
public void testPreferencesPlaceholderConfigurerWithCustomPropertiesInEnvironment() {
factory.registerBeanDefinition("tb",
genericBeanDefinition(TestBean.class)
.addPropertyValue("name", "${mypath/myName}")
.addPropertyValue("age", "${myAge}")
.addPropertyValue("touchy", "${myotherpath/myTouchy}")
.getBeanDefinition());
Properties props = new Properties();
props.put("myAge", "99");
factory.getEnvironment().getPropertySources().add(new PropertiesPropertySource("localProps", props));
PreferencesPlaceholderConfigurer ppc = new PreferencesPlaceholderConfigurer();
ppc.setSystemTreePath("mySystemPath");
ppc.setUserTreePath("myUserPath");
Preferences.systemRoot().node("mySystemPath").node("mypath").put("myName", "myNameValue");
Preferences.systemRoot().node("mySystemPath/myotherpath").put("myTouchy", "myTouchyValue");
Preferences.userRoot().node("myUserPath/myotherpath").put("myTouchy", "myOtherTouchyValue");
ppc.afterPropertiesSet();
ppc.postProcessBeanFactory(factory);
TestBean tb = (TestBean) factory.getBean("tb");
assertEquals("myNameValue", tb.getName());
assertEquals(99, tb.getAge());
assertEquals("myOtherTouchyValue", tb.getTouchy());
Preferences.userRoot().node("myUserPath/myotherpath").remove("myTouchy");
Preferences.systemRoot().node("mySystemPath/myotherpath").remove("myTouchy");
Preferences.systemRoot().node("mySystemPath/mypath").remove("myName");
}
*/
private static class ConvertingOverrideConfigurer extends PropertyOverrideConfigurer {

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="testBean" class="test.beans.TestBean">
<property name="name" value="topLevel"/>
</bean>
<beans>
<bean id="testBean" class="test.beans.TestBean">
<property name="name" value="nested"/>
</bean>
</beans>
</beans>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="testBean" class="test.beans.TestBean">
<property name="name" value="original"/>
</bean>
<!-- STS should raise an error for this duplicate id -->
<bean id="testBean" class="test.beans.TestBean">
<property name="name" value="duplicate"/>
</bean>
</beans>

View File

@ -0,0 +1,66 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.xml;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.io.ClassPathResource;
import test.beans.TestBean;
/**
* With Spring 3.1, bean id attributes (and all other id attributes across the
* core schemas) are no longer typed as xsd:id, but as xsd:string. This allows
* for using the same bean id within nested <beans> elements.
*
* Duplicate ids *within the same level of nesting* will still be treated as an
* error through the ProblemReporter, as this could never be an intended/valid
* situation.
*
* @author Chris Beams
* @since 3.1
* @see org.springframework.beans.factory.xml.XmlBeanFactoryTests#testWithDuplicateName
* @see org.springframework.beans.factory.xml.XmlBeanFactoryTests#testWithDuplicateNameInAlias
*/
public class DuplicateBeanIdTests {
@Test
public void duplicateBeanIdsWithinSameNestingLevelRaisesError() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(bf);
try {
reader.loadBeanDefinitions(new ClassPathResource("DuplicateBeanIdTests-sameLevel-context.xml", this.getClass()));
fail("expected parsing exception due to duplicate ids in same nesting level");
} catch (Exception ex) {
// expected
}
}
@Test
public void duplicateBeanIdsAcrossNestingLevels() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(bf);
reader.loadBeanDefinitions(new ClassPathResource("DuplicateBeanIdTests-multiLevel-context.xml", this.getClass()));
TestBean testBean = bf.getBean(TestBean.class); // there should be only one
assertThat(testBean.getName(), equalTo("nested"));
}
}

View File

@ -0,0 +1,113 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.xml;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Test;
import org.junit.internal.matchers.TypeSafeMatcher;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.core.io.ClassPathResource;
/**
* TODO SPR-7508: document
*
* @author Chris Beams
*/
public class EnvironmentBeansTests {
private static final String PROD_ELIGIBLE_XML = "environmentBeans-prodProfile.xml";
private static final String DEV_ELIGIBLE_XML = "environmentBeans-devProfile.xml";
private static final String ALL_ELIGIBLE_XML = "environmentBeans-noProfile.xml";
private static final String MULTI_ELIGIBLE_XML = "environmentBeans-multiProfile.xml";
private static final String UNKOWN_ELIGIBLE_XML = "environmentBeans-unknownProfile.xml";
private static final String PROD_ACTIVE = "prod";
private static final String DEV_ACTIVE = "dev";
private static final String NULL_ACTIVE = null;
private static final String UNKNOWN_ACTIVE = "unknown";
private static final String[] NONE_ACTIVE = new String[0];
private static final String[] MULTI_ACTIVE = new String[] { PROD_ACTIVE, DEV_ACTIVE };
private static final String TARGET_BEAN = "foo";
@Test
public void test() {
assertThat(beanFactoryFor(PROD_ELIGIBLE_XML, NONE_ACTIVE), not(containsTargetBean()));
assertThat(beanFactoryFor(PROD_ELIGIBLE_XML, NULL_ACTIVE), not(containsTargetBean()));
assertThat(beanFactoryFor(PROD_ELIGIBLE_XML, DEV_ACTIVE), not(containsTargetBean()));
assertThat(beanFactoryFor(PROD_ELIGIBLE_XML, PROD_ACTIVE), containsTargetBean());
assertThat(beanFactoryFor(PROD_ELIGIBLE_XML, MULTI_ACTIVE), containsTargetBean());
assertThat(beanFactoryFor(DEV_ELIGIBLE_XML, NONE_ACTIVE), not(containsTargetBean()));
assertThat(beanFactoryFor(DEV_ELIGIBLE_XML, NULL_ACTIVE), not(containsTargetBean()));
assertThat(beanFactoryFor(DEV_ELIGIBLE_XML, PROD_ACTIVE), not(containsTargetBean()));
assertThat(beanFactoryFor(DEV_ELIGIBLE_XML, DEV_ACTIVE), containsTargetBean());
assertThat(beanFactoryFor(DEV_ELIGIBLE_XML, MULTI_ACTIVE), containsTargetBean());
assertThat(beanFactoryFor(ALL_ELIGIBLE_XML, NONE_ACTIVE), containsTargetBean());
assertThat(beanFactoryFor(ALL_ELIGIBLE_XML, NULL_ACTIVE), containsTargetBean());
assertThat(beanFactoryFor(ALL_ELIGIBLE_XML, DEV_ACTIVE), containsTargetBean());
assertThat(beanFactoryFor(ALL_ELIGIBLE_XML, PROD_ACTIVE), containsTargetBean());
assertThat(beanFactoryFor(ALL_ELIGIBLE_XML, MULTI_ACTIVE), containsTargetBean());
assertThat(beanFactoryFor(MULTI_ELIGIBLE_XML, NONE_ACTIVE), not(containsTargetBean()));
assertThat(beanFactoryFor(MULTI_ELIGIBLE_XML, NULL_ACTIVE), not(containsTargetBean()));
assertThat(beanFactoryFor(MULTI_ELIGIBLE_XML, UNKNOWN_ACTIVE), not(containsTargetBean()));
assertThat(beanFactoryFor(MULTI_ELIGIBLE_XML, DEV_ACTIVE), containsTargetBean());
assertThat(beanFactoryFor(MULTI_ELIGIBLE_XML, PROD_ACTIVE), containsTargetBean());
assertThat(beanFactoryFor(MULTI_ELIGIBLE_XML, MULTI_ACTIVE), containsTargetBean());
assertThat(beanFactoryFor(UNKOWN_ELIGIBLE_XML, MULTI_ACTIVE), not(containsTargetBean()));
}
private BeanDefinitionRegistry beanFactoryFor(String xmlName, String... activeProfileNames) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
DefaultEnvironment env = new DefaultEnvironment();
env.setActiveProfiles(activeProfileNames);
reader.setEnvironment(env);
reader.loadBeanDefinitions(new ClassPathResource(xmlName, getClass()));
return beanFactory;
}
private static Matcher<BeanDefinitionRegistry> containsBeanDefinition(final String beanName) {
return new TypeSafeMatcher<BeanDefinitionRegistry>() {
public void describeTo(Description desc) {
desc.appendText("a BeanDefinitionRegistry containing bean named ")
.appendValue(beanName);
}
@Override
public boolean matchesSafely(BeanDefinitionRegistry beanFactory) {
return beanFactory.containsBeanDefinition(beanName);
}
};
}
private static Matcher<BeanDefinitionRegistry> containsTargetBean() {
return containsBeanDefinition(TARGET_BEAN);
}
}

View File

@ -0,0 +1,148 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.xml;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.Matchers.hasItems;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.io.ClassPathResource;
import test.beans.TestBean;
/**
* Tests for propagating enclosing beans element defaults to nested beans elements.
*
* @author Chris Beams
*/
public class NestedBeansElementAttributeRecursionTests {
@Test
public void defaultLazyInit() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("NestedBeansElementAttributeRecursionTests-lazy-context.xml", this.getClass()));
BeanDefinition foo = bf.getBeanDefinition("foo");
BeanDefinition bar = bf.getBeanDefinition("bar");
BeanDefinition baz = bf.getBeanDefinition("baz");
BeanDefinition biz = bf.getBeanDefinition("biz");
BeanDefinition buz = bf.getBeanDefinition("buz");
assertThat(foo.isLazyInit(), is(false));
assertThat(bar.isLazyInit(), is(true));
assertThat(baz.isLazyInit(), is(false));
assertThat(biz.isLazyInit(), is(true));
assertThat(buz.isLazyInit(), is(true));
}
@Test
@SuppressWarnings("unchecked")
public void defaultMerge() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("NestedBeansElementAttributeRecursionTests-merge-context.xml", this.getClass()));
TestBean topLevel = bf.getBean("topLevelConcreteTestBean", TestBean.class);
// has the concrete child bean values
assertThat(topLevel.getSomeList(), hasItems("charlie", "delta"));
// but does not merge the parent values
assertThat(topLevel.getSomeList(), not(hasItems("alpha", "bravo")));
TestBean firstLevel = bf.getBean("firstLevelNestedTestBean", TestBean.class);
// merges all values
assertThat(firstLevel.getSomeList(),
hasItems("charlie", "delta", "echo", "foxtrot"));
TestBean secondLevel = bf.getBean("secondLevelNestedTestBean", TestBean.class);
// merges all values
assertThat(secondLevel.getSomeList(),
hasItems("charlie", "delta", "echo", "foxtrot", "golf", "hotel"));
}
@Test
public void defaultAutowireCandidates() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("NestedBeansElementAttributeRecursionTests-autowire-candidates-context.xml", this.getClass()));
assertThat(bf.getBeanDefinition("fooService").isAutowireCandidate(), is(true));
assertThat(bf.getBeanDefinition("fooRepository").isAutowireCandidate(), is(true));
assertThat(bf.getBeanDefinition("other").isAutowireCandidate(), is(false));
assertThat(bf.getBeanDefinition("barService").isAutowireCandidate(), is(true));
assertThat(bf.getBeanDefinition("fooController").isAutowireCandidate(), is(false));
assertThat(bf.getBeanDefinition("bizRepository").isAutowireCandidate(), is(true));
assertThat(bf.getBeanDefinition("bizService").isAutowireCandidate(), is(false));
assertThat(bf.getBeanDefinition("bazService").isAutowireCandidate(), is(true));
assertThat(bf.getBeanDefinition("random").isAutowireCandidate(), is(false));
assertThat(bf.getBeanDefinition("fooComponent").isAutowireCandidate(), is(false));
assertThat(bf.getBeanDefinition("fRepository").isAutowireCandidate(), is(false));
assertThat(bf.getBeanDefinition("aComponent").isAutowireCandidate(), is(true));
assertThat(bf.getBeanDefinition("someService").isAutowireCandidate(), is(false));
}
@Test
public void initMethod() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(
new ClassPathResource("NestedBeansElementAttributeRecursionTests-init-destroy-context.xml", this.getClass()));
InitDestroyBean beanA = bf.getBean("beanA", InitDestroyBean.class);
InitDestroyBean beanB = bf.getBean("beanB", InitDestroyBean.class);
InitDestroyBean beanC = bf.getBean("beanC", InitDestroyBean.class);
InitDestroyBean beanD = bf.getBean("beanD", InitDestroyBean.class);
assertThat(beanA.initMethod1Called, is(true));
assertThat(beanB.initMethod2Called, is(true));
assertThat(beanC.initMethod3Called, is(true));
assertThat(beanD.initMethod2Called, is(true));
bf.destroySingletons();
assertThat(beanA.destroyMethod1Called, is(true));
assertThat(beanB.destroyMethod2Called, is(true));
assertThat(beanC.destroyMethod3Called, is(true));
assertThat(beanD.destroyMethod2Called, is(true));
}
}
class InitDestroyBean {
boolean initMethod1Called;
boolean initMethod2Called;
boolean initMethod3Called;
boolean destroyMethod1Called;
boolean destroyMethod2Called;
boolean destroyMethod3Called;
void initMethod1() { this.initMethod1Called = true; }
void initMethod2() { this.initMethod2Called = true; }
void initMethod3() { this.initMethod3Called = true; }
void destroyMethod1() { this.destroyMethod1Called = true; }
void destroyMethod2() { this.destroyMethod2Called = true; }
void destroyMethod3() { this.destroyMethod3Called = true; }
}

View File

@ -0,0 +1,49 @@
package org.springframework.beans.factory.xml;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
/**
* Tests for new nested beans element support in Spring XML
*
* @author Chris Beams
*/
public class NestedBeansElementTests {
private final Resource XML =
new ClassPathResource("NestedBeansElementTests-context.xml", this.getClass());
@Test
public void getBean_withoutActiveProfile() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(bf).loadBeanDefinitions(XML);
Object foo = bf.getBean("foo");
assertThat(foo, instanceOf(String.class));
}
@Test
public void getBean_withActiveProfile() {
ConfigurableEnvironment env = new DefaultEnvironment();
env.setActiveProfiles("dev");
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(bf);
reader.setEnvironment(env);
reader.loadBeanDefinitions(XML);
bf.getBean("devOnlyBean"); // should not throw NSBDE
Object foo = bf.getBean("foo");
assertThat(foo, instanceOf(Integer.class));
bf.getBean("devOnlyBean");
}
}

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
default-autowire-candidates="foo*">
<bean id="fooRepository" class="java.lang.Object"/>
<bean id="fooService" class="java.lang.Object"/>
<bean id="other" class="java.lang.Object"/>
<beans default-autowire-candidates="*Service">
<bean id="barService" class="java.lang.Object"/>
<bean id="fooController" class="java.lang.Object"/>
<beans default-autowire-candidates="*Repository">
<bean id="bizRepository" class="java.lang.Object"/>
<bean id="bizService" class="java.lang.Object"/>
</beans>
<beans> <!-- should inherit enclosing beans' defaults -->
<bean id="bazService" class="java.lang.Object"/>
<bean id="random" class="java.lang.Object"/>
<bean id="fooComponent" class="java.lang.Object"/>
<bean id="fRepository" class="java.lang.Object"/>
</beans>
<beans default-autowire-candidates="*Component">
<bean id="aComponent" class="java.lang.Object"/>
<bean id="someService" class="java.lang.Object"/>
</beans>
</beans>
</beans>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="foo" class="java.lang.Object"/>
<beans default-autowire="constructor">
<bean id="bar" class="java.lang.Object"/>
<beans>
<bean id="baz" class="java.lang.Object"/>
</beans>
</beans>
</beans>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
default-init-method="initMethod1"
default-destroy-method="destroyMethod1">
<bean id="beanA" class="org.springframework.beans.factory.xml.InitDestroyBean"/>
<beans default-init-method="initMethod2" default-destroy-method="destroyMethod2">
<bean id="beanB" class="org.springframework.beans.factory.xml.InitDestroyBean"/>
<beans default-init-method="initMethod3" default-destroy-method="destroyMethod3">
<bean id="beanC" class="org.springframework.beans.factory.xml.InitDestroyBean"/>
</beans>
<beans> <!-- should fall back to outer defaults (initMethod2 and destroyMethod2) -->
<bean id="beanD" class="org.springframework.beans.factory.xml.InitDestroyBean"/>
</beans>
</beans>
</beans>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<!-- lazy == false (based on default XSD values) -->
<bean id="foo" class="java.lang.Object"/>
<beans default-lazy-init="true">
<!-- lazy == true (explicit default specified) -->
<bean id="bar" class="java.lang.Object"/>
</beans>
<beans default-lazy-init="false">
<!-- lazy == false (explicit default specified) -->
<bean id="baz" class="java.lang.Object"/>
</beans>
<beans default-lazy-init="true">
<!-- lazy == true (explicit default specified) -->
<bean id="biz" class="java.lang.Object"/>
<beans>
<!-- lazy == true (inherit enclosing <beans> defaults -->
<bean id="buz" class="java.lang.Object"/>
</beans>
</beans>
</beans>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
default-merge="false">
<bean id="abstractTestBean" class="test.beans.TestBean" abstract="true">
<property name="someList">
<list>
<value>alpha</value>
<value>bravo</value>
</list>
</property>
</bean>
<bean id="topLevelConcreteTestBean" parent="abstractTestBean">
<property name="someList">
<list>
<value>charlie</value>
<value>delta</value>
</list>
</property>
</bean>
<beans default-merge="true">
<bean id="firstLevelNestedTestBean" parent="topLevelConcreteTestBean">
<property name="someList">
<list>
<value>echo</value>
<value>foxtrot</value>
</list>
</property>
</bean>
<beans>
<bean id="secondLevelNestedTestBean" parent="firstLevelNestedTestBean">
<property name="someList">
<list>
<value>golf</value>
<value>hotel</value>
</list>
</property>
</bean>
</beans>
</beans>
</beans>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="foo" class="java.lang.String"/>
<beans profile="dev">
<!-- should override the 'foo' bean above when the 'dev' profile is active -->
<bean name="foo" class="java.lang.Integer">
<constructor-arg value="42"/>
</bean>
<!-- should only be available when the 'dev' profile is active -->
<bean name="devOnlyBean" class="java.lang.Object"/>
</beans>
</beans>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
profile="dev">
<bean id="foo" class="java.lang.String"/>
</beans>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
profile="dev,prod">
<bean id="foo" class="java.lang.String"/>
</beans>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="foo" class="java.lang.String"/>
</beans>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
profile="prod">
<bean id="foo" class="java.lang.String"/>
</beans>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"
profile="unknown">
<bean id="foo" class="java.lang.String"/>
</beans>

View File

@ -1,15 +1,15 @@
#Wed Jul 15 00:01:30 PDT 2009
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.compiler.source=1.5
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16

View File

@ -4,12 +4,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<packaging>jar</packaging>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.1.0.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.1.0.BUILD-SNAPSHOT</version>
</parent>

View File

@ -1,15 +1,15 @@
#Wed Jul 15 00:01:31 PDT 2009
#Mon Sep 06 21:53:54 CEST 2010
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.compiler.source=1.5
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<beansProjectDescription>
<version>1</version>
<pluginVersion><![CDATA[2.3.3.201004202100-CI-R3763-B716]]></pluginVersion>
<pluginVersion><![CDATA[2.5.0.201008272200-CI-R3822-B852]]></pluginVersion>
<configSuffixes>
<configSuffix><![CDATA[xml]]></configSuffix>
</configSuffixes>
@ -11,7 +11,6 @@
<config>src/test/java/org/springframework/context/annotation/configuration/SecondLevelSubConfig-context.xml</config>
<config>src/test/java/org/springframework/context/annotation/configuration/ImportXmlWithAopNamespace-context.xml</config>
<config>src/test/java/org/springframework/context/annotation/Spr6602Tests-context.xml</config>
<config>src/test/java/org/springframework/beans/factory/FactoryBeanLookupTests-context.xml</config>
</configs>
<configSets>
</configSets>

View File

@ -6,12 +6,12 @@
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<packaging>jar</packaging>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.1.0.BUILD-SNAPSHOT</version>
<parent>
<groupId>org.springframework</groupId>
<artifactId>spring-parent</artifactId>
<relativePath>../org.springframework.spring-parent</relativePath>
<version>3.0.5.BUILD-SNAPSHOT</version>
<version>3.1.0.BUILD-SNAPSHOT</version>
</parent>
<dependencies>

View File

@ -19,6 +19,7 @@ package org.springframework.context;
import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.io.support.ResourcePatternResolver;
/**
@ -53,7 +54,7 @@ import org.springframework.core.io.support.ResourcePatternResolver;
* @see org.springframework.beans.factory.BeanFactory
* @see org.springframework.core.io.ResourceLoader
*/
public interface ApplicationContext extends ListableBeanFactory, HierarchicalBeanFactory,
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
/**

View File

@ -19,6 +19,8 @@ package org.springframework.context;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
/**
* SPI interface to be implemented by most if not all application contexts.
@ -31,6 +33,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
* methods should only be used by startup and shutdown code.
*
* @author Juergen Hoeller
* @author Chris Beams
* @since 03.11.2003
*/
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle {
@ -59,6 +62,11 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
*/
String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
/**
* Name of the {@link Environment} bean in the factory.
*/
String ENVIRONMENT_BEAN_NAME = "environment";
/**
* Name of the System properties bean in the factory.
* @see java.lang.System#getProperties()
@ -87,6 +95,16 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
*/
void setParent(ApplicationContext parent);
/**
* TODO SPR-7508: document
*/
ConfigurableEnvironment getEnvironment();
/**
* TODO SPR-7508: document
*/
void setEnvironment(ConfigurableEnvironment environment);
/**
* Add a new BeanFactoryPostProcessor that will get applied to the internal
* bean factory of this application context on refresh, before any of the
@ -105,7 +123,7 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
* @see org.springframework.context.event.ContextRefreshedEvent
* @see org.springframework.context.event.ContextClosedEvent
*/
void addApplicationListener(ApplicationListener listener);
void addApplicationListener(ApplicationListener<?> listener);
/**
* Load or refresh the persistent representation of the configuration,

View File

@ -0,0 +1,30 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context;
import org.springframework.core.env.Environment;
/**
* TODO SPR-7515: document
*
* @author Chris Beams
*/
public interface EnvironmentAware {
void setEnvironment(Environment environment);
}

View File

@ -24,6 +24,9 @@ import org.springframework.beans.factory.support.AutowireCandidateQualifier;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
/**
* Convenient adapter for programmatic registration of annotated bean classes.
@ -31,6 +34,7 @@ import org.springframework.beans.factory.support.BeanNameGenerator;
* the same resolution of annotations but for explicitly registered classes only.
*
* @author Juergen Hoeller
* @author Chris Beams
* @since 3.0
* @see AnnotationConfigApplicationContext#register
*/
@ -38,6 +42,8 @@ public class AnnotatedBeanDefinitionReader {
private final BeanDefinitionRegistry registry;
private Environment environment = new DefaultEnvironment();
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
@ -61,9 +67,17 @@ public class AnnotatedBeanDefinitionReader {
return this.registry;
}
/**
* Set the Environment to use when registering classes.
* <p>The default is a {@link DefaultEnvironment}.
*/
public void setEnvironment(Environment environment) {
this.environment = environment;
}
/**
* Set the BeanNameGenerator to use for detected bean classes.
* <p>Default is a {@link AnnotationBeanNameGenerator}.
* <p>The default is a {@link AnnotationBeanNameGenerator}.
*/
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
this.beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new AnnotationBeanNameGenerator());
@ -92,8 +106,45 @@ public class AnnotatedBeanDefinitionReader {
registerBean(annotatedClass, null, qualifiers);
}
private boolean hasEligibleProfile(AnnotationMetadata metadata) {
boolean hasEligibleProfile = false;
if (!metadata.hasAnnotation(Profile.class.getName())) {
hasEligibleProfile = true;
} else {
for (String profile : (String[])metadata.getAnnotationAttributes(Profile.class.getName()).get(Profile.CANDIDATE_PROFILES_ATTRIB_NAME)) {
if (this.environment.getActiveProfiles().contains(profile)) {
hasEligibleProfile = true;
break;
}
}
}
return hasEligibleProfile;
}
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (!hasEligibleProfile(abd.getMetadata())) {
// TODO SPR-7508: log that this bean is being rejected on profile mismatch
return;
}
/*
if (metadata.hasAnnotation(Profile.class.getName())) {
if (this.environment == null) {
return;
}
Map<String, Object> profileAttribs = metadata.getAnnotationAttributes(Profile.class.getName());
String[] names = (String[]) profileAttribs.get(Profile.CANDIDATE_PROFILES_ATTRIB_NAME);
boolean go=false;
for (String pName : names) {
if (this.environment.getActiveProfiles().contains(pName)) {
go = true;
}
}
if (!go) {
return;
}
}
*/
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

View File

@ -16,8 +16,11 @@
package org.springframework.context.annotation;
import org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
/**
* Standalone application context, accepting annotated classes as input - in particular
@ -46,6 +49,9 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
private final ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this);
{ // TODO: rework this, it's a bit confusing
this.setEnvironment(this.getEnvironment());
}
/**
* Create a new AnnotationConfigApplicationContext that needs to be populated
@ -75,6 +81,15 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
refresh();
}
/**
* TODO SPR-7508: document
*/
@Override
public void setEnvironment(ConfigurableEnvironment environment) {
super.setEnvironment(environment);
this.reader.setEnvironment(environment);
this.scanner.setEnvironment(environment);
}
/**
* Set the BeanNameGenerator to use for detected bean classes.
@ -94,7 +109,6 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
this.scanner.setScopeMetadataResolver(scopeMetadataResolver);
}
/**
* Register an annotated class to be processed. Allows for programmatically
* building a {@link AnnotationConfigApplicationContext}. Note that

View File

@ -39,7 +39,7 @@ import org.springframework.util.ClassUtils;
* @author Chris Beams
* @since 2.5
* @see CommonAnnotationBeanPostProcessor
* @see org.springframework.context.annotation.support.ConfigurationClassPostProcessor;
* @see org.springframework.context.annotation.ConfigurationClassPostProcessor
* @see org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
* @see org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor
* @see org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor

View File

@ -101,7 +101,7 @@ public @interface Bean {
* <p>Note: Only invoked on beans whose lifecycle is under the full control of the
* factory, which is always the case for singletons but not guaranteed
* for any other scope.
* @see {@link org.springframework.context.ConfigurableApplicationContext#close()}
* @see org.springframework.context.ConfigurableApplicationContext#close()
*/
String destroyMethod() default "";

View File

@ -27,6 +27,7 @@ import org.springframework.beans.factory.support.BeanDefinitionDefaults;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.PatternMatchUtils;
@ -48,6 +49,7 @@ import org.springframework.util.PatternMatchUtils;
*
* @author Mark Fisher
* @author Juergen Hoeller
* @author Chris Beams
* @since 2.5
* @see AnnotationConfigApplicationContext#scan
* @see org.springframework.stereotype.Component
@ -87,6 +89,10 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
* {@link org.springframework.context.ApplicationContext} implementations.
* <p>If given a plain BeanDefinitionRegistry, the default ResourceLoader will be a
* {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver}.
* <p>If the the passed-in bean factory also implements {@link EnvironmentCapable} its
* environment will be used by this reader. Otherwise, the reader will initialize and
* use a {@link DefaultEnvironment}. All ApplicationContext implementations are
* EnvironmentCapable, while normal BeanFactory implementations are not.
* @param registry the BeanFactory to load bean definitions into,
* in the form of a BeanDefinitionRegistry
* @param useDefaultFilters whether to include the default filters for the
@ -96,6 +102,7 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
* {@link org.springframework.stereotype.Controller @Controller} stereotype
* annotations.
* @see #setResourceLoader
* @see #setEnvironment
*/
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
super(useDefaultFilters);
@ -107,6 +114,11 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
if (this.registry instanceof ResourceLoader) {
setResourceLoader((ResourceLoader) this.registry);
}
// Inherit Environment if possible
if (this.registry instanceof EnvironmentCapable) {
setEnvironment(((EnvironmentCapable) this.registry).getEnvironment());
}
}

View File

@ -25,11 +25,13 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
@ -46,7 +48,6 @@ import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.SystemPropertyUtils;
/**
* A component provider that scans the classpath from a base package. It then
@ -59,18 +60,21 @@ import org.springframework.util.SystemPropertyUtils;
* @author Mark Fisher
* @author Juergen Hoeller
* @author Ramnivas Laddad
* @author Chris Beams
* @since 2.5
* @see org.springframework.core.type.classreading.MetadataReaderFactory
* @see org.springframework.core.type.AnnotationMetadata
* @see ScannedGenericBeanDefinition
*/
public class ClassPathScanningCandidateComponentProvider implements ResourceLoaderAware {
public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
private static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
protected final Log logger = LogFactory.getLog(getClass());
private Environment environment = new DefaultEnvironment();
private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);
@ -110,6 +114,20 @@ public class ClassPathScanningCandidateComponentProvider implements ResourceLoad
this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
}
/**
* TODO SPR-7508: document
*/
public void setEnvironment(Environment environment) {
this.environment = environment;
}
/**
* TODO SPR-7508: document
*/
public Environment getEnvironment() {
return this.environment;
}
/**
* Return the ResourceLoader that this component provider uses.
*/
@ -261,7 +279,7 @@ public class ClassPathScanningCandidateComponentProvider implements ResourceLoad
* @return the pattern specification to be used for package searching
*/
protected String resolveBasePackage(String basePackage) {
return ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(basePackage));
return ClassUtils.convertClassNameToResourcePath(environment.resolveRequiredPlaceholders(basePackage));
}
/**
@ -278,12 +296,28 @@ public class ClassPathScanningCandidateComponentProvider implements ResourceLoad
}
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
return true;
return hasEligibleProfile(metadataReader);
}
}
return false;
}
private boolean hasEligibleProfile(MetadataReader metadataReader) {
boolean hasEligibleProfile = false;
if (!metadataReader.getAnnotationMetadata().hasAnnotation(Profile.class.getName())) {
hasEligibleProfile = true;
} else {
for (String profile : (String[])metadataReader.getAnnotationMetadata().getAnnotationAttributes(Profile.class.getName()).get(Profile.CANDIDATE_PROFILES_ATTRIB_NAME)) {
if (this.environment.getActiveProfiles().contains(profile)) {
hasEligibleProfile = true;
break;
}
}
}
return hasEligibleProfile;
}
/**
* Determine whether the given bean definition qualifies as candidate.
* <p>The default implementation checks whether the class is concrete

View File

@ -0,0 +1,75 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.support.BeanNameGenerator;
/**
* Configures component scanning directives for use with {@link Configuration}
* classes. Provides support parallel with Spring XML's
* &lt;context:component-scan&gt; element.
*
* TODO SPR-7508: complete documentation.
*
* @author Chris Beams
* @since 3.1
* @see FilterType
* @see Configuration
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
/** base packages to scan */
String[] value() default {};
Class<?>[] packageOf() default Void.class;
Class<? extends BeanNameGenerator> nameGenerator() default AnnotationBeanNameGenerator.class;
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
String resourcePattern() default "**/*.class";
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
boolean useDefaultFilters() default true;
IncludeFilter[] includeFilters() default {};
ExcludeFilter[] excludeFilters() default {};
@Retention(RetentionPolicy.SOURCE)
@interface IncludeFilter {
FilterType type() default FilterType.ANNOTATION;
Class<?> value();
}
@Retention(RetentionPolicy.SOURCE)
@interface ExcludeFilter {
FilterType type() default FilterType.ANNOTATION;
Class<?> value();
}
}

View File

@ -98,6 +98,7 @@ public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
// Delegate bean definition registration to scanner class.
ClassPathBeanDefinitionScanner scanner = createScanner(readerContext, useDefaultFilters);
scanner.setResourceLoader(readerContext.getResourceLoader());
scanner.setEnvironment(parserContext.getDelegate().getEnvironment());
scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());

View File

@ -57,6 +57,7 @@ import org.springframework.stereotype.Component;
* @see Bean
* @see ConfigurationClassPostProcessor
* @see AnnotationConfigApplicationContext
* @see org.springframework.context.annotation.Profile
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)

View File

@ -105,7 +105,6 @@ final class ConfigurationClass {
return this.importedResources;
}
public void validate(ProblemReporter problemReporter) {
// An @Bean method may only be overloaded through inheritance. No single
// @Configuration class may declare two @Bean methods with the same name.

View File

@ -27,6 +27,7 @@ import java.util.Stack;
import org.springframework.beans.factory.parsing.Location;
import org.springframework.beans.factory.parsing.Problem;
import org.springframework.beans.factory.parsing.ProblemReporter;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.StandardAnnotationMetadata;
@ -63,14 +64,18 @@ class ConfigurationClassParser {
private final Set<ConfigurationClass> configurationClasses =
new LinkedHashSet<ConfigurationClass>();
private final Environment environment;
/**
* Create a new {@link ConfigurationClassParser} instance that will be used
* to populate the set of configuration classes.
*/
public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory, ProblemReporter problemReporter) {
public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory,
ProblemReporter problemReporter, Environment environment) {
this.metadataReaderFactory = metadataReaderFactory;
this.problemReporter = problemReporter;
this.environment = environment;
}
@ -95,8 +100,28 @@ class ConfigurationClassParser {
processConfigurationClass(new ConfigurationClass(clazz, beanName));
}
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
boolean hasEligibleProfile = false;
if (this.environment == null) {
hasEligibleProfile = true;
} else {
if (!configClass.getMetadata().hasAnnotation(Profile.class.getName())) {
hasEligibleProfile = true;
} else {
for (String profile : (String[])configClass.getMetadata().getAnnotationAttributes(Profile.class.getName()).get(Profile.CANDIDATE_PROFILES_ATTRIB_NAME)) {
if (this.environment.getActiveProfiles().contains(profile)) {
hasEligibleProfile = true;
break;
}
}
}
}
if (!hasEligibleProfile) {
//logger.debug("TODO SPR-7508: issue debug statement that this class is being excluded");
// make sure XML has a symmetrical statement as well
return;
}
AnnotationMetadata metadata = configClass.getMetadata();
while (metadata != null) {
doProcessConfigurationClass(configClass, metadata);
@ -120,6 +145,7 @@ class ConfigurationClassParser {
// Let's remove the old one and go with the new one.
this.configurationClasses.remove(configClass);
}
this.configurationClasses.add(configClass);
}

View File

@ -16,6 +16,7 @@
package org.springframework.context.annotation;
import java.awt.dnd.Autoscroll;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@ -38,7 +39,9 @@ import org.springframework.beans.factory.parsing.SourceExtractor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.Assert;
@ -61,7 +64,8 @@ import org.springframework.util.ClassUtils;
* @author Juergen Hoeller
* @since 3.0
*/
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, BeanClassLoaderAware {
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
BeanClassLoaderAware, EnvironmentAware {
/** Whether the CGLIB2 library is present on the classpath */
private static final boolean cglibAvailable = ClassUtils.isPresent(
@ -84,6 +88,8 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
private boolean postProcessBeanFactoryCalled = false;
private Environment environment;
/**
* Set the {@link SourceExtractor} to use for generated bean definitions
@ -121,8 +127,12 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
}
}
public void setEnvironment(Environment environment) {
this.environment = environment;
}
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
return Ordered.HIGHEST_PRECEDENCE + 1; // make room for AutoScanningBeanDefinitionRegistrar
}
@ -180,7 +190,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
}
// Populate a new configuration model by parsing each @Configuration classes
ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter);
ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment);
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,19 +16,39 @@
package org.springframework.context.annotation;
import org.springframework.core.type.filter.AssignableTypeFilter;
/**
* Enumeration of the valid type filters to be added for annotation-driven configuration.
* Enumeration of the type filters that may be used in conjunction with
* {@link ComponentScan @ComponentScan}.
*
* @author Mark Fisher
* @author Juergen Hoeller
* @author Chris Beams
* @since 2.5
* @see ComponentScan
* @see ComponentScan.IncludeFilter
* @see ComponentScan.ExcludeFilter
* @see org.springframework.core.type.filter.TypeFilter
*/
public enum FilterType {
/**
* Filter candidates marked with a given annotation.
* @see org.springframework.core.type.filter.AnnotationTypeFilter
*/
ANNOTATION,
/**
* Filter candidates assignable to a given type.
* @see AssignableTypeFilter
*/
ASSIGNABLE_TYPE,
ASPECTJ_PATTERN,
REGEX_PATTERN,
/** Filter candidates using a given custom
* {@link org.springframework.core.type.filter.TypeFilter} implementation
*/
CUSTOM
}

View File

@ -0,0 +1,46 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.annotation;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Chris Beams
* @since 3.1
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({
ANNOTATION_TYPE, // @Profile may be used as a meta-annotation
TYPE // In conjunction with @Component and its derivatives
})
public @interface Profile {
/**
* @see #value()
*/
static final String CANDIDATE_PROFILES_ATTRIB_NAME = "value";
/**
* TODO SPR-7508: document
*/
String[] value();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,6 +20,7 @@ import org.w3c.dom.Element;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.support.EnvironmentAwarePropertyPlaceholderConfigurer;
import org.springframework.util.StringUtils;
/**
@ -27,15 +28,24 @@ import org.springframework.util.StringUtils;
*
* @author Juergen Hoeller
* @author Dave Syer
* @author Chris Beams
* @since 2.5
*/
class PropertyPlaceholderBeanDefinitionParser extends AbstractPropertyLoadingBeanDefinitionParser {
@Override
protected Class getBeanClass(Element element) {
return PropertyPlaceholderConfigurer.class;
protected Class<?> getBeanClass(Element element) {
// as of Spring 3.1, the default for system-properties-mode is DELEGATE,
// meaning that the attribute should be disregarded entirely, instead
// deferring to the order of PropertySource objects in the enclosing
// application context's Environment object
if (!"DELEGATE".equals(element.getAttribute("system-properties-mode"))) {
return PropertyPlaceholderConfigurer.class;
}
return EnvironmentAwarePropertyPlaceholderConfigurer.class;
}
@Override
protected void doParse(Element element, BeanDefinitionBuilder builder) {
@ -44,9 +54,11 @@ class PropertyPlaceholderBeanDefinitionParser extends AbstractPropertyLoadingBea
builder.addPropertyValue("ignoreUnresolvablePlaceholders",
Boolean.valueOf(element.getAttribute("ignore-unresolvable")));
String systemPropertiesModeName = element.getAttribute("system-properties-mode");
if (StringUtils.hasLength(systemPropertiesModeName)) {
builder.addPropertyValue("systemPropertiesModeName", "SYSTEM_PROPERTIES_MODE_"+systemPropertiesModeName);
if (!"DELEGATE".equals(element.getAttribute("system-properties-mode"))) {
String systemPropertiesModeName = element.getAttribute("system-properties-mode");
if (StringUtils.hasLength(systemPropertiesModeName)) {
builder.addPropertyValue("systemPropertiesModeName", "SYSTEM_PROPERTIES_MODE_"+systemPropertiesModeName);
}
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.expression;
import org.springframework.core.env.Environment;
import org.springframework.expression.AccessException;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypedValue;
/**
* Read-only EL property accessor that knows how to retrieve keys
* of a Spring {@link Environment} instance.
*
* @author Chris Beams
* @since 3.1
*/
public class EnvironmentAccessor implements PropertyAccessor {
public Class<?>[] getSpecificTargetClasses() {
return new Class[] { Environment.class };
}
/**
* Can read any {@link Environment}, thus always returns true.
* @return true
*/
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
return true;
}
/**
* Access provided {@literal target} object by calling its {@link Environment#getProperty(String)}
* method with the provided {@literal name}.
*/
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
return new TypedValue(((Environment)target).getProperty(name));
}
/**
* Read only.
* @return false
*/
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
return false;
}
/**
* Read only. No-op.
*/
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
}
}

View File

@ -126,6 +126,7 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
sec.addPropertyAccessor(new BeanExpressionContextAccessor());
sec.addPropertyAccessor(new BeanFactoryAccessor());
sec.addPropertyAccessor(new MapAccessor());
sec.addPropertyAccessor(new EnvironmentAccessor());
sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory()));
sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader()));
ConversionService conversionService = evalContext.getBeanFactory().getConversionService();

View File

@ -18,7 +18,6 @@ package org.springframework.context.support;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.security.AccessControlException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
@ -33,7 +32,6 @@ import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.DisposableBean;
@ -54,6 +52,7 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.HierarchicalMessageSource;
import org.springframework.context.LifecycleProcessor;
import org.springframework.context.MessageSource;
@ -73,6 +72,8 @@ import org.springframework.core.OrderComparator;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
@ -203,7 +204,10 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
private ApplicationEventMulticaster applicationEventMulticaster;
/** Statically specified listeners */
private Set<ApplicationListener> applicationListeners = new LinkedHashSet<ApplicationListener>();
private Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<ApplicationListener<?>>();
/** TODO SPR-7508: document */
private ConfigurableEnvironment environment = new DefaultEnvironment();
/**
@ -271,6 +275,14 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
return this.parent;
}
public ConfigurableEnvironment getEnvironment() {
return this.environment;
}
public void setEnvironment(ConfigurableEnvironment environment) {
this.environment = environment;
}
/**
* Return this context's internal bean factory as AutowireCapableBeanFactory,
* if already available.
@ -363,6 +375,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
this.beanFactoryPostProcessors.add(beanFactoryPostProcessor);
}
/**
* Return the list of BeanFactoryPostProcessors that will get applied
* to the internal BeanFactory.
@ -371,7 +384,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
return this.beanFactoryPostProcessors;
}
public void addApplicationListener(ApplicationListener listener) {
public void addApplicationListener(ApplicationListener<?> listener) {
if (this.applicationEventMulticaster != null) {
this.applicationEventMulticaster.addApplicationListener(listener);
}
@ -383,7 +396,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
/**
* Return the list of statically specified ApplicationListeners.
*/
public Collection<ApplicationListener> getApplicationListeners() {
public Collection<ApplicationListener<?>> getApplicationListeners() {
return this.applicationListeners;
}
@ -481,7 +494,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
@ -489,6 +502,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
@ -505,54 +519,16 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
// Register default environment beans.
if (!beanFactory.containsBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
Map systemProperties;
try {
systemProperties = System.getProperties();
}
catch (AccessControlException ex) {
systemProperties = new ReadOnlySystemAttributesMap() {
@Override
protected String getSystemAttribute(String propertyName) {
try {
return System.getProperty(propertyName);
}
catch (AccessControlException ex) {
if (logger.isInfoEnabled()) {
logger.info("Not allowed to obtain system property [" + propertyName + "]: " +
ex.getMessage());
}
return null;
}
}
};
}
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, systemProperties);
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
Map<String,String> systemEnvironment;
try {
systemEnvironment = System.getenv();
}
catch (AccessControlException ex) {
systemEnvironment = new ReadOnlySystemAttributesMap() {
@Override
protected String getSystemAttribute(String variableName) {
try {
return System.getenv(variableName);
}
catch (AccessControlException ex) {
if (logger.isInfoEnabled()) {
logger.info("Not allowed to obtain system environment variable [" + variableName + "]: " +
ex.getMessage());
}
return null;
}
}
};
}
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, systemEnvironment);
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
@ -664,6 +640,15 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
}
/**
* Common location for subclasses to call and receive registration of standard
* {@link BeanFactoryPostProcessor} bean definitions.
*
* @param registry subclass BeanDefinitionRegistry
*/
protected void registerStandardBeanFactoryPostProcessors(BeanDefinitionRegistry registry) {
}
/**
* Instantiate and invoke all registered BeanPostProcessor beans,
* respecting explicit order if given.
@ -848,7 +833,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
*/
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener listener : getApplicationListeners()) {
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
@ -869,7 +854,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* @deprecated as of Spring 3.0, in favor of {@link #addApplicationListener}
*/
@Deprecated
protected void addListener(ApplicationListener listener) {
protected void addListener(ApplicationListener<?> listener) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
@ -1099,7 +1084,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
return getBeanFactory().isPrototype(name);
}
public boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException {
public boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException {
return getBeanFactory().isTypeMatch(name, targetType);
}
@ -1128,11 +1113,11 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
return getBeanFactory().getBeanDefinitionNames();
}
public String[] getBeanNamesForType(Class type) {
public String[] getBeanNamesForType(Class<?> type) {
return getBeanFactory().getBeanNamesForType(type);
}
public String[] getBeanNamesForType(Class type, boolean includeNonSingletons, boolean allowEagerInit) {
public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
return getBeanFactory().getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
}
@ -1347,7 +1332,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
private final Map<String, Boolean> singletonNames = new ConcurrentHashMap<String, Boolean>();
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) {
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanDefinition.isSingleton()) {
this.singletonNames.put(beanName, Boolean.TRUE);
}
@ -1363,7 +1348,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// singleton bean (top-level or inner): register on the fly
addApplicationListener((ApplicationListener) bean);
addApplicationListener((ApplicationListener<?>) bean);
}
else if (flag == null) {
if (logger.isWarnEnabled() && !containsBean(beanName)) {

View File

@ -53,6 +53,7 @@ import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
* supports {@literal @Configuration}-annotated classes as a source of bean definitions.
*
* @author Juergen Hoeller
* @author Chris Beams
* @since 1.1.3
* @see #loadBeanDefinitions
* @see org.springframework.beans.factory.support.DefaultListableBeanFactory
@ -217,6 +218,7 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
}
beanFactory.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer());
beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
registerStandardBeanFactoryPostProcessors(beanFactory);
}
/**

View File

@ -117,9 +117,13 @@ public abstract class AbstractRefreshableConfigApplicationContext extends Abstra
* system property values if necessary. Applied to config locations.
* @param path the original file path
* @return the resolved file path
* @see org.springframework.util.SystemPropertyUtils#resolvePlaceholders
* @see SystemPropertyUtils#resolveRequiredPlaceholders(String)
*/
protected String resolvePath(String path) {
// TODO SPR-7508: note that ARAC cannot delegate to its beanFactory's environment
// to call Environment.resolve[Required]Placeholders(String), as the bean factory
// has not yet been initialized. This amounts to one more reason not to use the ARAC
// hierarchy - it won't have early access to environment property resolution.
return SystemPropertyUtils.resolvePlaceholders(path);
}

View File

@ -83,6 +83,7 @@ public abstract class AbstractXmlApplicationContext extends AbstractRefreshableC
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

View File

@ -27,8 +27,10 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.env.Environment;
import org.springframework.util.StringValueResolver;
/**
@ -37,18 +39,24 @@ import org.springframework.util.StringValueResolver;
* implement the {@link ResourceLoaderAware}, {@link MessageSourceAware},
* {@link ApplicationEventPublisherAware} and/or
* {@link ApplicationContextAware} interfaces.
* If all of them are implemented, they are satisfied in the given order.
*
* <p>Also delegates the ApplicationContext {@link Environment} instance
* to beans that implement {@link EnvironmentAware}.
*
* <p>Implemented interfaces are satisfied in order of their mention above.
*
* <p>Application contexts will automatically register this with their
* underlying bean factory. Applications do not use this directly.
*
* @author Juergen Hoeller
* @author Costin Leau
* @author Chris Beams
* @since 10.10.2003
* @see org.springframework.context.ResourceLoaderAware
* @see org.springframework.context.MessageSourceAware
* @see org.springframework.context.ApplicationEventPublisherAware
* @see org.springframework.context.ApplicationContextAware
* @see org.springframework.context.EnvironmentAware
* @see org.springframework.context.support.AbstractApplicationContext#refresh()
*/
class ApplicationContextAwareProcessor implements BeanPostProcessor {
@ -105,6 +113,9 @@ class ApplicationContextAwareProcessor implements BeanPostProcessor {
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
}
public Object postProcessAfterInitialization(Object bean, String beanName) {

View File

@ -0,0 +1,115 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.context.support;
import java.util.LinkedList;
import java.util.Properties;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AbstractPropertyPlaceholderConfigurer;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.util.Assert;
import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver;
/**
* TODO SPR-7508: document
*
* Local properties are added as a property source in any case. Precedence is based
* on the value of the {@link #setLocalOverride(boolean) localOverride} property.
*
* @author Chris Beams
* @since 3.1
* @see PropertyPlaceholderConfigurer
* @see EnvironmentAwarePropertyOverrideConfigurer
*/
public class EnvironmentAwarePropertyPlaceholderConfigurer
extends AbstractPropertyPlaceholderConfigurer implements EnvironmentAware {
private ConfigurableEnvironment environment;
private Environment wrappedEnvironment;
public void setEnvironment(Environment environment) {
this.wrappedEnvironment = environment;
}
@Override
protected PlaceholderResolver getPlaceholderResolver(Properties props) {
return new PlaceholderResolver() {
public String resolvePlaceholder(String placeholderName) {
return environment.getProperty(placeholderName);
}
};
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
Assert.notNull(this.wrappedEnvironment, "Environment must not be null. Did you call setEnvironment()?");
environment = new AbstractEnvironment() { };
LinkedList<PropertySource<?>> propertySources = environment.getPropertySources();
EnvironmentPropertySource environmentPropertySource =
new EnvironmentPropertySource("wrappedEnvironment", wrappedEnvironment);
if (!this.localOverride) {
propertySources.add(environmentPropertySource);
}
if (this.localProperties != null) {
int cx=0;
for (Properties localProps : this.localProperties) {
propertySources.add(new PropertiesPropertySource("localProperties"+cx++, localProps));
}
}
if (this.localOverride) {
propertySources.add(environmentPropertySource);
}
super.postProcessBeanFactory(beanFactory);
}
static class EnvironmentPropertySource extends PropertySource<Environment> {
public EnvironmentPropertySource(String name, Environment source) {
super(name, source);
}
@Override
public boolean containsProperty(String key) {
return source.containsProperty(key);
}
@Override
public String getProperty(String key) {
return source.getProperty(key);
}
@Override
public int size() {
// TODO Auto-generated method stub
return source.getPropertyCount();
}
}
}

View File

@ -28,6 +28,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
@ -78,6 +79,7 @@ import org.springframework.util.Assert;
* from the {@link AbstractRefreshableApplicationContext} base class.
*
* @author Juergen Hoeller
* @author Chris Beams
* @since 1.1.2
* @see #registerBeanDefinition
* @see #refresh()
@ -102,6 +104,7 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
this.beanFactory = new DefaultListableBeanFactory();
this.beanFactory.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer());
this.beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
registerStandardBeanFactoryPostProcessors(this.beanFactory);
}
/**
@ -181,7 +184,7 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
* delegate all <code>getResource</code> calls to the given ResourceLoader.
* If not set, default resource loading will apply.
* <p>The main reason to specify a custom ResourceLoader is to resolve
* resource paths (withour URL prefix) in a specific fashion.
* resource paths (without URL prefix) in a specific fashion.
* The default behavior is to resolve such paths as class path locations.
* To resolve resource paths as file system locations, specify a
* FileSystemResourceLoader here.

View File

@ -17,7 +17,7 @@
package org.springframework.context.support;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.Resource;
/**
@ -47,6 +47,7 @@ public class GenericXmlApplicationContext extends GenericApplicationContext {
* through {@link #load} calls and then manually {@link #refresh refreshed}.
*/
public GenericXmlApplicationContext() {
reader.setEnvironment(this.getEnvironment());
}
/**
@ -88,6 +89,15 @@ public class GenericXmlApplicationContext extends GenericApplicationContext {
this.reader.setValidating(validating);
}
/**
* Set a custom environment. Should be called before any call to
* {@link #load}. TODO SPR-7508: document
*/
@Override
public void setEnvironment(ConfigurableEnvironment environment) {
super.setEnvironment(environment);
this.reader.setEnvironment(this.getEnvironment());
}
/**
* Load bean definitions from the given XML resources.

View File

@ -21,6 +21,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
@ -29,6 +30,8 @@ import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanNotOfRequiredTypeException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.DefaultEnvironment;
import org.springframework.jndi.JndiLocatorSupport;
import org.springframework.jndi.TypeMismatchNamingException;
@ -67,6 +70,9 @@ public class SimpleJndiBeanFactory extends JndiLocatorSupport implements BeanFac
/** Cache of the types of nonshareable resources: bean name --> bean type */
private final Map<String, Class> resourceTypes = new HashMap<String, Class>();
/** TODO SPR-7508: should be JNDI-specific environment */
private ConfigurableEnvironment environment = new DefaultEnvironment();
public SimpleJndiBeanFactory() {
setResourceRef(true);
@ -94,6 +100,11 @@ public class SimpleJndiBeanFactory extends JndiLocatorSupport implements BeanFac
}
//---------------------------------------------------------------------
// Implementation of BeanFactory interface
//---------------------------------------------------------------------
public Object getBean(String name) throws BeansException {
return getBean(name, Object.class);
}

View File

@ -1,13 +1,17 @@
http\://www.springframework.org/schema/context/spring-context-2.5.xsd=org/springframework/context/config/spring-context-2.5.xsd
http\://www.springframework.org/schema/context/spring-context-3.0.xsd=org/springframework/context/config/spring-context-3.0.xsd
http\://www.springframework.org/schema/context/spring-context.xsd=org/springframework/context/config/spring-context-3.0.xsd
http\://www.springframework.org/schema/context/spring-context-3.1.xsd=org/springframework/context/config/spring-context-3.1.xsd
http\://www.springframework.org/schema/context/spring-context.xsd=org/springframework/context/config/spring-context-3.1.xsd
http\://www.springframework.org/schema/jee/spring-jee-2.0.xsd=org/springframework/ejb/config/spring-jee-2.0.xsd
http\://www.springframework.org/schema/jee/spring-jee-2.5.xsd=org/springframework/ejb/config/spring-jee-2.5.xsd
http\://www.springframework.org/schema/jee/spring-jee-3.0.xsd=org/springframework/ejb/config/spring-jee-3.0.xsd
http\://www.springframework.org/schema/jee/spring-jee.xsd=org/springframework/ejb/config/spring-jee-3.0.xsd
http\://www.springframework.org/schema/jee/spring-jee-3.1.xsd=org/springframework/ejb/config/spring-jee-3.1.xsd
http\://www.springframework.org/schema/jee/spring-jee.xsd=org/springframework/ejb/config/spring-jee-3.1.xsd
http\://www.springframework.org/schema/lang/spring-lang-2.0.xsd=org/springframework/scripting/config/spring-lang-2.0.xsd
http\://www.springframework.org/schema/lang/spring-lang-2.5.xsd=org/springframework/scripting/config/spring-lang-2.5.xsd
http\://www.springframework.org/schema/lang/spring-lang-3.0.xsd=org/springframework/scripting/config/spring-lang-3.0.xsd
http\://www.springframework.org/schema/lang/spring-lang.xsd=org/springframework/scripting/config/spring-lang-3.0.xsd
http\://www.springframework.org/schema/lang/spring-lang-3.1.xsd=org/springframework/scripting/config/spring-lang-3.1.xsd
http\://www.springframework.org/schema/lang/spring-lang.xsd=org/springframework/scripting/config/spring-lang-3.1.xsd
http\://www.springframework.org/schema/task/spring-task-3.0.xsd=org/springframework/scheduling/config/spring-task-3.0.xsd
http\://www.springframework.org/schema/task/spring-task.xsd=org/springframework/scheduling/config/spring-task-3.0.xsd
http\://www.springframework.org/schema/task/spring-task-3.1.xsd=org/springframework/scheduling/config/spring-task-3.1.xsd
http\://www.springframework.org/schema/task/spring-task.xsd=org/springframework/scheduling/config/spring-task-3.1.xsd

View File

@ -0,0 +1,500 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.springframework.org/schema/context"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://www.springframework.org/schema/context"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd" />
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd" />
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines the configuration elements for the Spring Framework's application
context support. Effects the activation of various configuration styles
for the containing Spring ApplicationContext.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType name="propertyPlaceholder">
<xsd:attribute name="location" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The location of the properties file to resolve placeholders against, as a Spring
resource location: a URL, a "classpath:" pseudo URL, or a relative file path.
Multiple locations may be specified, separated by commas. If neither location nor properties-ref is
specified, placeholders will be resolved against system properties.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="properties-ref" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:java.util.Properties"><![CDATA[
The bean name of a Java Properties object that will be used for property substitution.
If neither location nor properties-ref is specified, placeholders will be resolved against system properties.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="file-encoding" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies the encoding to use for parsing properties files. Default is none,
using the java.util.Properties default encoding. Only applies to classic
properties files, not to XML files.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="order" type="xsd:integer">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies the order for this placeholder configurer. If more than one is present in a context
the order can be important since the first one to be match a placeholder will win. Often used
in conjunction with
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ignore-resource-not-found" type="xsd:boolean"
default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies if failure to find the property resource location should be ignored. Default
is "false", meaning that if there is no file in the location specified an exception will
be raised at runtime.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ignore-unresolvable" type="xsd:boolean"
default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies if failure to find the property value to replace a key should be ignored. Default
is "false", meaning that this placeholder configurer will raise an exception if it cannot resolve
a key. Set to "true" to allow the configurer to pass on the key to any others in
the context that have not yet visited the key in question.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="local-override" type="xsd:boolean"
default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies whether local properties override properties from files. Default
is "false": Properties from files override local defaults.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:element name="property-placeholder">
<xsd:annotation>
<xsd:documentation><![CDATA[
Activates replacement of ${...} placeholders, resolved against the specified properties file or
Properties object (if any). Defines an EnvironmentAwarePropertyPlaceholderConfigurer within the context.
For backward compatibility with versions earlier than Spring 3.1, a PropertyPlaceholderConfigurer will be
registered if the 'system-properties-mode' attribute has been explicitly assigned a value.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports
type="org.springframework.beans.factory.config.AbstractPropertyPlaceholderConfigurer" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="propertyPlaceholder">
<xsd:attribute name="system-properties-mode" default="DELEGATE">
<xsd:annotation>
<xsd:documentation><![CDATA[
If set to any value other than DELEGATE, register a PropertyPlaceholderConfigurer bean and call
its setSystemPropertiesModeName() method with the value. If set to DELEGATE (the default), register
an EnvironmentAwarePropertyPlaceholderConfigurer and ignore the setting altogether, instead delegating
to the enclosing application context's Environment object and its collection of PropertySource objects
which may or may not include system properties and environment variables.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="DELEGATE"/>
<xsd:enumeration value="NEVER"/>
<xsd:enumeration value="FALLBACK"/>
<xsd:enumeration value="OVERRIDE"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="property-override">
<xsd:annotation>
<xsd:documentation><![CDATA[
Activates pushing of override values into bean properties, based on configuration
lines of the following format: beanName.property=value
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports
type="org.springframework.beans.factory.config.PropertyOverrideConfigurer" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="propertyPlaceholder" />
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="annotation-config">
<xsd:annotation>
<xsd:documentation><![CDATA[
Activates various annotations to be detected in bean classes: Spring's @Required and
@Autowired, as well as JSR 250's @PostConstruct, @PreDestroy and @Resource (if available),
JAX-WS's @WebServiceRef (if available), EJB3's @EJB (if available), and JPA's
@PersistenceContext and @PersistenceUnit (if available). Alternatively, you may
choose to activate the individual BeanPostProcessors for those annotations.
Note: This tag does not activate processing of Spring's @Transactional or EJB3's
@TransactionAttribute annotation. Consider the use of the <tx:annotation-driven>
tag for that purpose.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="component-scan">
<xsd:annotation>
<xsd:documentation><![CDATA[
Scans the classpath for annotated components that will be auto-registered as
Spring beans. By default, the Spring-provided @Component, @Repository,
@Service, and @Controller stereotypes will be detected.
Note: This tag implies the effects of the 'annotation-config' tag, activating @Required,
@Autowired, @PostConstruct, @PreDestroy, @Resource, @PersistenceContext and @PersistenceUnit
annotations in the component classes, which is usually desired for autodetected components
(without external configuration). Turn off the 'annotation-config' attribute to deactivate
this default behavior, for example in order to use custom BeanPostProcessor definitions
for handling those annotations.
Note: You may use placeholders in package paths, but only resolved against system
properties (analogous to resource paths). A component scan results in new bean definition
being registered; Spring's PropertyPlaceholderConfigurer will apply to those bean
definitions just like to regular bean definitions, but it won't apply to the component
scan settings themselves.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="include-filter" type="filterType"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls which eligible types to include for component scanning.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="exclude-filter" type="filterType"
minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls which eligible types to exclude for component scanning.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="base-package" type="xsd:string"
use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The comma-separated list of packages to scan for annotated components.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="resource-pattern" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls the class files eligible for component detection. Defaults to "**/*.class", the recommended value.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="use-default-filters" type="xsd:boolean"
default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether automatic detection of classes annotated with @Component, @Repository, @Service,
or @Controller should be enabled. Default is "true".
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="annotation-config" type="xsd:boolean"
default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether the implicit annotation post-processors should be enabled. Default is "true".
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="name-generator" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The fully-qualified class name of the BeanNameGenerator to be used for naming detected components.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-type type="java.lang.Class" />
<tool:assignable-to
type="org.springframework.beans.factory.support.BeanNameGenerator" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="scope-resolver" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The fully-qualified class name of the ScopeMetadataResolver to be used for resolving the scope of
detected components.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-type type="java.lang.Class" />
<tool:assignable-to
type="org.springframework.context.annotation.ScopeMetadataResolver" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="scoped-proxy">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether proxies should be generated for detected components, which may be necessary
when using scopes in a proxy-style fashion. Default is to generate no such proxies.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="no" />
<xsd:enumeration value="interfaces" />
<xsd:enumeration value="targetClass" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="load-time-weaver">
<xsd:annotation>
<xsd:documentation><![CDATA[
Activates a Spring LoadTimeWeaver for this application context, available as
a bean with the name "loadTimeWeaver". Any bean that implements the
LoadTimeWeaverAware interface will then receive the LoadTimeWeaver reference
automatically; for example, Spring's JPA bootstrap support.
The default weaver is determined automatically. As of Spring 2.5: detecting
Sun's GlassFish, Oracle's OC4J, Spring's VM agent and any ClassLoader
supported by Spring's ReflectiveLoadTimeWeaver (for example, the
TomcatInstrumentableClassLoader).
The activation of AspectJ load-time weaving is specified via a simple flag
(the 'aspectj-weaving' attribute), with the AspectJ class transformer
registered through Spring's LoadTimeWeaver. AspectJ weaving will be activated
by default if a "META-INF/aop.xml" resource is present in the classpath.
This also activates the current application context for applying dependency
injection to non-managed classes that are instantiated outside of the Spring
bean factory (typically classes annotated with the @Configurable annotation).
This will only happen if the AnnotationBeanConfigurerAspect is on the classpath
(i.e. spring-aspects.jar), effectively activating "spring-configured" by default.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports
type="org.springframework.instrument.classloading.LoadTimeWeaver" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="weaver-class" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The fully-qualified classname of the LoadTimeWeaver that is to be activated.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-type type="java.lang.Class" />
<tool:assignable-to
type="org.springframework.instrument.classloading.LoadTimeWeaver" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="aspectj-weaving" default="autodetect">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="on">
<xsd:annotation>
<xsd:documentation><![CDATA[
Switches Spring-based AspectJ load-time weaving on.
]]></xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="off">
<xsd:annotation>
<xsd:documentation><![CDATA[
Switches Spring-based AspectJ load-time weaving off.
]]></xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="autodetect">
<xsd:annotation>
<xsd:documentation><![CDATA[
Switches AspectJ load-time weaving on if a "META-INF/aop.xml" resource
is present in the classpath. If there is no such resource, then AspectJ
load-time weaving will be switched off.
]]></xsd:documentation>
</xsd:annotation>
</xsd:enumeration>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="spring-configured">
<xsd:annotation>
<xsd:documentation
source="java:org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect">
<![CDATA[
Signals the current application context to apply dependency injection
to non-managed classes that are instantiated outside of the Spring bean
factory (typically classes annotated with the @Configurable annotation).
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string" />
</xsd:simpleType>
</xsd:element>
<xsd:element name="mbean-export">
<xsd:annotation>
<xsd:documentation
source="java:org.springframework.jmx.export.annotation.AnnotationMBeanExporter"><![CDATA[
Activates default exporting of MBeans by detecting standard MBeans in the Spring
context as well as @ManagedResource annotations on Spring-defined beans.
The resulting MBeanExporter bean is defined under the name "mbeanExporter".
Alternatively, consider defining a custom AnnotationMBeanExporter bean explicitly.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports
type="org.springframework.jmx.export.annotation.AnnotationMBeanExporter" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="default-domain" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The default domain to use when generating JMX ObjectNames.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="server" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The bean name of the MBeanServer to which MBeans should be exported.
Default is to use the platform's default MBeanServer (autodetecting
WebLogic 9+, WebSphere 5.1+ and the JDK 1.5+ platform MBeanServer).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="registration">
<xsd:annotation>
<xsd:documentation><![CDATA[
The registration behavior, indicating how to deal with existing MBeans
of the same name: fail with an exception, ignore and keep the existing
MBean, or replace the existing one with the new MBean.
Default is to fail with an exception.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:NMTOKEN">
<xsd:enumeration value="failOnExisting" />
<xsd:enumeration value="ignoreExisting" />
<xsd:enumeration value="replaceExisting" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="mbean-server">
<xsd:annotation>
<xsd:documentation
source="java:org.springframework.jmx.support.MBeanServerFactoryBean"><![CDATA[
Exposes a default MBeanServer for the current platform.
Autodetects WebLogic 9+, WebSphere 6.1+ and the JDK 1.5+ platform MBeanServer.
The default bean name for the exposed MBeanServer is "mbeanServer".
This may be customized through specifying the "id" attribute.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="javax.management.MBeanServer" />
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="agent-id" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The agent id of the target MBeanServer, if any.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="filterType">
<xsd:attribute name="type" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls the type of filtering to apply to the expression.
"annotation" indicates an annotation to be present at the type level in target components;
"assignable" indicates a class (or interface) that the target components are assignable to (extend/implement);
"aspectj" indicates an AspectJ type expression to be matched by the target components;
"regex" indicates a regex expression to be matched by the target components' class names;
"custom" indicates a custom implementation of the org.springframework.core.type.TypeFilter interface.
Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per concrete bean definition.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="annotation" />
<xsd:enumeration value="assignable" />
<xsd:enumeration value="aspectj" />
<xsd:enumeration value="regex" />
<xsd:enumeration value="custom" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="expression" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates the filter expression, the type of which is indicated by "type".
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:schema>

View File

@ -0,0 +1,254 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/jee"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://www.springframework.org/schema/jee"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd"/>
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines configuration elements for access to traditional Java EE components
such as JNDI resources and EJB session beans.
]]></xsd:documentation>
</xsd:annotation>
<xsd:element name="jndi-lookup">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.jndi.JndiObjectFactoryBean"><![CDATA[
Exposes an object reference via a JNDI lookup.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="jndiLocatingType">
<xsd:attribute name="cache" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether the object returned from the JNDI lookup is cached
after the first lookup.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expected-type" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:java.lang.Class"><![CDATA[
The type that the located JNDI object is supposed to be assignable
to, if indeed any.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="lookup-on-startup" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether the JNDI lookup is performed immediately on startup
(if true, the default), or on first access (if false).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="proxy-interface" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:java.lang.Class"><![CDATA[
The proxy interface to use for the JNDI object.
Needs to be specified because the actual JNDI object type is not
known in advance in case of a lazy lookup.
Typically used in conjunction with "lookupOnStartup"=false and/or
"cache"=false.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-type type="java.lang.Class"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="default-value" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specify a default literal value to fall back to if the JNDI lookup fails.
This is typically used for literal values in scenarios where the JNDI environment
might define specific config settings but those are not required to be present.
Default is none. Note: This is only supported for lookup on startup.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="default-ref" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specify a default bean reference to fall back to if the JNDI lookup fails.
This might for example point to a local fallback DataSource.
Default is none. Note: This is only supported for lookup on startup.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="local-slsb" type="ejbType">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean"><![CDATA[
Exposes a reference to a local EJB Stateless SessionBean.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="remote-slsb">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean"><![CDATA[
Exposes a reference to a remote EJB Stateless SessionBean.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="ejbType">
<xsd:attribute name="home-interface" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:java.lang.Class"><![CDATA[
The home interface that will be narrowed to before performing
the parameterless SLSB create() call that returns the actual
SLSB proxy.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="refresh-home-on-connect-failure" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether to refresh the EJB home on connect failure.
Can be turned on to allow for hot restart of the EJB server.
If a cached EJB home throws an RMI exception that indicates a
remote connect failure, a fresh home will be fetched and the
invocation will be retried.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cache-session-bean" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether to cache the actual session bean object.
Off by default for standard EJB compliance. Turn this flag
on to optimize session bean access for servers that are
known to allow for caching the actual session bean object.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<!-- base types -->
<xsd:complexType name="jndiLocatingType" abstract="true">
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:sequence>
<xsd:element name="environment" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
The newline-separated, key-value pairs for the JNDI environment
(in standard Properties format, namely 'key=value' pairs)
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="environment-ref" type="environmentRefType">
<xsd:annotation>
<xsd:documentation><![CDATA[
A reference to JNDI environment properties, indicating the name of a
shared bean of type [java.util.Properties}.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="jndi-name" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The JNDI name to look up. This may be a fully-qualified JNDI path
or a local Java EE environment naming context path in which case the
prefix "java:comp/env/" will be prepended if applicable.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="resource-ref" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether the lookup occurs in a Java EE container, i.e. if the
prefix "java:comp/env/" needs to be added if the JNDI name doesn't
already contain it. Default is "true" (since Spring 2.5).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="expose-access-context" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Set whether to expose the JNDI environment context for all access to the target
EJB, i.e. for all method invocations on the exposed object reference.
Default is "false", i.e. to only expose the JNDI context for object lookup.
Switch this flag to "true" in order to expose the JNDI environment (including
the authorization context) for each EJB invocation, as needed by WebLogic
for EJBs with authorization requirements.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="ejbType">
<xsd:complexContent>
<xsd:extension base="jndiLocatingType">
<xsd:attribute name="lookup-home-on-startup" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether the lookup of the EJB home object is performed
immediately on startup (if true, the default), or on first access
(if false).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cache-home" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether the EJB home object is cached once it has been located.
On by default; turn this flag off to always reobtain fresh home objects.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="business-interface" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation source="java:java.lang.Class"><![CDATA[
The business interface of the EJB being proxied.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:simpleType name="environmentRefType">
<xsd:annotation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="java.util.Properties"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
<xsd:union memberTypes="xsd:string"/>
</xsd:simpleType>
</xsd:schema>

View File

@ -0,0 +1,233 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/task"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://www.springframework.org/schema/task"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines the elements used in the Spring Framework's support for task execution and scheduling.
]]></xsd:documentation>
</xsd:annotation>
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd"/>
<xsd:element name="annotation-driven">
<xsd:annotation>
<xsd:documentation><![CDATA[
Enables the detection of @Async and @Scheduled annotations on any Spring-managed object. If present,
a proxy will be generated for executing the annotated methods asynchronously.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="executor" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies the java.util.Executor instance to use when invoking asynchronous methods.
If not provided, an instance of org.springframework.core.task.SimpleAsyncTaskExecutor
will be used by default
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="scheduler" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Specifies the org.springframework.scheduling.TaskScheduler or
java.util.ScheduledExecutorService instance to use when invoking scheduled
methods. If no reference is provided, a TaskScheduler backed by a single
thread scheduled executor will be used.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="scheduler">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a ThreadPoolTaskScheduler instance with configurable pool size.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The bean name for the generated ThreadPoolTaskScheduler instance.
It will also be used as the default thread name prefix.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pool-size" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The size of the ScheduledExecutorService's thread pool. The default is 1.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="executor">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines a ThreadPoolTaskExecutor instance with configurable pool size,
queue-capacity, keep-alive, and rejection-policy values.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="id" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The bean name for the generated ThreadPoolTaskExecutor instance.
This value will also be used as the thread name prefix which is why it is
required even when defining the executor as an inner bean: The executor
won't be directly accessible then but will nevertheless use the specified
id as the thread name prefix of the threads that it manages.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pool-size" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The size of the executor's thread pool as either a single value or a range
(e.g. 5-10). If no bounded queue-capacity value is provided, then a max value
has no effect unless the range is specified as 0-n. In that case, the core pool
will have a size of n, but the 'allowCoreThreadTimeout' flag will be set to true.
If a queue-capacity is provided, then the lower bound of a range will map to the
core size and the upper bound will map to the max size. If this attribute is not
provided, the default core size will be 1, and the default max size will be
Integer.MAX_VALUE (i.e. unbounded).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="queue-capacity" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Queue capacity for the ThreadPoolTaskExecutor. If not specified, the default will
be Integer.MAX_VALUE (i.e. unbounded).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="keep-alive" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Keep-alive time in seconds. Inactive threads that have been created beyond the
core size will timeout after the specified number of seconds elapse. If the
executor has an unbounded queue capacity and a size range represented as 0-n,
then the core threads will also be configured to timeout when inactive.
Otherwise, core threads will not ever timeout.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="rejection-policy" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The RejectedExecutionHandler type. When a bounded queue cannot accept any
additional tasks, this determines the behavior. While the default is ABORT,
consider using CALLER_RUNS to throttle inbound tasks. In other words, by forcing
the caller to run the task itself, it will not be able to provide another task
until after it completes the task at hand. In the meantime, one or more tasks
may be removed from the queue. Alternatively, if it is not critical to run every
task, consider using DISCARD to drop the current task or DISCARD_OLDEST to drop
the task at the head of the queue.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ABORT"/>
<xsd:enumeration value="CALLER_RUNS"/>
<xsd:enumeration value="DISCARD"/>
<xsd:enumeration value="DISCARD_OLDEST"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="scheduled-tasks">
<xsd:annotation>
<xsd:documentation><![CDATA[
Top-level element that contains one or more task sub-elements to be
managed by a given TaskScheduler.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="scheduled" type="scheduledTaskType" minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="scheduler" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Reference to an instance of TaskScheduler to manage the provided tasks. If not specified,
the default value will be a wrapper for a single-threaded Executor.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="org.springframework.scheduling.TaskScheduler"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="scheduledTaskType">
<xsd:annotation>
<xsd:documentation><![CDATA[
Element defining a scheduled method-invoking task and its corresponding trigger.
]]></xsd:documentation>
</xsd:annotation>
<xsd:attribute name="cron" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
A cron-based trigger. See the org.springframework.scheduling.support.CronSequenceGenerator
JavaDoc for example patterns.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="fixed-delay" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
An interval-based trigger where the interval is measured from the completion time of the
previous task. The time unit value is measured in milliseconds.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="fixed-rate" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
An interval-based trigger where the interval is measured from the start time of the
previous task. The time unit value is measured in milliseconds.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="ref" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
Reference to an object that provides a method to be invoked.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref" />
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="method" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the method to be invoked.
]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:expected-method type-ref="@ref"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:schema>

View File

@ -0,0 +1,199 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.springframework.org/schema/lang"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
targetNamespace="http://www.springframework.org/schema/lang"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines the elements used in the Spring Framework's dynamic language
support, which allows bean definitions that are backed by classes
written in a language other than Java.
]]></xsd:documentation>
</xsd:annotation>
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="http://www.springframework.org/schema/tool/spring-tool-3.1.xsd"/>
<xsd:element name="defaults">
<xsd:annotation>
<xsd:documentation><![CDATA[
Default settings for any scripted beans registered within this context.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attributeGroup ref="defaultableAttributes"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="groovy" type="customizableScriptType">
<xsd:annotation>
<xsd:documentation><![CDATA[
A Spring bean backed by a Groovy class definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="jruby" type="dynamicScriptType">
<xsd:annotation>
<xsd:documentation><![CDATA[
A Spring bean backed by a JRuby class definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="bsh" type="dynamicScriptType">
<xsd:annotation>
<xsd:documentation><![CDATA[
A Spring bean backed by a BeanShell script.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- Script Types -->
<xsd:complexType name="simpleScriptType">
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:sequence>
<xsd:element name="inline-script" minOccurs="0" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
The source code for the dynamic language-backed bean.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="property" type="beans:propertyType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation><![CDATA[
Dynamic language-backed bean definitions can have zero or more properties.
Property elements correspond to JavaBean setter methods exposed
by the bean classes. Spring supports primitives, references to other
beans in the same or related factories, lists, maps and properties.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attributeGroup ref="defaultableAttributes"/>
<xsd:attribute name="script-source" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.core.io.Resource"><![CDATA[
The resource containing the script for the dynamic language-backed bean.
Examples might be '/WEB-INF/scripts/Anais.groovy', 'classpath:Nin.bsh', etc.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="name" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of this scripted bean as an alias or replacement for the id.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="scope" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The scope of this scripted bean: typically "singleton" (one shared instance,
which will be returned by all calls to getBean with the given id), or
"prototype" (independent instance resulting from each call to getBean).
Default is "singleton".
Singletons are most commonly used, and are ideal for multi-threaded
service objects. Further scopes, such as "request" or "session", might
be supported by extended bean factories (e.g. in a web environment).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="autowire" default="default">
<xsd:annotation>
<xsd:documentation><![CDATA[
The autowire mode for the scripted bean.
Analogous to the 'autowire' attribute on a standard bean definition.
]]></xsd:documentation>
</xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:NMTOKEN">
<xsd:enumeration value="default"/>
<xsd:enumeration value="no"/>
<xsd:enumeration value="byName"/>
<xsd:enumeration value="byType"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="depends-on" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The names of the beans that this bean depends on being initialized.
The bean factory will guarantee that these beans get initialized
before this bean.
Note that dependencies are normally expressed through bean properties.
This property should just be necessary other kinds of dependencies
like statics (*ugh*) or database preparation on startup.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="init-method" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of an initialization method defined on the scripted bean.
Analogous to the 'init-method' attribute on a standard bean definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="destroy-method" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of a destruction method defined on the scripted bean.
Analogous to the 'destroy-method' attribute on a standard bean definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="dynamicScriptType">
<xsd:complexContent>
<xsd:extension base="simpleScriptType">
<xsd:attribute name="script-interfaces">
<xsd:annotation>
<xsd:documentation source="java:java.lang.Class"><![CDATA[
The Java interfaces that the dynamic language-backed object is to expose; comma-delimited.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="customizableScriptType">
<xsd:complexContent>
<xsd:extension base="simpleScriptType">
<xsd:attribute name="customizer-ref">
<xsd:annotation>
<xsd:documentation><![CDATA[
Reference to a GroovyObjectCustomizer or similar customizer bean.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:attributeGroup name="defaultableAttributes">
<xsd:attribute name="refresh-check-delay" type="xsd:long">
<xsd:annotation>
<xsd:documentation><![CDATA[
The delay (in milliseconds) between checks for updated sources when
using the refreshable beans feature.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:attributeGroup>
</xsd:schema>

View File

@ -0,0 +1,13 @@
package example.profilescan;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Profile(ProfileAnnotatedComponent.PROFILE_NAME)
@Component(ProfileAnnotatedComponent.BEAN_NAME)
public class ProfileAnnotatedComponent {
public static final String BEAN_NAME = "profileAnnotatedComponent";
public static final String PROFILE_NAME = "test";
}

Some files were not shown because too many files have changed in this diff Show More