Spring configuration can be done through XML. In fact, this was the only way to configure Spring beans before Java configuration was introduced. We will cover some Spring XML for reference material and for use in legacy applications.
XML
The XML standard is composed of the basic syntax, namespaces, and XML schema definitions. The syntax, in a nutshell, is based around Elements, names, typically lowercase, surrounded by greater-than and less-than symbols (like <bean>); attributes which can be set within those symbols and use double quotes (like <bean name=“myBean”); and elements can be nested, where the nesting is ended with a backslash (like </beans>).
For clarification, let’s look at the first three lines typically found in any Spring
configuration XML file and break down what they mean:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- 1.
<?xml... declares this is an XML file.
- 2.
<beans is the root element (the one element that wraps the entire document), and xmlns:=“...” declares the root namespace. This allows you to reference <bean> without specifying a namespace, for example.
- 3.
xmlns:xsi= declares the “xsi” namespace which stands for XML Schema Instance. This allows the document to subsequently use xsi:schemaLocation= to define where to locate the corresponding XML schemas.
Spring XML Configuration Organization
To keep things organized and easier to understand, it makes sense in a medium- to large-sized application to use multiple XML files and split up the configuration among them. You can decide to segregate the files in many different ways: horizontal slices (controls, services, and repositories or DAOs (Data Access Objects)), vertical slices (by feature), or by function (web services, front end, and back end).
XML Application Context
To get started, use one of the following
application contexts:
For both ClassPathXmlApplicationContext and FileSystemXmlApplicationContext, you need to specify the XML file or files.
Classpath
For example, here is an application entry class, App, that uses a
ClassPathXmlApplicationContext
:
package com.apress.spring_quick.di;
import com.apress.spring_quick.config.AppSpringConfig;
import com.apress.spring_quick.di.model.Message;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public static void main(String[] args) {
final ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("classpath:/application.xml");
final MyBeanInterface myBean = applicationContext
.getBean(MyBeanInterface.class);
//...
}
}
In this example, "classpath:/application.xml" refers to a file named application.xml
at the root of the classpath (typically included in, e.g., a JAR file). In a typical build, you should put this file in the src/main/resources/ directory, and Maven or Gradle will add it to the JAR file automatically during the build. Although here we supply one file, multiple XML files could be used.
Web
For XmlWebApplicationContext
, the default location for the root context (the application context which could be the parent of multiple servlet contexts) is "/WEB-INF/applicationContext.xml", and "/WEB-INF/<name>-servlet.xml" for a context with the namespace "<name>-servlet”. For example, with a DispatcherServlet instance with the servlet-name “products”, it would look for “/WEB-INF/products-servlet.xml”.
XML Beans
The most basic thing to do in Spring XML is to create
beans. Here is an example of how the
application.xml file might look:
<?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.xsd">
<bean class=
"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations"
value="classpath:db/datasource.properties"/>
</bean>
<bean id="dataSource1"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driverClassName}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</bean>
</beans>
Listing 4-2application.xml
This example shows how to define Spring beans and set properties on those beans. Note that you can reference properties using the ${} syntax, such as how ${db.driverClassName} references the db.driverClassName property.
Init and Destroy
The
initialize method (which is called right after Spring has instantiated and resolved all dependencies on a bean) can be configured by setting the
init-method attribute
on a bean definition, as shown in the following XML configuration:
<bean name="userService"
class="com.apress.spring_quick.service.UserService"
init-method="doInitialization" />
The
destroy method (which is called right before Spring discards a Spring bean) can be configured by setting the
destroy-method attribute
as seen in the following XML configuration:
<bean name="userService"
class="com.apress.spring_quick.service.UserService"
destroy-method="doCleanup" />
This can be used to remove any resources that are not needed
anymore when the bean is destroyed. This would call a method defined like the following:
public void doCleanup() {
// do clean up
}
Both the init-method and destroy-method should be public and have void as the return type.
Enabling AOP
In XML, use <aop:aspectj-autoproxy> in the same application context as the object to apply the aspect to (in particular, in a typical Spring Web MVC application applicationContext.xml and ...-servlet.xml).
AOP Configuration
The following example XML configuration uses Spring
AOP and the Spring Retry
1 project to repeat a service call to a method called
remoteCall in any class or interface ending with "Service":
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<aop:config>
<aop:pointcut id="remote"
expression="execution(* com..*Service.remoteCall(..))" />
<aop:advisor pointcut-ref="remote"
advice-ref="retryAdvice" />
</aop:config>
<bean id="retryAdvice"
class="org.springframework.retry.interceptor.RetryOperationsInterceptor"
/>
<!-- other bean definitions... -->
Note that the pointcut-ref references the previously defined pointcut named “remote”. Please see Chapter 5 for more details.
Enabling Spring Data JPA
Spring Data JPA allows you to interact with a database using an
ORM (Object-Relational Mapping) such as Hibernate or EclipseLink. To enable Spring Data JPA in XML, use the following XML:
<beans xmlns:="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
https://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<jpa:repositories base-package="com.acme.repositories"/>
</beans>
This would scan the "com.acme.repositories" package and below for any JPA repositories. See Chapter 6 for more information.
Mixing XML and Java Configuration
There’s no reason you can’t use a mix of XML configuration and Java configuration. In fact, you can activate Java configuration from XML and import an XML configuration file from Java.
For example, the following Spring XML file enables
Java configuration:
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.apress.spring.config" />
This XML starts a component scan in the "com.apress.spring.config" package and any subpackages. Any files marked with @Configuration, @Component, or many other annotations would be picked up by Spring.
From a Spring Java configuration file, you can use @
ImportResource to import Spring XML files, for example:
@Configuration
@ImportResource( { "spring-context1.xml", "spring-context2.xml" } )
public class ConfigClass { }
If enabled as configuration in a Spring application (either through component scanning or other means), this class would make Spring read both files, “spring-context1.xml” and “spring-context2.xml”, as Spring XML configuration.