The differences between Applicationcontext.xml and Dispatch-servlet.xml and the problems and lessons they cause

Source: Internet
Author: User
Tags throw exception

You know, in spring MVC, you can configure spring in both Applicationcontext.xml and dispatch-servlet.xml, so what's the difference between them:

Let's take a look at the Spring official documentation:

 Spring lets you define multiple contexts in a parent-child hierarchy.
	The applicationcontext.xml defines the beans for the "root webapp context" and i.e. the context associated with the WebApp. The spring-servlet.xml (or whatever else call it) defines the beans for one servlet's app context. There can many of these in a webapp, one per Spring servlet (e.g. Spring1-servlet.xml for servlet spring1, Spring2-serv
	Let.xml for servlet spring2).
	Beans in Spring-servlet.xml can reference Beans in Applicationcontext.xml, but not vice versa.
	All Spring MVC controllers must go in the spring-servlet.xml context. In more simple cases, the applicationcontext.xml context is unnecessary. It's generally used to contain beans, that's shared between all servlets in a webapp. If you are only having one servlet, then there's not really much point, unless has a specific use for it. 

As can be seen, applicationcontext.xml and dispatch-servlet.xml form the context of two parent-child relationships, tested and found:

1) If a bean is defined in two files (for example, two files define the same package as component scan), Spring generates an instance in both application context and servlet context. They are in different contexts and they behave differently (see the problem described below).

2) If there is an instance of the same @Service in both the application context and the servlet context, the controller (in servlet context) will prefer SERVL when it passes the @Resource reference An instance in the ET context.

issues that occur when configuring MyBatis transactions in Spring:

I added the following configuration to the Applicationcontext.xml file as described online:

1. Applicationcontext.xml

<!--This is the original configuration of the sqlsession and DAO, and the configuration remains the same when the transaction is increased--
<bean id= "Sqlsessionfactory" class= "Org.mybatis.spring.SqlSessionFactoryBean" >
		<property name= " DataSource "ref=" DataSource "></property>
		<property name=" configlocation "value=" classpath: Mybatis.xml "></property>
		<property name=" mapperlocations "value=" classpath:com/sjl/dao/*- Mapper.xml "></property>
	</bean>
	
	<bean id=" Idao "class=" Com.sjl.dao.IdaoImpl ">
		<property name= "Sqlsessionfactory" ref= "sqlsessionfactory" ></property>
	</bean>       

    <!--increased MyBatis transaction Control--
    <bean id= "TransactionManager" class= " Org.springframework.jdbc.datasource.DataSourceTransactionManager "> 
          <property name=" DataSource "ref=" DataSource "></property>    
    </bean> 
	<tx:annotation-driven transaction-manager=" TransactionManager "/>
2. Then use the @Transactional annotation in the DAO to declare the transaction

Package com.sjl.base;
Import java.io.Serializable;
Import Java.util.HashMap;

Import java.util.List;

Import Javax.annotation.Resource;

Import org.springframework.transaction.annotation.Transactional;
Import Com.sjl.common.EntityClassUtil;
Import Com.sjl.common.Pager;

Import Com.sjl.dao.Idao; public class abstractbasedao<t, PK extends serializable> implements Basedao <t, pk> {@Resource private Idao
	
	<t, pk> Idao;
	Private Class Entityclass = Entityclassutil.getentityclass (GetClass ()); <strong><span style= "color: #ff0000;"
		> @Transactional </span></strong> public void Save (T entity) {Idao.save (entity);
		
	throw new RuntimeException ();//throw exception, transaction rollback} public void Delete (PK pk) {idao.delete (entityclass, PK); } public pager<t> findbypage (int pageoffset, int pageSize) {hashmap<string, integer> map = new HashMap (
		);
		Map.put ("Pageoffset", Pageoffset);
		Map.put ("PageSize", pageSize); pager<t> Pager = idao.fIndbypage (entityclass, map);
		
		
	return pager; }

	
}
The Idao definition is as follows: <pre name= "code" class= "Java" >package Com.sjl.dao;
Import java.io.Serializable;
Import java.util.List;

Import Java.util.Map;
Import Org.mybatis.spring.support.SqlSessionDaoSupport;

Import Org.springframework.stereotype.Repository;

Import Com.sjl.common.Pager; @Repository ("Idao") public class idaoimpl<t, PK extends serializable> extends Sqlsessiondaosupport implements Idao <t, pk> {public void Save (T entity) {this.getsqlsession (). Insert (Entity.getclass (). GetName () + ". Add", Entit
	y);  } public void Delete (class<t> entityclass, PK PK) {this.getsqlsession (). Insert (Entityclass.getname () + ". Delete",
		
	PK);
		
		} public pager<t> Findbypage (class<t> entityclass, Map param) {pager<t> Pager = new Pager ();
		list<t> pagecontent = This.getsqlsession (). SelectList (Entityclass.getname () + ". Findpagecontent", param);
		
		Pager.setpagecontent (PageContent); int count = This.getsqlsession (). SelectOne (Entityclass.getname () + ". Findtotal");
		
		Pager.settotalcount (count);
		
	return pager;
 }
}

After the above configuration, according to the truth should be no problem, but the program after the operation found that the transaction has not started, even Transaction-manager have not entered, looked for a long time did not find out where the problem. Later saw the same configuration on the Internet to run successfully, compared to find that he was in the ordinary Java application mode of running successfully, I put my own program in the common Java application Mode, found that transaction function, This feeling should be a problem in the spring MVC environment, and should be transaction configuration does not work, accidentally remembered in their own configuration, Dispatch-servlet.xml and Applicationcontext.xml The configured Component-scan are scanned for the same package, so that, although Transaction-manager is defined in application context, But this transaction-manager configuration is a function of the bean defined in the application context. According to the previous application context and Dispatcher-servlet context relationship, Dispatcher-servlet context and application The same type of service bean instance exists in the context, the Controller will invoke the service Bean in dispatcher-servlet context first, and Dispatcher-servlet Because transaction manager is not configured in the context, the generated service bean instance does not have a transactional implant (AOP) and of course cannot start the transaction.

Workaround:

1. Modify the Component-scan configuration in Applicationcontext.xml as follows:

<context:component-scan base-package= "COM.SJL" >
<span style= "White-space:pre" >	</span> <context:exclude-filter type= "Annotation" expression= "Org.springframework.stereotype.Controller"/>// Classes that do not scan tagged @controller
</context:component-scan>
2. Modify the Component-scan configuration in Dispatcher-servlet.xml:

<context:component-scan base-package= "Com.sjl.controller" ></context:component-scan>.//Scan Controller only Package


With the above configuration, the Service Bean instance will only be generated in the application context, and it will be possible to use Transaction-manager-managed declarative transactions.


Lesson:

Beans defined in application context and Dispatcher-servlet are best not to repeat, dispatcher-servlet it is best to just define a type of controller bean.



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.