Spring bean how to access server resource only once? - spring

I have a Spring bean which refers connection factory to access J2C resource. This code is deployed in webSphere server in 2 jvms load balanced. I had the readAuth method as init-method in bean xml but it was called multiple times during a load test. Since Spring singleton is per bean per container, I assumed there are multiple containers causing it to load multiple times. So I removed the init-method and changed the username and password to static and added null check in get methods. But now also, readAuth method is being called multiple times. I want to ensure this method is called only once per jvm since this method access server resource and connection is timing out during load test.
Please suggest a best approach on how to write this class. Thanks in advance.
<bean id="J2CUtils"
class="test.J2CUtils">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<jee:jndi-lookup id="connectionFactory" jndi-name="eis/J2CAuth" />
public class J2Ctils {
private ConnectionFactory connectionFactory;
private static String userName;
private static String password;
private void readAuth() throws ResourceException {
System.out.println("Auth loaded");
Connection conn = connectionFactory.getConnection();
Interaction interaction = (Interaction) conn.createInteraction();
Config config = interaction.getConfig();
userName = config.getUserName();
password = config.getPassword();
}
public String getUserName() {
if(null == userName) {
readAuth();
}
return userName;
}
public String getPassword() {
if(null == password) {
readAuth();
}
return password;
}
public void setConnectionFactory(ConnectionFactory connectionFactory) {
this.connectionFactory = connectionFactory;
}
}

Singletons or static methods don't help if you want to access a resource exactly once because every member of the cluster has it's own instance of the class.
Take in mind that neither the Java EE specification the Spring specification do define any kind of cluster behavior. You need to search for specific vendor solution to achieve this kind of requirement. Just as an example see have a look at #ApplicationScped in a cluster.
Other approaches to archive the expected behaviour are using a distributed lock like Zookeeper or maybe even a Queue with duplicate message filter.

Related

Spring scopes behaviour with respective to single and multiple web request/session

Whenever I try to analysis to understand the spring scopes I am stuck up somewhere. Below is my understanding from my analysis and before conclude myself I would like to confirm with you. Please correct me if my understanding is wrong.
<bean id="signupController" class="com.crp.controller.SignupController"
scope="">
If scope is "request", then for every new request from client irrespective of session, the spring container will generate new instance. Once the request is completes then spring container will manage to close the life cycle of instance.
If scope is "session", then for first request of a session a new instance will be generated by spring container and maintain it for all the client request for that particular session. Once the session timed out then spring container will manage to close the life cycle of instance.
If scope is "prototype", new instance will be generated by spring container whenever the bean is requested irrespective of session. Developer should manage the life cycle of the instance because spring container will not manage life cycle of prototype scope.
If scope is "singleton", only one instance generated by spring container and maintain it to be available for all request irrespective of sessions. For every session a copy of singleton instance will be maintained so that the one session singleton object will not share by another session and spring container will manage the life cycle of the copy of singleton instance and close it when session timed out.
Note: I believe most of you may have different opinion in my understanding on singleton scope. Even I am also confused in the behaviour of singleton scope and getting different information during my analysis. Please share your thoughts
Thank you.
For singleton scope how container works for below implementation for multiple user (session) send request at same time.
Login.java:
public class Login {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
LoginController.java:
public class LoginController extends MultiActionController {
private Login login;
public ModelAndView submitLogin(HttpServletRequest request,
HttpServletResponse response) {
String userName = request.getParameter("username");
String password= request.getParameter("password");
getLogin().setUserName(userName);
getLogin().setPassword(password);
// TODO send login bean to DAO for executing further business logic.
}
public Login getLogin() {
return login;
}
public void setLogin(Login login) {
this.login = login;
}
}
context.xml:
<bean id="login" class="com.crp.bean.Login" scope="singleton">
</bean>
<bean id="loginController" class="com.crp.controller.LoginController" scope="singleton">
<property name="login" ref="login"></property>
</bean>
No, that's not entirely correct.
If scope is "request", then for every new request from client irrespective of session, the spring container will generate new instance.
No. The bean instance will only be created if the code calls a method on the bean (i.e. on the scoped proxy that wraps the actual bean instance). But you're right that every request has a bean instance that is different from the other requests, and that the bean is destroyed at the end of the request (i.e. its life-cycle hooks, if they exist, are called when the request ends).
If scope is "session", then for first request of a session a new instance will be generated by spring container and maintain it for all the client request for that particular session.
Same remark as for the request scope: the bean instance is created on-demand.
If scope is "prototype", new instance will be generated by spring container whenever the bean is requested irrespective of session.
Right. But note that you need to request a bean instance to the spring context to get a new instance. If you inject a prototype to a singleton bean, the singleton bean will keep a reference to this bean for all of its life, and the same prototype bean will thus be used every time the singleton bean calls it.
If scope is "singleton", only one instance generated by spring container and maintain it to be available for all request irrespective of sessions. For every session a copy of singleton instance will be maintained so that the one session singleton object will not share by another session and spring container will manage the life cycle of the copy of singleton instance and close it when session timed out.
No. That is completely wrong. No copy is made at all. A single instance is created, injected everywhere, and used concurrently everywhere. The bean is only destroyed when the application itself ends.

Using one DataSource object for multiple DB connections - using only one connection at a time

Can we define only one DataSource object and wire it dynamically at runtime connecting to different databases ? I need to connect to only one database at a time.
I will be passing the name of the Database as argument. I will lookup the DB URL and other details from a property file and then I need to connect to the DB using the DB URL.
In Short - I do not know the number of databases I need to connect to. I will have all possible database connection details configured in the database.properties file following a certain syntax (like prefixed with DB01 etc.). The name of the DB will be passed as argument and I need to execute the query against that database.
database.properties file
DB01.driver=com.ibm.db2.jcc.DB2Driver
DB01.url=jdbc:db2://localhost:50000/SAMPLE
DB01.username=db2admin
DB01.password=db2admin
DAO class
#Autowired
#Qualifier("DB01") // how do I make this dynamic ?
private DataSource datasource;
private JdbcTemplate jdbcTemplate;
// some more code
public SqlRowSet executeQuery(String sqlQuery)
{
// can I pass the DB name here (the database.properties file will have the DB details
// with this name as given above) and set the DataSource Object accordingly ?
// so that the query will be executed against that DB ?
setJdbcTemplate(new JdbcTemplate(this.datasource));
return getJdbcTemplate().queryForRowSet(sqlQuery);
}
Using Spring v4.1.4 RELEASE. Thanks !!
You can define a Routing DataSource that redirects the getConnection method to one datasource or another based on a key, in your case, it seems to be the database name.
For instance, the spring xml:
....
<bean id="DB01DataSource" parent="parentDatasource" p:url="${DB01.url}" ... />
<bean id="DB02DataSource" parent="parentDatasource" p:url="${DB02.url}" .../>
<bean id="dataSource" class="DBRoutingDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="DB01" value-ref="DB01DataSource"/>
<entry key="DB02" value-ref="DB02DataSource"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="DB01DataSource"/>
</bean>
....
The DBRoutingDataSource class:
public class DBRoutingDataSource extends AbstractRoutingDataSource {
#Override
protected Object determineCurrentLookupKey() {
return DBContextHolder.getDB();
}
}
And the DBContextHolder class:
public final class DBContextHolder {
private static final ThreadLocal<String> CONTEXT = new ThreadLocal<String>();
private DBContextHolder() {
// empty
}
public static void setDB(final String db) {
CONTEXT.set(db);
}
public static String getDB() {
return CONTEXT.get();
}
public static void clearDB() {
CONTEXT.remove();
}
}
In your service class before calling your DAO you set the key that will enable the Routing DataSource to get the right connection:
DBContextHolder.setDB("DB01");
try{
dao.executeQuery(sqlSentence);
}finally{
DBContextHolder.clearDB();
}

Spring Jdbc embedded database lifecycyle

I am using spring embedded jdbc database configuration in spring context file for Junit testing. I am using in memory database for testing. I am trying to unit test only DAO layer and for unit testing I am using spring container's in memory database.
When I am running Junit test case I am not seeing first test case values in second test case (testAddressCreate in testAddressUpdate test case). I am not using #Before or #After in my Junit for now. I am not sure how spring is creating in memory database and starting it. According to behavior it seems that it is creating or resetting before each test case. Does anyone know about it? Also how can we connect to spring created in memory database. Please suggest.
Spring Configuration is :
<jdbc:embedded-database id="dataSource" type="HSQL">
<jdbc:script location="classpath:createdb.sql" />
Junit test case is :
#ContextConfiguration(locations="classpath:test-context.xml")
#Transactional
public class GenericDaoImplTest extends AbstractTransactionalJUnit4SpringContextTests {
#Autowired
private GenericDao<Address, Long> addressDao;
#Test
public void testAddressCreate() {
Address address = new Address();
address.setAddress1("first address");
address.setCity("First City");
address.setCountry("First one");
address.setPostalCode("22222");
boolean result = addressDao.create(address);
Assert.assertEquals(true, result);
List<Address> listOfAddress = addressDao.findAll();
Assert.assertNotNull(listOfAddress);
for(Address addressTemp : listOfAddress){
System.out.println(addressTemp.getAddress1());
System.out.println(addressTemp.getAddressId());
}
}
#Test
public void testAddressUpdate(){
Address address = new Address();
address.setAddress1("second address");
address.setCity("Second City");
address.setCountry("Second one");
address.setPostalCode("11111");
boolean result = addressDao.create(address);
Assert.assertEquals(true, result);
address.setAddress1("Updated Second Address");
Assert.assertNotNull(addressDao.update(address));
List<Address> listOfAddress = addressDao.findAll();
Assert.assertNotNull(listOfAddress);
for(Address addressTemp : listOfAddress){
System.out.println(addressTemp.getAddress1());
System.out.println(addressTemp.getAddressId());
}
}
}
By default, a #Transactional test method will rollback any changes made to the database during the test method. If you want to change this behavior you need to annotate your method with #Rollback(false). I don't think the documentation is specific about the default behavior, but the Javadocs mentions this here:
Retrieves the TransactionConfigurationAttributes for the specified class which may optionally declare or inherit #TransactionConfiguration. If TransactionConfiguration is not present for the supplied class, the default values for attributes defined in TransactionConfiguration will be used instead.
And the default value defined in TransactionConfiguration for rollback is "true".
These being said, you need something like this to be able to keep the values from the first #Test method in the second one:
#Test
#Rollback(false)
public void testAddressCreate() {
Address address = new Address();
...
}
For connecting at the in-memory HSQLDB, take a look at this post on Stackoverflow.

How to choose spring configuration in runtime based on a tenant?

I would like to be able to choose specific Spring (or Grails) context configuration based on the tenant that user belongs to in runtime. Let's say I use Spring Security and I retrieve tenantId during login.
Imagine now I have a two tenants and they pay different commission. How to inject specific service into a controller without too much plumbing? Here are two different contexts. So, I should inject different ExchangeService based on tenant.
#Configuration
public class FooTenant{
#Bean
public ExchangeService bar() {
return new ZeroCommisionExchangeService ();
}
}
#Configuration
public class BarTenant{
#Bean
public ExchangeService bar() {
return new StandardCommisionExchangeService ();
}
}
Edit:
I am aware I can obtain reference to Spring context and ask for service "manually", but I am looking for a more generic solution where this problematic is solved by IoC framework.
A couple of years ago we needed somthing like this but only for DataSources and ViewResolvers. We developed a solution using spring' TargetSource solution. (Initially we used a HotswappableTargetSource but that wasn't adequate for our use-case.
The code we developed is availabe here in the multi-tenant directory.
It is fully configurable and flexible.
Basically what you do is you configura a ContextSwappableTargetSource and tell it what type of interface/class it needs to return.
<bean id="yourTentantBasedServiceId" class="biz.deinum.multitenant.aop.target.ContextSwappableTargetSource">
<constructor-arg value="ExchangeService" />
</bean>
The default is to lookup beans in the ApplicationContext based on the tenantId (see the BeanFactoryTargetRegistry for this). However you can specify one or more of those (we used a JndiLookupTargetRegistry to dynamically lookup datasource, which allowed use to add tenants on the fly without restarting the application).
If you explicitly configure a BeanFactoryTargetRegistry you can add a prefix and suffix.
<bean id="exchangeService" class="biz.deinum.multitenant.aop.target.ContextSwappableTargetSource">
<constructor-arg value="ExchangeService" />
<property name="targetRegistry>
<bean class="biz.deinum.multitenant.aop.target.registry.impl.BeanFactoryTargetRegistry">
<property suffix="ExchangeService"/>
</bean>
</property>
</bean>
Now for foo it would lookup a bean named fooExchangeService and for bar barExchangeService.
The tenantId is stored in a ThreadLocal which is wrapped inside the ContextHolder. You need to find a way to fill and clear this thread local (in general a servlet Filter does that trick.
In your code you can now simply use the interface ExchangeService and at runtime based on the tenantId the correct implemenation will be looked up.
Also see http://mdeinum.wordpress.com/2007/01/05/one-application-per-client-database/
Assuming you have different services already defined, you can get their bean from the context and use it. In my example, all the services have implementation of serviceMethod and based on some criteria pick your proper service. The only thing I am not sure is how Multitenancy might impact this.
import org.springframework.context.ApplicationContext
class ServiceManagerController {
def serviceManager
def index() {
ApplicationContext ctx = grails.util.Holders.grailsApplication.mainContext
serviceManager = ctx.getBean(params.serviceName); //firstService or secondService
render serviceManager.serviceMethod()
}
}
FirstService
class FirstService {
def serviceMethod() {
return "first"
}
}
SecondService:
class SecondService {
def serviceMethod() {
return "second"
}
}
While it is possible to swap beans instantiated in a spring context at runtime (HotswappableTargetSource), it is not meant for use cases such as yours.
Remember there is one Spring Context for your application, all threads use the same instances (in most cases), this implies when you swap out a bean implementation, you are affectively doing this for all your application's users. To prevent this, you run into issues of ensuring Thread Safety, employing Thread Locals, as listed in another answer.
While it is possible to continue this approach and arrive at an implementation that gets the job done, it would definitely be a very contrived way of solving this problem.
You should take a step back and look at your problem in a more wholesome, system wide design point of view. Bust out your patterns books and look at how this can be resolved, regardless of whether you use Spring or an other framework. Service Locator, Factory bean etc described in some of the answers above is a step in the correct direction.
Your Use Case is pretty common for multi-tenant applications. You need to narrow down things that are likely to change based on a tenantId versus things that are constant across.
For instance as mentioned in the question, each Tenant might have a different commission amount or even different algorithm for commission calculation. A simple solution to this would be to implement a CommissionCalculationService which accepts a tenantId, and any other domain object based on which commission is to be calculated, I would imagine this would be something like Order or Sale, whatever makes sense in your application.
You now need a CommissionServiceFactory or a ServiceLocator which will contain tenant specific implementations of the CommissionCalculationService. The Service Locator is instantiated when the Spring context loads, and is injected with implementation classes also at application startup.
When you want to calculate commission for a tenant, you basically obtain the tenantId from the user's login, pass the tenant id to your service locator, based on the tenantId passed, the service locator returns the appropriate instance of a Service Implementation. In your calling class, use this instance to calculate the commission for the tenant.
Another pattern to consider is the Strategy Pattern, or even Template Pattern.
Bottom line, even if you want tenant specific logic implemented cleanly, don't thing about changing the beans loaded in the context. Have classes in your context that can handle all your tenant specific logic. Rely on design patterns to use the correct bean from the context based on the tenant id.
I apologize if the answer was a little verbose, I felt it was needed to explain why I think updating beans in a loaded Spring Context is not the appropriate solution.
I use the following code:
public class ConfigurableProxyFactoryBean implements FactoryBean<Object>, BeanNameAware {
#Autowired
private ApplicationContextProvider applicationContextProvider;
private Class<?> proxyType;
private String beanName;
private Object object;
private Object fallbackObject;
private Object monitor = new Object();
private ConfigurableProxy proxy;
public ConfigurableProxyFactoryBean(Class<?> proxyType) {
this.proxyType = proxyType;
}
public Object getFallbackObject() {
return fallbackObject;
}
public void setFallbackObject(Object fallbackObject) {
synchronized (monitor) {
this.fallbackObject = fallbackObject;
if (proxy != null) {
proxy.setFallbackObject(fallbackObject);
}
}
}
#Override
public void setBeanName(String name) {
beanName = name;
}
#Override
public Object getObject() throws Exception {
synchronized (monitor) {
if (object == null) {
#SuppressWarnings("unchecked")
Class<Object> type = (Class<Object>)proxyType;
proxy = new ConfigurableProxy(applicationContextProvider, beanName);
proxy.setFallbackObject(fallbackObject);
object = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class<?>[] { type }, proxy);
}
return object;
}
}
#Override
public Class<?> getObjectType() {
return proxyType;
}
#Override
public boolean isSingleton() {
return true;
}
}
class ConfigurableProxy implements InvocationHandler {
public ConfigurableProxy(ApplicationContextProvider appContextProvider, String beanName) {
this.appContextProvider = appContextProvider;
this.beanName = beanName;
}
private ApplicationContextProvider appContextProvider;
private String beanName;
private Object fallbackObject;
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
ApplicationContext appContext = appContextProvider.getApplicationContext();
String name = "$&&#" + beanName;
Object bean = appContext.containsBean(name) ? appContext.getBean(name) : fallbackObject;
return method.invoke(bean, args);
}
public void setFallbackObject(Object fallbackObject) {
this.fallbackObject = fallbackObject;
}
}
ApplicationContextProvider has implementation, that chooses ApplicationContext according to current tennant.
In XML configuration it is used like this:
<bean class="my.package.infrastructure.ConfigurableProxyFactoryBean" name="beanName">
<constructor-arg>
<value type="java.lang.Class">my.package.model.ServiceInterface</value>
</constructor-arg>
<property name="fallbackObject">
<bean class="my.package.service.DefaultServiceImplementation"/>
</property>
</bean>
And in tennant configuration that way:
<bean class="my.package.service.ServiceImplementationA" name="$&&#beanName"/>
To inject this service somewhere you just write:
public class MyController {
#Autowired
private ServiceInterface service;
}
Also you are to implement ApplicationContextProvider, I won't share mine. It is not very hard to implement. For example, your implementation can just store context in ThreadLocal. And you create your own ServletContextListener, which for every query gets the current tennant and stores it into your ApplicationContextProvider implementation.
The new tenant scope and a servicelocator can helps
Tenant scope will guarantee than service is created one time for a tenant
Sample code:
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="tenant" value="foo.TenantScope"/>
</map>
</property>
</bean>
<bean id="service" class="foo.Service" factory-bean="tenantServiceLocator" factory-method="createInstance" scope="tenant"/>
<bean id="fooService" class="FooService">
<bean id="barService" class="BarService">
<bean id="tenantServiceLocator" class="foo.TenantServiceLocator">
<property name="services">
<map>
<entry key="foo" value-ref="fooService"/>
<entry key="bar" value-ref="barService"/>
</map>
</property>
</bean>
TenantServiceLocator should know the user tenantId
public class TenantServiceLocator {
private Map<String, Service> services;
public String getTenantId() {
return "foo"; // get it from user in session
}
public Map<String, Service> getServices() {
return services;
}
public void setServices(Map<String, Service> services) {
this.services = services;
}
public Service createInstance(){
return services.get(tenantId);
}
}
public class FooController{
#Autowired
private Service service;
}
A sample TenantScope implementation
public class TenantScope implements Scope {
private static Map<String, Map<String, Object>> scopeMap = new HashMap<String, Map<String, Object>>();
#Override
public Object get(String name, ObjectFactory<?> objectFactory) {
Map<String, Object> scope = getTenantScope(getTenantId());
Object object = scope.get(name);
if(object == null){
object = objectFactory.getObject();
scope.put(name, object);
}
return object;
}
private Map<String, Object> getTenantScope(String tenantId) {
if (!scopeMap.containsKey(tenantId)) {
scopeMap.put(tenantId, new HashMap<String, Object>());
}
return scopeMap.get(tenantId);
}
private String getTenantId() {
return "foo"; // load you tenantId
}
#Override
public Object remove(String name) {
Map<String, Object> scope = getTenantScope(getTenantId());
return scope.remove(name);
}
#Override
public void registerDestructionCallback(String name, Runnable callback) {
}
#Override
public Object resolveContextualObject(String key) {
return null;
}
#Override
public String getConversationId() {
return null;
}
}
Transforming my comment in an answer, one possible solution is to create a spring factory bean, that receive all he needs to decide which service needs to be returned when creating the instance.
Translating to Grails:
public interface ChoosableServiceIntf {
String getName();
}
class NormalService implements ChoosableServiceIntf {
public String getName() {
return getClass().name;
}
}
class ExtendedService implements ChoosableServiceIntf {
public String getName() {
return getClass().name
}
}
class ChoosableServiceFactory {
static ChoosableServiceIntf getInstance(String decisionParam) {
if(decisionParam == 'X') {
return applicationContext.getBean('extendedService')
}
return applicationContext.getBean('normalService')
}
static ApplicationContext getApplicationContext() {
return Holders.grailsApplication.mainContext
}
}
Here we have two services and ChoosableServiceFactory is responsible to know witch is the correct one.
Then you will need to use the method ApplicationContext#getBean(String, Object[]) to return the correct instance and will also make the factory prototyped scope because of the runtime params.
A controller to test it:
class MyController {
def grailsApplication
def index() {
ChoosableServiceIntf service = grailsApplication.mainContext.getBean('choosableServiceFactory', ["X"] as Object[])
ChoosableServiceIntf serviceNormal = grailsApplication.mainContext.getBean('choosableServiceFactory', ["N"] as Object[])
render text: "#1 - ${service.class.name} , #2 - ${serviceNormal.class.name}"
}
}
This will print #1 - dummy.ExtendedService , #2 - dummy.NormalService
The declaration of the beans will be:
choosableServiceFactory(ChoosableServiceFactory) { bean ->
bean.scope = 'prototype'
bean.factoryMethod = 'getInstance'
}
normalService(NormalService)
extendedService(ExtendedService)

mybatis 3.1 + sprinng 3.2 properties

We have 4 applications running on a Tomcat7 server. The existing applications work on Hibernate and Spring.
The backend is connected to a second database and some old schemas are kept here live. Each schema is called xxx_live and xxx_test.
When the Tomcat server starts, a JNDI property is set for the right environment.
Test
Local
Live
The properties are parsed on an extention of the PropertySourcesPlaceholderConfigurer class:
public class GenericPropertySourcesPlaceholderConfigurer extends PropertySourcesPlaceholderConfigurer {
private String application;
private String environment;
private static final String ENVIRONMENT = "environment";
public GenericPropertySourcesPlaceholderConfigurer(String application) throws IOException {
this.application = application;
this.environment = System.getProperty(ENVIRONMENT);
if (this.environment == null) {
this.environment = System.getenv().get(ENVIRONMENT);
}
initPropertySources();
}
/**
* setup default properties configuration
* Default configuration properties look like :
* app-global.properties
* app-environment.properties
* jndi properties
*/
private void initPropertySources() throws IOException {
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addLast(new ResourcePropertySource(new ClassPathResource(MessageFormat.format("properties/{0}-global.properties", application))));
propertySources.addLast(new ResourcePropertySource(new ClassPathResource(MessageFormat.format("properties/{0}/{1}.properties", environment, application))));
propertySources.addLast(new NotFailingJndiPropertySource("jndi"));
setPropertySources(propertySources);
setIgnoreResourceNotFound(false);
setIgnoreUnresolvablePlaceholders(true);
}
}
Now we're migrating everything to MyBatis. Is there a way to inject or parse these properties into my XML configuration?
Something like:
<select id="findAllUsers" parameterType="list" resultType="user">
SELECT * FROM ${mybatis.default_schema}.USER
</select>
Yes, Definitely you can pass this property.
The function declaration in DAO layer (JAVA Mapper for mybatis in spring) would be like
List<User> findAllUsers(#Param("schemaName") String schemaName)
And when you call this function pass the schema name as argument.
Few Suggestions (Assuming you are new to MyBatis)
You should rather configure your Property using spring's util tag in context.xml
i.e. <util:properties id="mailProps" location="classpath:mail.properties" />
Scan for Mappers & Autowire using spring (again in context.xml)
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.foo.bar" />
</bean>
Where com.foo.bar is package where you Java Interface's representing your XML are located.
This way You will actually be using spring's benefits i.e. DI / IOC
parameterType would be String or java.lang.String not list.
If you need further help / any doubts feel free to ask back.
HTH
Thanks.

Resources