XML Schemas

This part of the appendix lists XML schemas related to the core container.

The util Schema

As the name implies, the util tags deal with common, utility configuration issues, such as configuring collections, referencing constants, and so forth. To use the tags in the util schema, you need to have the following preamble at the top of your Infra XML configuration file (the text in the snippet references the correct schema so that the tags in the util namespace are available to you):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:util="http://www.springframework.org/schema/util"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">

    <!-- bean definitions here -->

</beans>

Using <util:constant/>

Consider the following bean definition:

<bean id="..." class="...">
  <property name="isolation">
    <bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
        class="cn.taketoday.beans.factory.config.FieldRetrievingFactoryBean" />
  </property>
</bean>

The preceding configuration uses a Infra FactoryBean implementation (the FieldRetrievingFactoryBean) to set the value of the isolation property on a bean to the value of the java.sql.Connection.TRANSACTION_SERIALIZABLE constant. This is all well and good, but it is verbose and (unnecessarily) exposes Infra internal plumbing to the end user.

The following XML Schema-based version is more concise, clearly expresses the developer’s intent (“inject this constant value”), and it reads better:

<bean id="..." class="...">
  <property name="isolation">
    <util:constant static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>
  </property>
</bean>

Setting a Bean Property or Constructor Argument from a Field Value

FieldRetrievingFactoryBean is a FactoryBean that retrieves a static or non-static field value. It is typically used for retrieving public static final constants, which may then be used to set a property value or constructor argument for another bean.

The following example shows how a static field is exposed, by using the staticField property:

<bean id="myField"
    class="cn.taketoday.beans.factory.config.FieldRetrievingFactoryBean">
  <property name="staticField" value="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>
</bean>

There is also a convenience usage form where the static field is specified as the bean name, as the following example shows:

<bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
    class="cn.taketoday.beans.factory.config.FieldRetrievingFactoryBean"/>

This does mean that there is no longer any choice in what the bean id is (so any other bean that refers to it also has to use this longer name), but this form is very concise to define and very convenient to use as an inner bean since the id does not have to be specified for the bean reference, as the following example shows:

<bean id="..." class="...">
  <property name="isolation">
    <bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
        class="cn.taketoday.beans.factory.config.FieldRetrievingFactoryBean" />
  </property>
</bean>

You can also access a non-static (instance) field of another bean, as described in the API documentation for the FieldRetrievingFactoryBean class.

Injecting enumeration values into beans as either property or constructor arguments is easy to do in Infra. You do not actually have to do anything or know anything about the Infra internals (or even about classes such as the FieldRetrievingFactoryBean). The following example enumeration shows how easy injecting an enum value is:

  • Java

package jakarta.persistence;

public enum PersistenceContextType {

  TRANSACTION,
  EXTENDED
}

Now consider the following setter of type PersistenceContextType and the corresponding bean definition:

  • Java

package example;

public class Client {

  private PersistenceContextType persistenceContextType;

  public void setPersistenceContextType(PersistenceContextType type) {
    this.persistenceContextType = type;
  }
}
<bean class="example.Client">
  <property name="persistenceContextType" value="TRANSACTION"/>
</bean>

Using <util:property-path/>

Consider the following example:

<!-- target bean to be referenced by name -->
<bean id="testBean" class="cn.taketoday.beans.TestBean" scope="prototype">
  <property name="age" value="10"/>
  <property name="spouse">
    <bean class="cn.taketoday.beans.TestBean">
      <property name="age" value="11"/>
    </bean>
  </property>
</bean>

<!-- results in 10, which is the value of property 'age' of bean 'testBean' -->
<bean id="testBean.age" class="cn.taketoday.beans.factory.config.PropertyPathFactoryBean"/>

The preceding configuration uses a Infra FactoryBean implementation (the PropertyPathFactoryBean) to create a bean (of type int) called testBean.age that has a value equal to the age property of the testBean bean.

Now consider the following example, which adds a <util:property-path/> element:

<!-- target bean to be referenced by name -->
<bean id="testBean" class="cn.taketoday.beans.TestBean" scope="prototype">
  <property name="age" value="10"/>
  <property name="spouse">
    <bean class="cn.taketoday.beans.TestBean">
      <property name="age" value="11"/>
    </bean>
  </property>
</bean>

<!-- results in 10, which is the value of property 'age' of bean 'testBean' -->
<util:property-path id="name" path="testBean.age"/>

The value of the path attribute of the <property-path/> element follows the form of beanName.beanProperty. In this case, it picks up the age property of the bean named testBean. The value of that age property is 10.

Using <util:property-path/> to Set a Bean Property or Constructor Argument

PropertyPathFactoryBean is a FactoryBean that evaluates a property path on a given target object. The target object can be specified directly or by a bean name. You can then use this value in another bean definition as a property value or constructor argument.

The following example shows a path being used against another bean, by name:

<!-- target bean to be referenced by name -->
<bean id="person" class="cn.taketoday.beans.TestBean" scope="prototype">
  <property name="age" value="10"/>
  <property name="spouse">
    <bean class="cn.taketoday.beans.TestBean">
      <property name="age" value="11"/>
    </bean>
  </property>
</bean>

<!-- results in 11, which is the value of property 'spouse.age' of bean 'person' -->
<bean id="theAge"
    class="cn.taketoday.beans.factory.config.PropertyPathFactoryBean">
  <property name="targetBeanName" value="person"/>
  <property name="propertyPath" value="spouse.age"/>
</bean>

In the following example, a path is evaluated against an inner bean:

<!-- results in 12, which is the value of property 'age' of the inner bean -->
<bean id="theAge"
    class="cn.taketoday.beans.factory.config.PropertyPathFactoryBean">
  <property name="targetObject">
    <bean class="cn.taketoday.beans.TestBean">
      <property name="age" value="12"/>
    </bean>
  </property>
  <property name="propertyPath" value="age"/>
</bean>

There is also a shortcut form, where the bean name is the property path. The following example shows the shortcut form:

<!-- results in 10, which is the value of property 'age' of bean 'person' -->
<bean id="person.age"
    class="cn.taketoday.beans.factory.config.PropertyPathFactoryBean"/>

This form does mean that there is no choice in the name of the bean. Any reference to it also has to use the same id, which is the path. If used as an inner bean, there is no need to refer to it at all, as the following example shows:

<bean id="..." class="...">
  <property name="age">
    <bean id="person.age"
        class="cn.taketoday.beans.factory.config.PropertyPathFactoryBean"/>
  </property>
</bean>

You can specifically set the result type in the actual definition. This is not necessary for most use cases, but it can sometimes be useful. See the javadoc for more info on this feature.

Using <util:properties/>

Consider the following example:

<!-- creates a java.util.Properties instance with values loaded from the supplied location -->
<bean id="jdbcConfiguration" class="cn.taketoday.beans.factory.config.PropertiesFactoryBean">
  <property name="location" value="classpath:com/foo/jdbc-production.properties"/>
</bean>

The preceding configuration uses a Infra FactoryBean implementation (the PropertiesFactoryBean) to instantiate a java.util.Properties instance with values loaded from the supplied Resource location).

The following example uses a util:properties element to make a more concise representation:

<!-- creates a java.util.Properties instance with values loaded from the supplied location -->
<util:properties id="jdbcConfiguration" location="classpath:com/foo/jdbc-production.properties"/>

Using <util:list/>

Consider the following example:

<!-- creates a java.util.List instance with values loaded from the supplied 'sourceList' -->
<bean id="emails" class="cn.taketoday.beans.factory.config.ListFactoryBean">
  <property name="sourceList">
    <list>
      <value>[email protected]</value>
      <value>[email protected]</value>
      <value>[email protected]</value>
      <value>[email protected]</value>
    </list>
  </property>
</bean>

The preceding configuration uses a Infra FactoryBean implementation (the ListFactoryBean) to create a java.util.List instance and initialize it with values taken from the supplied sourceList.

The following example uses a <util:list/> element to make a more concise representation:

<!-- creates a java.util.List instance with the supplied values -->
<util:list id="emails">
  <value>[email protected]</value>
  <value>[email protected]</value>
  <value>[email protected]</value>
  <value>[email protected]</value>
</util:list>

You can also explicitly control the exact type of List that is instantiated and populated by using the list-class attribute on the <util:list/> element. For example, if we really need a java.util.LinkedList to be instantiated, we could use the following configuration:

<util:list id="emails" list-class="java.util.LinkedList">
  <value>[email protected]</value>
  <value>[email protected]</value>
  <value>[email protected]</value>
  <value>d'[email protected]</value>
</util:list>

If no list-class attribute is supplied, the container chooses a List implementation.

Using <util:map/>

Consider the following example:

<!-- creates a java.util.Map instance with values loaded from the supplied 'sourceMap' -->
<bean id="emails" class="cn.taketoday.beans.factory.config.MapFactoryBean">
  <property name="sourceMap">
    <map>
      <entry key="pechorin" value="[email protected]"/>
      <entry key="raskolnikov" value="[email protected]"/>
      <entry key="stavrogin" value="[email protected]"/>
      <entry key="porfiry" value="[email protected]"/>
    </map>
  </property>
</bean>

The preceding configuration uses a Infra FactoryBean implementation (the MapFactoryBean) to create a java.util.Map instance initialized with key-value pairs taken from the supplied 'sourceMap'.

The following example uses a <util:map/> element to make a more concise representation:

<!-- creates a java.util.Map instance with the supplied key-value pairs -->
<util:map id="emails">
  <entry key="pechorin" value="[email protected]"/>
  <entry key="raskolnikov" value="[email protected]"/>
  <entry key="stavrogin" value="[email protected]"/>
  <entry key="porfiry" value="[email protected]"/>
</util:map>

You can also explicitly control the exact type of Map that is instantiated and populated by using the 'map-class' attribute on the <util:map/> element. For example, if we really need a java.util.TreeMap to be instantiated, we could use the following configuration:

<util:map id="emails" map-class="java.util.TreeMap">
  <entry key="pechorin" value="[email protected]"/>
  <entry key="raskolnikov" value="[email protected]"/>
  <entry key="stavrogin" value="[email protected]"/>
  <entry key="porfiry" value="[email protected]"/>
</util:map>

If no 'map-class' attribute is supplied, the container chooses a Map implementation.

Using <util:set/>

Consider the following example:

<!-- creates a java.util.Set instance with values loaded from the supplied 'sourceSet' -->
<bean id="emails" class="cn.taketoday.beans.factory.config.SetFactoryBean">
  <property name="sourceSet">
    <set>
      <value>[email protected]</value>
      <value>[email protected]</value>
      <value>[email protected]</value>
      <value>[email protected]</value>
    </set>
  </property>
</bean>

The preceding configuration uses a Infra FactoryBean implementation (the SetFactoryBean) to create a java.util.Set instance initialized with values taken from the supplied sourceSet.

The following example uses a <util:set/> element to make a more concise representation:

<!-- creates a java.util.Set instance with the supplied values -->
<util:set id="emails">
  <value>[email protected]</value>
  <value>[email protected]</value>
  <value>[email protected]</value>
  <value>[email protected]</value>
</util:set>

You can also explicitly control the exact type of Set that is instantiated and populated by using the set-class attribute on the <util:set/> element. For example, if we really need a java.util.TreeSet to be instantiated, we could use the following configuration:

<util:set id="emails" set-class="java.util.TreeSet">
  <value>[email protected]</value>
  <value>[email protected]</value>
  <value>[email protected]</value>
  <value>[email protected]</value>
</util:set>

If no set-class attribute is supplied, the container chooses a Set implementation.

The aop Schema

The aop tags deal with configuring all things AOP in Infra, including Infra own proxy-based AOP framework and Infra integration with the AspectJ AOP framework. These tags are comprehensively covered in the chapter entitled Aspect Oriented Programming with Infra .

In the interest of completeness, to use the tags in the aop schema, you need to have the following preamble at the top of your Infra XML configuration file (the text in the snippet references the correct schema so that the tags in the aop namespace are available to you):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

  <!-- bean definitions here -->

</beans>

The context Schema

The context tags deal with ApplicationContext configuration that relates to plumbing — that is, not usually beans that are important to an end-user but rather beans that do a lot of the “grunt” work in Infra, such as BeanfactoryPostProcessors. The following snippet references the correct schema so that the elements in the context namespace are available to you:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

  <!-- bean definitions here -->

</beans>

Using <property-placeholder/>

This element activates the replacement of ${…​} placeholders, which are resolved against a specified properties file (as a resource location). This element is a convenience mechanism that sets up a PropertySourcesPlaceholderConfigurer for you. If you need more control over the specific PropertySourcesPlaceholderConfigurer setup, you can explicitly define it as a bean yourself.

Only one such element should be defined for a given application with the properties that it needs. Several property placeholders can be configured as long as they have distinct placeholder syntax (${…​}).

If you need to modularize the source of properties used for the replacement, you should not create multiple properties placeholders. Rather, each module should contribute a PropertySource to the Environment. Alternatively, you can create your own PropertySourcesPlaceholderConfigurer bean that gathers the properties to use.

Using <annotation-config/>

This element activates the Infra infrastructure to detect annotations in bean classes:

  • Infra @Configuration model

  • @Autowired/@Inject, @Value, and @Lookup

  • JSR-250’s @Resource, @PostConstruct, and @PreDestroy (if available)

  • JAX-WS’s @WebServiceRef and EJB 3’s @EJB (if available)

  • JPA’s @PersistenceContext and @PersistenceUnit (if available)

  • Infra @EventListener

Alternatively, you can choose to explicitly activate the individual BeanPostProcessors for those annotations.

This element does not activate processing of Infra @Transactional annotation; you can use the <tx:annotation-driven/> element for that purpose. Similarly, Infra caching annotations need to be explicitly enabled as well.

Using <component-scan/>

This element is detailed in the section on annotation-based container configuration .

Using <load-time-weaver/>

This element is detailed in the section on load-time weaving with AspectJ in the TODAY Framework .

Using <infra-configured/>

This element is detailed in the section on using AspectJ to dependency inject domain objects with Infra .

Using <mbean-export/>

This element is detailed in the section on configuring annotation-based MBean export .

The Beans Schema

Last but not least, we have the elements in the beans schema. These elements have been in Infra since the very dawn of the framework. Examples of the various elements in the beans schema are not shown here because they are quite comprehensively covered in dependencies and configuration in detail (and, indeed, in that entire chapter).

Note that you can add zero or more key-value pairs to <bean/> XML definitions. What, if anything, is done with this extra metadata is totally up to your own custom logic (and so is typically only of use if you write your own custom elements as described in the appendix entitled XML Schema Authoring).

The following example shows the <meta/> element in the context of a surrounding <bean/> (note that, without any logic to interpret it, the metadata is effectively useless as it stands).

<?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 https://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="foo" class="x.y.Foo">
    <meta key="cacheName" value="foo"/> (1)
    <property name="name" value="Rick"/>
  </bean>

</beans>
1 This is the example meta element

In the case of the preceding example, you could assume that there is some logic that consumes the bean definition and sets up some caching infrastructure that uses the supplied metadata.