`

Spring mvc+hibernate框架搭建

阅读更多

待续,待续,明天再来

 

编写文档时间:2012-5-28

1、spring下载地址:

Spring Framework 3.1.0.RELEASE is the current production release (requires Java 1.5+)

http://www.springsource.org/download/community

 

2、hibernate下载地址:

 

Hibernate ORM 4.1.2 Release

http://sourceforge.net/projects/hibernate/files/hibernate4/4.1.2.Final/hibernate-release-4.1.2.Final.zip/download

 

3、tomcat7.0下载地址

http://tomcat.apache.org/download-70.cgi(根据不同的系统来选择不同包来下载)

我的是window7  64位系统,我选择了64-bit Windows zip (pgpmd5),没有选择server,如果你用server版本也可以:),对于两者区别,自己下下玩玩就知道了。

 

4、mysql下载地址

http://www.mysql.com/downloads/mysql/

我下载版本:mysql-5.5.24-winx64.msi

 

5、新建一个动态网页项目(我是使用eclipse javaee ide)

 

6、修改web.xml文件

 

我们知道tomcat解析web.xml并加载类的时候,他加载顺序是:listener-filter-servlet-other

第一步:我们把spring的bean的注册工作放在listener,优先启动(这里包括数据源模块的启动)

 

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>spring-mvc</display-name>
  
  <!--配置欢迎界面  -->
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <!--配置listener -->
 		 <!--在这里可以配置spring的监听器,启动的时候需要把spring中的bean都注册到spring容器中  -->
 		 <listener>
 		 	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 		 </listener>
  
  <!--配置filter对编码进行转换  -->
  
  <!--配置servlet  -->
  
</web-app>
 

 

所以你首先需要到Spring Framework 3.1.0.RELEASE里面找到“org.springframework.web-3.1.0.RELEASE.jar”放到lib底下

 

第二步:添加编码转换,并拦截所有的url地址

 

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>spring-mvc</display-name>
  
  <!--配置欢迎界面  -->
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <!--配置listener -->
 		 <!--在这里可以配置spring的监听器,启动的时候需要把spring中的bean都注册到spring容器中  -->
 		 <listener>
 		 	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 		 </listener>
  
  <!--配置filter对编码进行转换  -->
  		<filter>
  			<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  			<filter-name>encodingFilter</filter-name>
  			<init-param>
  				<param-name>encoding</param-name>
  				<param-value>UTF-8</param-value>
  			</init-param>
  			<init-param>  
          	  	<param-name>forceEncoding</param-name>  
            	<param-value>true</param-value><!-- 强制进行转码 -->  
       		</init-param> 
  		</filter>
		   <filter-mapping>  
        		<filter-name>encodingFilter</filter-name>  
      	 		 <url-pattern>/*</url-pattern>  
   		 </filter-mapping>  
  <!--配置servlet  -->
  
</web-app>
 

 

第三步:添加spring中C(控制器),来对url进行拦截,并转发给不同的control处理

 

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>spring-mvc</display-name>
  
  <!--配置欢迎界面  -->
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <!--配置listener -->
 		 <!--在这里可以配置spring的监听器,启动的时候需要把spring中的bean都注册到spring容器中  -->
 		 <listener>
 		 	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 		 </listener>
  
  <!--配置filter对编码进行转换  -->
  		<filter>
  			<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  			<filter-name>encodingFilter</filter-name>
  			<init-param>
  				<param-name>encoding</param-name>
  				<param-value>UTF-8</param-value>
  			</init-param>
  			<init-param>  
          	  	<param-name>forceEncoding</param-name>  
            	<param-value>true</param-value><!-- 强制进行转码 -->  
       		</init-param> 
  		</filter>
  		
  		 <filter-mapping>  
        	<filter-name>encodingFilter</filter-name>  
      	 	 <url-pattern>/*</url-pattern>  
   		 </filter-mapping>  
      
  <!--配置servlet  -->
  		<!--我们希望spring的控制器比其他servlet优先启动,所以你需要设置load-on-startup
  		这个东西:值越小越先启动(0-5),没有或者为负数的时候,servlet被选用的时候才加载-->
  		<servlet>
  			<servlet-name>controller</servlet-name>
  			<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  			<load-on-startup>2</load-on-startup>
  		</servlet>
  		<servlet-mapping>
  			<servlet-name>controller</servlet-name>
  			<url-pattern>/</url-pattern>
  		</servlet-mapping>
</web-app>
 

这里你发现,org.springframework.web.servlet.DispatcherServlet这个类在spring包中的:org.springframework.web.servlet-3.1.0.RELEASE.jar中,所以你需要把他导入到lib下

 

===================web.xml配置文件大功告成==================

 

第四步,你试着启动下:),你发现他出错了:

 

五月 29, 2012 11:35:04 下午 org.apache.catalina.core.AprLifecycleListener init
信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: F:\Program Files\Java\jdk1.7.0\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;F:\Program Files\Java\jdk1.7.0\jre\bin;F:\Program Files (x86)\PHP\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;D:\res\java\jar\apache-ant-1.8.2-bin\apache-ant-1.8.2\bin;.
五月 29, 2012 11:35:04 下午 org.apache.tomcat.util.digester.SetPropertiesRule begin
警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:spring-mvc' did not find a matching property.
五月 29, 2012 11:35:05 下午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["http-bio-8080"]
五月 29, 2012 11:35:05 下午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["ajp-bio-8009"]
五月 29, 2012 11:35:05 下午 org.apache.catalina.startup.Catalina load
信息: Initialization processed in 855 ms
五月 29, 2012 11:35:05 下午 org.apache.catalina.core.StandardService startInternal
信息: Starting service Catalina
五月 29, 2012 11:35:05 下午 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet Engine: Apache Tomcat/7.0.27
五月 29, 2012 11:35:05 下午 org.apache.catalina.core.ContainerBase startInternal
严重: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/spring-mvc]]
	at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252)
	at java.util.concurrent.FutureTask.get(FutureTask.java:111)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1128)
	at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:782)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
	at java.lang.Thread.run(Thread.java:722)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/spring-mvc]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	... 7 more
Caused by: java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContextException
	at java.lang.Class.getDeclaredFields0(Native Method)
	at java.lang.Class.privateGetDeclaredFields(Class.java:2308)
	at java.lang.Class.getDeclaredFields(Class.java:1760)
	at org.apache.catalina.startup.WebAnnotationSet.getDeclaredFields(WebAnnotationSet.java:452)
	at org.apache.catalina.startup.WebAnnotationSet.loadFieldsAnnotation(WebAnnotationSet.java:257)
	at org.apache.catalina.startup.WebAnnotationSet.loadApplicationListenerAnnotations(WebAnnotationSet.java:88)
	at org.apache.catalina.startup.WebAnnotationSet.loadApplicationAnnotations(WebAnnotationSet.java:64)
	at org.apache.catalina.startup.ContextConfig.applicationAnnotationsConfig(ContextConfig.java:381)
	at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:858)
	at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:345)
	at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
	at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5161)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 7 more
Caused by: java.lang.ClassNotFoundException: org.springframework.context.ApplicationContextException
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1711)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)
	... 21 more

五月 29, 2012 11:35:05 下午 org.apache.catalina.core.ContainerBase startInternal
严重: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
	at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252)
	at java.util.concurrent.FutureTask.get(FutureTask.java:111)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1128)
	at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:302)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:732)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:675)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:322)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:450)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
	at java.lang.Thread.run(Thread.java:722)
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1136)
	at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:782)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 7 more

五月 29, 2012 11:35:05 下午 org.apache.catalina.startup.Catalina start
严重: Catalina.start: 
org.apache.catalina.LifecycleException: Failed to start component [StandardServer[8005]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:675)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:322)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:450)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardService[Catalina]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:732)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 7 more
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 9 more
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1136)
	at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:302)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 11 more

五月 29, 2012 11:35:05 下午 org.apache.catalina.startup.Catalina start
信息: Server startup in 653 ms
 

第五步:发现错误,解决错误

Caused by: java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContextException  这句话告诉我们,他找不到这个类,我们查看下spring jar包,发现他在:org.springframework.context-3.1.0.RELEASE.jar里面,于是,我加入到lib中,再次启动。

他继续报错:

 

五月 29, 2012 11:41:58 下午 org.apache.catalina.core.AprLifecycleListener init
信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: F:\Program Files\Java\jdk1.7.0\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;F:\Program Files\Java\jdk1.7.0\jre\bin;F:\Program Files (x86)\PHP\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;D:\res\java\jar\apache-ant-1.8.2-bin\apache-ant-1.8.2\bin;.
五月 29, 2012 11:41:58 下午 org.apache.tomcat.util.digester.SetPropertiesRule begin
警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:spring-mvc' did not find a matching property.
五月 29, 2012 11:41:58 下午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["http-bio-8080"]
五月 29, 2012 11:41:58 下午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["ajp-bio-8009"]
五月 29, 2012 11:41:58 下午 org.apache.catalina.startup.Catalina load
信息: Initialization processed in 917 ms
五月 29, 2012 11:41:58 下午 org.apache.catalina.core.StandardService startInternal
信息: Starting service Catalina
五月 29, 2012 11:41:58 下午 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet Engine: Apache Tomcat/7.0.27
五月 29, 2012 11:41:59 下午 org.apache.catalina.core.ContainerBase startInternal
严重: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/spring-mvc]]
	at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252)
	at java.util.concurrent.FutureTask.get(FutureTask.java:111)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1128)
	at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:782)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
	at java.lang.Thread.run(Thread.java:722)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/spring-mvc]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	... 7 more
Caused by: java.lang.NoClassDefFoundError: org/springframework/core/env/EnvironmentCapable
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2889)
	at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1170)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1678)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2889)
	at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1170)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1678)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)
	at java.lang.Class.getDeclaredFields0(Native Method)
	at java.lang.Class.privateGetDeclaredFields(Class.java:2308)
	at java.lang.Class.getDeclaredFields(Class.java:1760)
	at org.apache.catalina.startup.WebAnnotationSet.getDeclaredFields(WebAnnotationSet.java:452)
	at org.apache.catalina.startup.WebAnnotationSet.loadFieldsAnnotation(WebAnnotationSet.java:257)
	at org.apache.catalina.startup.WebAnnotationSet.loadApplicationListenerAnnotations(WebAnnotationSet.java:88)
	at org.apache.catalina.startup.WebAnnotationSet.loadApplicationAnnotations(WebAnnotationSet.java:64)
	at org.apache.catalina.startup.ContextConfig.applicationAnnotationsConfig(ContextConfig.java:381)
	at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:858)
	at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:345)
	at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
	at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5161)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 7 more
Caused by: java.lang.ClassNotFoundException: org.springframework.core.env.EnvironmentCapable
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1711)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)
	... 35 more

五月 29, 2012 11:41:59 下午 org.apache.catalina.core.ContainerBase startInternal
严重: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
	at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252)
	at java.util.concurrent.FutureTask.get(FutureTask.java:111)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1128)
	at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:302)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:732)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:675)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:322)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:450)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
	at java.lang.Thread.run(Thread.java:722)
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1136)
	at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:782)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 7 more

五月 29, 2012 11:41:59 下午 org.apache.catalina.startup.Catalina start
严重: Catalina.start: 
org.apache.catalina.LifecycleException: Failed to start component [StandardServer[8005]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:675)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:322)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:450)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardService[Catalina]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:732)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 7 more
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 9 more
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1136)
	at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:302)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 11 more

五月 29, 2012 11:41:59 下午 org.apache.catalina.startup.Catalina start
信息: Server startup in 404 ms

 

 

发现错误:Caused by: java.lang.NoClassDefFoundError: org/springframework/core/env/EnvironmentCapable

我们继续到spring jar中去查找,继续报错,说少了org.springframework.core-3.1.0.RELEASE这个jar中,于是我把他导入到lib中。继续重启tomcat。

继续报错:

 

五月 29, 2012 11:44:59 下午 org.apache.catalina.core.AprLifecycleListener init
信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: F:\Program Files\Java\jdk1.7.0\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;F:\Program Files\Java\jdk1.7.0\jre\bin;F:\Program Files (x86)\PHP\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;D:\res\java\jar\apache-ant-1.8.2-bin\apache-ant-1.8.2\bin;.
五月 29, 2012 11:44:59 下午 org.apache.tomcat.util.digester.SetPropertiesRule begin
警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:spring-mvc' did not find a matching property.
五月 29, 2012 11:44:59 下午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["http-bio-8080"]
五月 29, 2012 11:44:59 下午 org.apache.coyote.AbstractProtocol init
信息: Initializing ProtocolHandler ["ajp-bio-8009"]
五月 29, 2012 11:44:59 下午 org.apache.catalina.startup.Catalina load
信息: Initialization processed in 996 ms
五月 29, 2012 11:44:59 下午 org.apache.catalina.core.StandardService startInternal
信息: Starting service Catalina
五月 29, 2012 11:44:59 下午 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet Engine: Apache Tomcat/7.0.27
五月 29, 2012 11:45:00 下午 org.apache.catalina.core.ContainerBase startInternal
严重: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/spring-mvc]]
	at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252)
	at java.util.concurrent.FutureTask.get(FutureTask.java:111)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1128)
	at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:782)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
	at java.lang.Thread.run(Thread.java:722)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/spring-mvc]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	... 7 more
Caused by: java.lang.NoClassDefFoundError: org/springframework/beans/factory/ListableBeanFactory
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2889)
	at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1170)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1678)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
	at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2889)
	at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1170)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1678)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)
	at java.lang.Class.getDeclaredFields0(Native Method)
	at java.lang.Class.privateGetDeclaredFields(Class.java:2308)
	at java.lang.Class.getDeclaredFields(Class.java:1760)
	at org.apache.catalina.startup.WebAnnotationSet.getDeclaredFields(WebAnnotationSet.java:452)
	at org.apache.catalina.startup.WebAnnotationSet.loadFieldsAnnotation(WebAnnotationSet.java:257)
	at org.apache.catalina.startup.WebAnnotationSet.loadApplicationListenerAnnotations(WebAnnotationSet.java:88)
	at org.apache.catalina.startup.WebAnnotationSet.loadApplicationAnnotations(WebAnnotationSet.java:64)
	at org.apache.catalina.startup.ContextConfig.applicationAnnotationsConfig(ContextConfig.java:381)
	at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:858)
	at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:345)
	at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
	at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5161)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 7 more
Caused by: java.lang.ClassNotFoundException: org.springframework.beans.factory.ListableBeanFactory
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1711)
	at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)
	... 35 more

五月 29, 2012 11:45:00 下午 org.apache.catalina.core.ContainerBase startInternal
严重: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
	at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252)
	at java.util.concurrent.FutureTask.get(FutureTask.java:111)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1128)
	at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:302)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:732)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:675)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:322)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:450)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
	at java.lang.Thread.run(Thread.java:722)
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1136)
	at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:782)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 7 more

五月 29, 2012 11:45:00 下午 org.apache.catalina.startup.Catalina start
严重: Catalina.start: 
org.apache.catalina.LifecycleException: Failed to start component [StandardServer[8005]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	at org.apache.catalina.startup.Catalina.start(Catalina.java:675)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:322)
	at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:450)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardService[Catalina]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:732)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 7 more
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina]]
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
	at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 9 more
Caused by: org.apache.catalina.LifecycleException: A child container failed during start
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1136)
	at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:302)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	... 11 more

五月 29, 2012 11:45:00 下午 org.apache.catalina.startup.Catalina start
信息: Server startup in 413 ms
 

 

同上方法:他说这个找不到 org/springframework/beans/factory/ListableBeanFactory ,我把org.springframework.beans-3.1.0.RELEASE.jar包导入

 

接着他继续报错:Caused by: java.lang.NoClassDefFoundError: org/apache/commons/logging/Log;

于是乎,我继续导入jar包,(其实这个包是spring core那个jar包依赖与他的,你再env/AbstractEnvironment.java这个类中就有),于是我又去上网找了这个jar包

 

地址:http://commons.apache.org/logging/download_logging.cgi

我下载的版本是:commons-logging-1.1.1-bin.zip,解压开,我们需要里面的commons-logging-1.1.1.jar

把他放入lib中,重新启动,发现错误:

java.lang.NoClassDefFoundError: org/springframework/asm/ClassVisitor

Caused by: java.lang.ClassNotFoundException: org.springframework.asm.ClassVisitor

java.lang.NoClassDefFoundError: org/apache/log4j/LogManager

Caused by: java.lang.ClassNotFoundException: org.apache.log4j.LogManager

 

我把org.springframework.asm-3.1.0.RELEASE.jar 导入,

http://logging.apache.org/log4j/1.2/download.html下载:log4j-1.2.17.zip

 

重新启动tomcat:继续报错

Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml] 说找不到这个文件。

 

第六步:他报错这么久了,我们试图跟踪下代码

1、首先从listener下手,服务器会加载监听器也就是web.xml里面的listener类:org.springframework.web.context.ContextLoaderListener

既然他是listener,服务器监听的时候,会调用contextInitialized方法:

 

	/**
	 * Initialize the root web application context.
	 */
	public void contextInitialized(ServletContextEvent event) {
		this.contextLoader = createContextLoader();
		if (this.contextLoader == null) {
			this.contextLoader = this;
		}
		this.contextLoader.initWebApplicationContext(event.getServletContext());
	}

 

  我们可以看出他会使用initWebApplicationContext方法,对根上下文进行载入和初始化

2、继续跟踪到ContextLoader类中的initWebApplicationContext()方法

 

public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
		if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
			throw new IllegalStateException(
					"Cannot initialize context because there is already a root application context present - " +
					"check whether you have multiple ContextLoader* definitions in your web.xml!");
		}

		Log logger = LogFactory.getLog(ContextLoader.class);
		servletContext.log("Initializing Spring root WebApplicationContext");
		if (logger.isInfoEnabled()) {
			logger.info("Root WebApplicationContext: initialization started");
		}
		long startTime = System.currentTimeMillis();

		try {
			// Store context in local instance variable, to guarantee that
			// it is available on ServletContext shutdown.
			if (this.context == null) {
				this.context = createWebApplicationContext(servletContext);
			}
			if (this.context instanceof ConfigurableWebApplicationContext) {
				configureAndRefreshWebApplicationContext((ConfigurableWebApplicationContext)this.context, servletContext);
			}
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);

			ClassLoader ccl = Thread.currentThread().getContextClassLoader();
			if (ccl == ContextLoader.class.getClassLoader()) {
				currentContext = this.context;
			}
			else if (ccl != null) {
				currentContextPerThread.put(ccl, this.context);
			}

			if (logger.isDebugEnabled()) {
				logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +
						WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
			}
			if (logger.isInfoEnabled()) {
				long elapsedTime = System.currentTimeMillis() - startTime;
				logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
			}

			return this.context;
		}
		catch (RuntimeException ex) {
			logger.error("Context initialization failed", ex);
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
			throw ex;
		}
		catch (Error err) {
			logger.error("Context initialization failed", err);
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
			throw err;
		}
	}

 

 你设置断点,他会执行

servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);

将WebApplicationContext作为一个属性设置到servletContext,我们知道servletContext是web的上下文,可理解为web的一个存储数据的地方,可以从他的实例获取静态的html啊,图片啊等资源。

当然,你就可以通过servletContext来获取spring的applicationContext了。

还有,上面代码:

if中的configureAndRefreshWebApplicationContext((ConfigurableWebApplicationContext)this.context, servletContext);这行代码

 

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
		if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
			// The application context id is still set to its original default value
			// -> assign a more useful id based on available information
			String idParam = sc.getInitParameter(CONTEXT_ID_PARAM);
			if (idParam != null) {
				wac.setId(idParam);
			}
			else {
				// Generate default id...
				if (sc.getMajorVersion() == 2 && sc.getMinorVersion() < 5) {
					// Servlet <= 2.4: resort to name specified in web.xml, if any.
					wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
							ObjectUtils.getDisplayString(sc.getServletContextName()));
				}
				else {
					wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
							ObjectUtils.getDisplayString(sc.getContextPath()));
				}
			}
		}

		// Determine parent for root web application context, if any.
		ApplicationContext parent = loadParentContext(sc);

		wac.setParent(parent);
		wac.setServletContext(sc);
		String initParameter = sc.getInitParameter(CONFIG_LOCATION_PARAM);
		if (initParameter != null) {
			wac.setConfigLocation(initParameter);
		}
		customizeContext(sc, wac);
		wac.refresh();
	}

 你看到没有ApplicationContext parent = loadParentContext(sc);他得到了一个ApplicationContext,这个就是我们spring的上下文,我们很多工作都是从它开始,从它获取。

 

最重要的一个丹麦:wac.refresh();完成了对applicationContext的初始化,注册啊,封装bean的工作。

我们来解析refresh()

3、AbstractApplicationContext中refresh()

 

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}
		}
	}

       这个方法这个网址说的很好:http://www.ibm.com/developerworks/cn/java/j-lo-spring-principle/ 你可以搜索:“如何创建 BeanFactory 工厂”。直接定位到想看的地方。

代码1:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

 

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}

 这里有一个refreshBeanFactory();

代码2:refreshBeanFactory();

 

protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

 这个方法实现了 AbstractApplicationContext 的抽象方法 refreshBeanFactory,这段代码清楚的说明了 BeanFactory 的创建过程,loadBeanDefinitions(beanFactory) 将找到答案,这个方法将开始加载、解析 Bean 的定义,也就是把用户定义的数据结构转化为 Ioc 容器中的特定数据结构。(抄自上面那个网址)

 

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// then proceed with actually loading the bean definitions.
		initBeanDefinitionReader(beanDefinitionReader);
		loadBeanDefinitions(beanDefinitionReader);
	}

 跟踪这句话: loadBeanDefinitions(beanDefinitionReader);

 

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			for (String configLocation : configLocations) {
				reader.loadBeanDefinitions(configLocation);
			}
		}
	}

这句话: reader.loadBeanDefinitions(configLocation);

这里的configLocation就是要读取xml文件。

在这个类里面有这个一个方法:

 

	/**
	 * The default location for the root context is "/WEB-INF/applicationContext.xml",
	 * and "/WEB-INF/test-servlet.xml" for a context with the namespace "test-servlet"
	 * (like for a DispatcherServlet instance with the servlet-name "test").
	 */
	@Override
	protected String[] getDefaultConfigLocations() {
		if (getNamespace() != null) {
			return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
		}
		else {
			return new String[] {DEFAULT_CONFIG_LOCATION};
		}
	}

}
 

看看上面的说明,默认的是读取上面两个配置文件,看看applicatinContext.xml 出现了。具体细节可以继续跟踪下去

直到XmlBeanDefinitionReader底下:这个方法报错

 

/**
	 * Load bean definitions from the specified XML file.
	 * @param encodedResource the resource descriptor for the XML file,
	 * allowing to specify an encoding to use for parsing the file
	 * @return the number of bean definitions found
	 * @throws BeanDefinitionStoreException in case of loading or parsing errors
	 */
	public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		Assert.notNull(encodedResource, "EncodedResource must not be null");
		if (logger.isInfoEnabled()) {
			logger.info("Loading XML bean definitions from " + encodedResource.getResource());
		}

		Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
		if (currentResources == null) {
			currentResources = new HashSet<EncodedResource>(4);
			this.resourcesCurrentlyBeingLoaded.set(currentResources);
		}
		if (!currentResources.add(encodedResource)) {
			throw new BeanDefinitionStoreException(
					"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
		}
		try {
			InputStream inputStream = encodedResource.getResource().getInputStream();
			try {
				InputSource inputSource = new InputSource(inputStream);
				if (encodedResource.getEncoding() != null) {
					inputSource.setEncoding(encodedResource.getEncoding());
				}
				return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
			}
			finally {
				inputStream.close();
			}
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(
					"IOException parsing XML document from " + encodedResource.getResource(), ex);
		}
		finally {
			currentResources.remove(encodedResource);
			if (currentResources.isEmpty()) {
				this.resourcesCurrentlyBeingLoaded.remove();
			}
		}
	}

 说明他找不到这个xml文件。。。

XmlBeanDefinitionReader这个类继承AbstractBeanDefinitionReader,而AbstractBeanDefinitionReader又实现了接口BeanDefinitionReader,这个接口的作用要求不同的实现类来读取不同的配置文件,像这里XmlBeanDefinitionReader就是要读取xml文件了,如果要读取Properties文件,就需要实现能够读取properties根式的类:org\springframework\beans\factory\support包底下:PropertiesBeanDefinitionRead.java。

 

那么这些类的作用是什么?

1、读取不同格式的文件,并把文件内容映射到BeanDefinition中,然后把映射后的BeanDefinition注册到一个BeanDefinitionRegistry,之后BeanDefinitionRegistry完成了Bean的注册和加载。大部分工作在于解析文件、映射装配BeanDefinition之类的工作(这个由BeanDefinitionReader来做),BeanDefinitionRegistry只负责保管。

2、spring每一个被管理的bean对象,在容器中都有一个BeanDefinition的实例与之对应,该实例负责保存对象的所

有必要信息,包括对应的对象的class类型、是否抽象、构造方法参数以及其他属性。当客户端向BeanFactory请求对象的时候,BeanFactory会通过这些信息为客户端返回一个完备可用的对象实例。

3、BeanFactory跟我们打交道,你向它要什么它就给你什么,对于你要的东西在哪里,对于我们是透明的,这个放置哪里怎么放的问题BeanDefinitionRegistry帮她解决了。

 

对于读取xml文件工作大概是这样的:(这段话和代码参考自:《spring揭秘》)

 

 

package spring;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;

public class Test {
	
	
	public static void main(String[] args) {
		//对我们客户端来说,我们只要与BeanFactory打交道
		//这是beanFsctory的实现类,他间接的实现了BeanFactory,还实现了BeanDefinitionRegistry,所以他完成把bean注册到容器的工作,还提供beanfacotry实例
		DefaultListableBeanFactory beanRegistry = new DefaultListableBeanFactory();
		BeanFactory container = (BeanFactory)bindViaXMLFile(beanRegistry);
		container.getBean("你想要的类的名称");//在xml文件配置的bean名称
	}
	
	public static BeanFactory bindViaXMLFile(BeanDefinitionRegistry registry) {
		
		XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(registry);
		reader.loadBeanDefinitions("你的applicationContext.xml文件");
		//XmlBeanDefinitionReader读取了xml文件,并能解析,封装bean对象的class类型,构造方法等信息到一个BeanDefinition中
		return (BeanFactory) registry;
		
	}
}
 

 

 

 

第七步:配置applicationContext.xml文件

1、他就是上面的web.xml中listener——ContextLoaderListener这个类需要的。

2、上面说到把配置文件中的bean里面的信息注册到容器中,形如:

<bean id="User" class="org.test.User"/>//这样就可以了,

但是如果我需要很多个的话,配置文件会臃肿,下面我们使用annocation+classpath-scanning功能解决这个问题。

3、这时候请你打开spring的doc文档:spring-framework-3.1.0.RELEASE-with-docs\docs\spring-framework-reference\html\beans.html,这里面讲的很清楚。

4、我们来拷贝里面的xml配置文件吧,下面我们使用annocation+classpath-scanning,注意了classpath-scanning他会默认的使用一中命名规则来匹配,比如你的类名为UserGroup,他bean的定义名称为userGroup,相当于<bean id="userGroup" class=""UserGroup/>。对于依赖注入使用的注解有两个1、@Autowired和@Resource,两者的区别在于,一个是默认使用Type来匹配,一个是根据name来匹配。

 

	@Autowired
	private BeanFactory b;//他去注册的bean中找类型为BeanFactory的进行注入
	@Resource
	private BeanFactory c;//他去bean中查找id="beanFactory"的那个 	

 

 

@Autowired使用时候,如果在xml配置文件中如果有两个bean如下
<bean id="a" class="BeanFacotryA"/>

<bean id="c" class="BeanFacotryB"/> 

BeanFacotryA和BeanFacotryB都实现了BeanFactory,那注入BeanFactory的时候,

他叫容器帮你注入a?还是c实例了?所以他需要一个@Qualifier配合,

 

	@Autowired
	@Qualifier("a")
	private BeanFactory b;

 

我们的applicationContext.xml就是下面的

 

<?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-3.0.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:component-scan base-package="spring"></context:component-scan>
</beans>

  对于下面这个:

<context:component-scan base-package="spring">他会去spring这个源码包底下去搜索有@compone的类,把他当做bean,注入到容器中。这个就厉害了,我们不需要在xml中一个一个去配置bean了。

 

第八步:重新启动服务器,你发现他继续报错,找不到applicationContext.xml。

注意了,我的applicationContext.xm放在classpath底下,所以他找不到,于是我在web.xml添加下面几行来告诉spring的那个listener去这个地方找applicationContext.xml

 

.......
 </welcome-file-list>
	  <context-param>
	  <param-name>contextConfigLocation</param-name>
	   <param-value>classpath:applicationContext.xml</param-value>
	  </context-param>
  <!--配置listener -->
..............
..............

第九步:你重新启动他报错,“java.lang.NoClassDefFoundError: org/springframework/expression/PropertyAccessor”,我们引入org.springframework.expression-3.1.0.RELEASE.jar包

 

第十步:重新启动,又报错:Could not open ServletContext resource [/WEB-INF/controller-servlet.xml],这个文件配置了controller的转发的映射关系。我们到spring的doc目录底下去找找。spring-framework-3.1.0.RELEASE-with-docs/docs/spring-framework-reference/html/mvc.html#mvc-servlet这个网页里面看看。

controll-servlet.xml如下:

 

<?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:p="http://www.springframework.org/schema/p" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="spring"/>


</beans>
 

最后web.xml文件如下:

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>spring-mvc</display-name>
  
  <!--配置欢迎界面  -->
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
	  <context-param>
	  <param-name>contextConfigLocation</param-name>
	   <param-value>classpath:applicationContext.xml</param-value>
	  </context-param>
  <!--配置listener -->
 		 <!--在这里可以配置spring的监听器,启动的时候需要把spring中的bean都注册到spring容器中 
 		 ,当然他需要读取一个配置文件applicationContext.xml -->
 		 <listener>
 		 	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 		 </listener>
 		 
 		 <!--配置log包  -->
 		 <listener>
 		 	<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
 		 </listener>
  
  <!--配置filter对编码进行转换  -->
  		<filter>
  			<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  			<filter-name>encodingFilter</filter-name>
  			<init-param>
  				<param-name>encoding</param-name>
  				<param-value>UTF-8</param-value>
  			</init-param>
  			<init-param>  
          	  	<param-name>forceEncoding</param-name>  
            	<param-value>true</param-value><!-- 强制进行转码 -->  
       		</init-param> 
  		</filter>
  		
  		 <filter-mapping>  
        	<filter-name>encodingFilter</filter-name>  
      	 	 <url-pattern>/*</url-pattern>  
   		 </filter-mapping>  
      
  <!--配置servlet  -->
  		<!--我们希望spring的控制器比其他servlet优先启动,所以你需要设置load-on-startup
  		这个东西:值越小越先启动(0-5),没有或者为负数的时候,servlet被选用的时候才加载-->
  		<servlet>
  			<servlet-name>controller</servlet-name>
  			<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  			<load-on-startup>2</load-on-startup>
  			<init-param>
  				<param-name>contextConfigLocation</param-name>
  				<param-value>classpath:controller-servlet.xml</param-value>
  			</init-param>
  		</servlet> 
  		
  		
  		<servlet-mapping>
  			<servlet-name>controller</servlet-name>
  			<url-pattern>/</url-pattern>
  		</servlet-mapping>
</web-app>

 启动服务器,终于不报错了。。


-=-=-=-=-=-=-=-=-=-=-=-=--=-=-spring mvc基本配置完成-=-=-=-=-=-=-=-=-=-=

 

配置日志,开发人员查看debug日志

1、我们发现我们启动tomcat的并没有打印出出spring包里面写的日志内容,日志内容对开发人员跟踪错误是有帮助的,所以我们先加入日志。

2、日志的三种选择:

1、从jdk1.4开始他有自带的logging这个日志类,用来记录日志。由于他的扩展性差、易用性差所以出现了Log4j控件

2、见上面的截图,有log4j这个jar包吧。

3、commons-logging,他是apache commons底下的一个类库,这个比较通用,他可以判断如果有Log4j,他就把日志输出功能交给Log4j去处理,如果没有Log4j功能,他就交给了jdk的日志功能去处理。

 

3、配置文件log4j.properties(默认名称)

 

log4j.rootLogger=INFO, stdout
log4j.categroy.org.hibernate.SQL=DEBUG 
log4j.category.org.springframework=INFO
log4j.appender.stdout=org.apache.log4j.ConsoleAppender 
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n

第一行,把Info的信息输出给stdout中

第二、三行,以log4j.category开头,后面跟着包名,就是配置包底下的日志输出,看上面有配置spring包底下的日志输出

第四行,输出到哪里?输出到控制台

第五行和第六航,输出的格式和布局

 

这个只是输出到控制台,对于tomcat底下跟踪日志,我们设置更高级别,并使用日志文件来输出,提供以后查看(以后再说。) 

 

这时候你可以看到一系列的日志输出。

 

2012-06-02 15:02:58,866 [org.springframework.web.context.ContextLoader]-[INFO] Root WebApplicationContext: initialization started
2012-06-02 15:02:58,962 [org.springframework.web.context.support.XmlWebApplicationContext]-[INFO] Refreshing Root WebApplicationContext: startup date [Sat Jun 02 15:02:58 CST 2012]; root of context hierarchy
2012-06-02 15:02:59,024 [org.springframework.beans.factory.xml.XmlBeanDefinitionReader]-[INFO] Loading XML bean definitions from class path resource [applicationContext.xml]
2012-06-02 15:02:59,310 [org.springframework.beans.factory.config.PropertyPlaceholderConfigurer]-[INFO] Loading properties file from class path resource [hibernate.properties]
2012-06-02 15:02:59,326 [org.springframework.beans.factory.support.DefaultListableBeanFactory]-[INFO] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@534a5d1b: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0,dataSource,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy
2012-06-02 15:02:59,340 [com.mchange.v2.log.MLog]-[INFO] MLog clients using log4j logging.
 

 

 

 

spring集成hibernate

1、spring对ORM解决方案主要有三个:统一了管理方式,无论你是使用JDBC还是ORM,我们都只要使用spring提供给我们的接口即可,对底层JDBC或者ORM是透明的;spring提供了统一的事务管理了,我们只要使用它的事务管理机制就可以了,不用在代码中写什么事务启动,事务回滚的代码;异常统一处理方式(不同的数据库报的异常不相同,如果把异常交给用户处理,他们会累死,所以spring对不同的异常他都进行了封装处理)

 

2、一般我们写hibernate,有几个步骤:

1、获得session 

2、通过session获取事务开始,Transaction tx = session.beginTransaction();

3、写我们的业务逻辑代码(增删改查操作)

4、事务提交 tx.commit();

5、关闭session

6、如果有异常,需要进行回滚catch(异常) {回滚} finally{...}

 

在软件开发过程我们很强调把不变得东西给抽象出来,作为一个单独的处理代码。那么,哪里不变?是不是除了业务逻辑代码之外,其他代码都是一样的。所以我们考虑把其他的单独抽出来(这里可以使用设计模式中的模板方法)

有一个模板是这样的

 

模板方法(一个回调对象, session) {

1、获得session 

2、利用回调对象,处理业务逻辑

3、处理异常

}

 

对于我们用户来说,只要写一个回调对象,处理业务逻辑即可。。异常代码、回滚代码都不用我们来写。

 

—————以上就是HibernateTemplate核心模板方法,这个类做了这一个封装抽象的工作。

我们发现上面模板方法已经对异常进行的处理,这个就是前面说的spring统一了异常处理。

 

这个模板提供了4组查询方法:

1、get模板办法——根据id到数据库查询对象,如果没有则方法null

2、load模板办法——根据id到数据库加载对象,如果没有则抛出异常,而不是null

3、find模板方法

4、iterate模板方法

对于get和load区别说一下:来自csdn

 

最大的区别:
  1>load先到缓存中去查,如果没有则返回一个代理对象(不马上到DB中去找),等 后面
  使用这个代理对象操作的时候,才到DB中。如还没有找到return Exception
  2>get先到缓存中去查,(注意这里不是返回一个代理对象)如果没有就到DB中去查,还没有的话return null 
  总之,如果你确定DB中有这个对象就用load(),不确定就用get()(这样效率高)

 

3、hiberateTemplate如果获取session的?

Hiberante中获取session是根据SessionFactory来的,一切都是从sessionFactory开始,这个类他相当于一个数据源,所以我们的hiberanteTemplate一定需要必须需要用到他。

SessionFactory从哪里来?Spring提供了一个LocalSessionFacotryBean,你只要把数据源注入给他,调用他的getObject方法,就有sessionFactory对象了。

所以很经常见到配置文件:

 

<bean id="sessionFacotry" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="dataSource" ref="dataSource"/>

//上面这里就是数据源了

</bean>

 

当然你如果想要用注解的也有,AnnotationSessionFactoryBean,你可以service层使用注解注入。

 

4、下面我们来配置

在我们下载的

Hibernate ORM 4.1.2 Release这个jar中hibernate-release-4.1.2.Final\lib\optional\c3p0找到c3p0-0.9.1.jar,加入到lib底下。

applicationcontext.xml需要配置数据源以及占位符文件

 

<?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-3.0.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:component-scan base-package="spring"></context:component-scan>

<!--告诉spring去哪里获取占位符的配置文件  -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<property name="locations">
		<list>
			<value>classpath:hibernate.properties</value>
		</list>
	</property>
</bean>


<!--配置数据源  -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
	<property name="driverClass"><value>${db.driver}</value></property>      
    <property name="jdbcUrl"><value>${db.url}</value></property>     
    <property name="user"><value>${db.user}</value></property>    
    <property name="password"><value>${db.password}</value></property>    
</bean>

<!--数据源提供给spring的sessionFactory,这里我们要求是使用注解方式,所以spring要选择AnnotationSessionFactoryBean来获取sessionFactory
当然你如果要用xml的,使用LoaclSessionFactoryBean来配置,当然这里的AnnotationSessionFactoryBean是继承LoaclSessionFactoryBean  -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
	<property name="dataSource" ref="dataSource"/>
	<!--让spring帮你扫描这个包底下的所有类,主要作用扫描跟数据库对应的实体类  -->
	<property name="packagesToScan" value="spring.model"/>
	<!--设置hibernate的属性  -->
	<property name="hibernateProperties">
      <value>
        hibernate.dialect=org.hibernate.dialect.MySQLDialect
        hibernate.show_sql=true
      </value>
    </property>

</bean>

</beans>

 

 占位符hibernate.properties文件,放在classpath目录下

 

db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://127.0.0.1:3306?useUnicode=true&amp;characterEncoding=utf-8
db.user=root
db.password=root

 

上面报错了,需要引入:org.springframework.orm-3.1.0.RELEASE.jar(作为hibernate关联)、org.springframework.transaction-3.1.0.RELEASE.jar(事务、dao支持)、hibernate-core-4.1.2.Final.jar(hibernate的必须的)、hibernate-jpa-2.0-api-1.0.1.Final.jar(hibernate必须的)、jboss-transaction-api_1.1_spec-1.0.0.Final.jar(hibernate必须的)

 

这时候你启动下,发现报错:

java.lang.NoClassDefFoundError: Lorg/hibernate/cache/CacheProvider;

百度,google下:

有:写道

hibernate4整合spring3.1的过程中,发现了java.lang.NoClassDefFoundError: Lorg/hibernate/cache/CacheProvider异常,查了一下相关资料,原来发现hibernate4已经将hibernate3的一些功能改掉了,在hibernate4已经不使用CacheProvider了,所以做了以下修改,
原先:<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
改成:<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
问题解决,发现可以正常使用了

所以我们更改下,applicationContext.xml的配置

 

<?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-3.0.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:component-scan base-package="spring"></context:component-scan>

<!--告诉spring去哪里获取占位符的配置文件  -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<property name="locations">
		<list>
			<value>classpath:hibernate.properties</value>
		</list>
	</property>
</bean>


<!--配置数据源  -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
	<property name="driverClass"><value>${db.driver}</value></property>      
    <property name="jdbcUrl"><value>${db.url}</value></property>     
    <property name="user"><value>${db.user}</value></property>    
    <property name="password"><value>${db.password}</value></property>    
</bean>

<!--数据源提供给spring的sessionFactory,这里我们要求是使用注解方式,
所以spring要选择AnnotationSessionFactoryBean来获取sessionFactory
当然你如果要用xml的,使用LoaclSessionFactoryBean来配置,
当然这里的AnnotationSessionFactoryBean是继承LoaclSessionFactoryBean
但是发现,hibernate4版本更改了,会报错误“java.lang.NoClassDefFoundError: Lorg/hibernate/cache/CacheProvider;”  -->
<!-- <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
	<property name="dataSource" ref="dataSource"/>
	让spring帮你扫描这个包底下的所有类,主要作用扫描跟数据库对应的实体类 
	<property name="packagesToScan" value="spring.model"/>
	设置hibernate的属性 
	<property name="hibernateProperties">
      <value>
        hibernate.dialect=org.hibernate.dialect.MySQLDialect
        hibernate.show_sql=true
      </value>
    </property>
</bean> -->

<!--看看源码中的这段话,其实它更接近于annotation,你跟进代码,发现他是支持注解的
<p><b>NOTE:</b> This variant of LocalSessionFactoryBean requires Hibernate 4.0
 * or higher. It is similar in role to the same-named class in the <code>orm.hibernate3</code>
 * package. However, in practice, it is closer to <code>AnnotationSessionFactoryBean</code>
 * since its core purpose is to bootstrap a <code>SessionFactory</code> from annotation scanning.  -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
	<property name="dataSource" ref="dataSource"/>
	<!-- 让spring帮你扫描这个包底下的所有类,主要作用扫描跟数据库对应的实体类  -->
	<property name="packagesToScan" value="spring.model"/>
	<!-- 设置hibernate的属性  -->
	<property name="hibernateProperties">
      <value>
        hibernate.dialect=org.hibernate.dialect.MySQLDialect
        hibernate.show_sql=true
      </value>
    </property>
</bean>

</beans>
 

 

  我们发现,他还是报错,少了包,继续添加:

 

 当然,上面jdbc.driver的jar包还没有加入。dom4j-1.6.1.jar(hibernate必须的)、hibernate-commons-annotations-4.0.1.Final(hibernate必须的)、jboss-logging-3.1.0.GA(hibernate必须的)antlr-2.7.7(hibernate必须的)

 

对了,我们的mysql jdbc的驱动还没加入了

http://dev.mysql.com/downloads/connector/j/5.1.html地址,下一个吧。(mysql-connector-java-5.1.20.zip),解压开mysql-connector-java-5.1.20-bin.jar,放入到lib底下。

 

重启一下,哈哈,发现没有问题,大功告成。

 

等等,我们还有哪些没配了?事务,事务,对了,还有事务没有配置。事务的配置,当你在进行配置事务的时候,发现自动提示标签,哦,,1、你忘记加入spring的重要的东西,AOP的jar包,还有/org.springframework.aspects-3.1.0.RELEASE。2、applicationContext.xml刚开始那段需要修改,需要引入标签头。这个在spring的文档中有。

applicationContext.xml里程碑

 

<?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"
     xmlns:tx="http://www.springframework.org/schema/tx"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="
     http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
     http://www.springframework.org/schema/aop 
     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-3.0.xsd">


<context:component-scan base-package="spring"></context:component-scan>

<!--告诉spring去哪里获取占位符的配置文件  -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<property name="locations">
		<list>
			<value>classpath:hibernate.properties</value>
		</list>
	</property>
</bean>


<!--配置数据源  -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
	<property name="driverClass"><value>${db.driver}</value></property>      
    <property name="jdbcUrl"><value>${db.url}</value></property>     
    <property name="user"><value>${db.user}</value></property>    
    <property name="password"><value>${db.password}</value></property>    
</bean>

<!--数据源提供给spring的sessionFactory,这里我们要求是使用注解方式,
所以spring要选择AnnotationSessionFactoryBean来获取sessionFactory
当然你如果要用xml的,使用LoaclSessionFactoryBean来配置,
当然这里的AnnotationSessionFactoryBean是继承LoaclSessionFactoryBean
但是发现,hibernate4版本更改了,会报错误“java.lang.NoClassDefFoundError: Lorg/hibernate/cache/CacheProvider;”  -->
<!-- <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
	<property name="dataSource" ref="dataSource"/>
	让spring帮你扫描这个包底下的所有类,主要作用扫描跟数据库对应的实体类 
	<property name="packagesToScan" value="spring.model"/>
	设置hibernate的属性 
	<property name="hibernateProperties">
      <value>
        hibernate.dialect=org.hibernate.dialect.MySQLDialect
        hibernate.show_sql=true
      </value>
    </property>
</bean> -->

<!--看看源码中的这段话,其实它更接近于annotation,你跟进代码,发现他是支持注解的
<p><b>NOTE:</b> This variant of LocalSessionFactoryBean requires Hibernate 4.0
 * or higher. It is similar in role to the same-named class in the <code>orm.hibernate3</code>
 * package. However, in practice, it is closer to <code>AnnotationSessionFactoryBean</code>
 * since its core purpose is to bootstrap a <code>SessionFactory</code> from annotation scanning.  -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource"/>
		<!-- 让spring帮你扫描这个包底下的所有类,主要作用扫描跟数据库对应的实体类  -->
		<property name="packagesToScan" value="spring.model"/>
		<!-- 设置hibernate的属性  -->
		<property name="hibernateProperties">
	      <value>
	        hibernate.dialect=org.hibernate.dialect.MySQLDialect
	        hibernate.show_sql=true
	      </value>
	    </property>
	</bean>

<!--事务配置  -->
    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">  
        <property name="sessionFactory" ref="sessionFactory"></property>  
    </bean>  
  
    <aop:config>
        <aop:advisor pointcut="execution(* spring.service.*Service.*(..))" advice-ref="txAdvice"/>  
    </aop:config>  
  
    <tx:advice id="txAdvice" transaction-manager="txManager">  
        <tx:attributes>  
            <tx:method name="get*" read-only="true"/>  
            <tx:method name="query*" read-only="true"/>  
            <tx:method name="find*" read-only="true"/>  
            <tx:method name="load*" read-only="true"/>  
            <tx:method name="*" rollback-for="Exception"/>  
        </tx:attributes>  
    </tx:advice>  

</beans>

 把org.springframework.aop-3.1.0.RELEASE.jar、org.springframework.aspects-3.1.0.RELEASE.jar加入lib底下

启动发现你少了一包aopalliance.jar(spring的依赖包从3.0后就使用maven了,不包含在jar包中)

下载地址:http://sourceforge.net/projects/aopalliance/files/aopalliance/1.0/aopalliance.zip/download

 

还有,下载aspectj weaver.jar http://www.eclipse.org/downloads/download.php?file=/tools/aspectj/aspectj-1.6.12.jar

org.springframework.jdbc-3.1.0.RELEASE.jar把这里的三个都放入jar底下。

 

 

在启动下,发现没有问题,又一次的大功告成。。

此时的jar文件:

 

==================结束配置======================

 

可能我们需要使用jsp的标签库:jstl.jar和standard.jar

这里有下载的:http://archive.apache.org/dist/jakarta/

 

到此为止,上面的配置算是最简单的包了。


如果你需要用hibernate的验证框架:

http://sourceforge.net/projects/hibernate/files/hibernate-validator/4.3.0.Final/hibernate-validator-4.3.0.Final-dist.zip/download

 

 

WEB框架还需要做哪些了?

 

1、日志管理

 

之前已经给出了log相关操作,对于关键的业务跟踪需要在后台保存做日志记录,以便后续跟踪

        部署的时候:需要去掉没有必要的日志打印,比如hibernate的日志输出,struts2的日志输出,都改成false

 

2、前台、后台数据校验

见我另一篇博文数据校验:jquery前端验证和hibernate服务端验证

 

3、业务逻辑测试

       见我另一篇博文“spring测试

 

4、异常统一处理

      404、500错误要转到哪里,逻辑错误要转到哪个页面显示

      比如我写的spring mvc:

 

 

public class BusinessException extends Exception {
	private Throwable cause;

	public BusinessException(String msg) {
		super(msg);
	}

	public BusinessException(String msg, Throwable ex) {
		super(msg);
		this.cause = ex;
	}

	public Throwable getCause() {
		return (this.cause == null ? this : this.cause);
	}

	public String getMessage() {
		String message = super.getMessage();
		Throwable cause = getCause();
		if (cause != null) {
			message = message + ";BusinessException Exception is " + cause;
		}
		return message;
	}

	public void printStackTrace(PrintStream ps) {
		if (getCause() == null) {
			super.printStackTrace(ps);

		} else {
			ps.println(this);
			getCause().printStackTrace(ps);
		}
	}

	public void printStackTrace(PrintWriter pw) {
		if (getCause() == null) {
			super.printStackTrace(pw);
		} else {
			pw.println(this);
			getCause().printStackTrace(pw);
		}
	}

	public void printStackTrace() {
		printStackTrace(System.err);
	}
}


public class ExceptionHandler implements HandlerExceptionResolver {

	public ModelAndView resolveException(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex) {
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("ex", ex);
		
		// 根据不同错误转向不同页面
		if(ex instanceof BusinessException) {
			return new ModelAndView("error-business", model);
		}/*else if(ex instanceof ParameterException) {
			return new ModelAndView("error-parameter", model);
		} */
		else {
			return new ModelAndView("error", model);
		}
	}
}

5、拦截器

 

public class FromDupInterceptor implements HandlerInterceptor {

	private Logger log = Logger.getLogger(FromDupInterceptor.class);
	
	public void afterCompletion(HttpServletRequest arg0,
			HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		 log.info("==============执行顺序: afterCompletion================");  
		
	}

	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
			Object arg2, ModelAndView arg3) throws Exception {
		log.info("==============执行顺序: postHandle================");  
		
	}

	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
			Object arg2) throws Exception {
		log.info("==============执行顺序: preHandle================");  
		return true;  
	}

}

 

 

<!--配置拦截器  -->
    <mvc:interceptors>  
        <!-- 多个拦截器,顺序执行 -->  
        <mvc:interceptor>  
        <!--这里的path符号有/*, /**, *, ? 等,对于student.do?param=1从?开始不作为path  -->
           <mvc:mapping path="/student/save*" /><!-- 如果不配置或/*,将拦截所有的Controller -->  
           <bean class="spring.common.interceptor.FromDupInterceptor"></bean>  
        </mvc:interceptor>  
    </mvc:interceptors> 


在springmvc的控制器配置文件中,你就可以这么配置拦截器,具体你在拦截器里面做什么,自己去做
 

6、避免重复提交

1、js方面:第一次提交表单的时候禁用提交按钮;利用onsubmit事件处理程序取消后续的表单提交操作

 

2、使用token


Hibernate——让我们来一起读读官方文档吧。

对于这块,标出我平时不大注意的问题!!

 

chapter1

1、 写道
This is the case with the date property. Hibernate cannot know if the property, which is of java.util.Date, should map to a SQL date, timestamp, or time column. Full date and time information is preserved by mapping the property with a timestamp converter.

对于java.uitl.Date,Hibernate不知道要要转那个,所有的时间信息都给你进行了timestamp转换。

<hibernate-mapping package="org.hibernate.tutorial.domain">

    <class name="Event" table="EVENTS">
        <id name="id" column="EVENT_ID">
            <generator class="native"/>
        </id>
        <property name="date" type="timestamp" column="EVENT_DATE"/>
        <property name="title"/>
    </class>

</hibernate-mapping>

 

2、写道

SessionFactory是线性安全的,对于session表示一个单位业务的单线程

 A org.hibernate.SessionFactory is used to obtain org.hibernate.Session instances. A org.hibernate.Session represents a single-threaded unit of work. The org.hibernate.SessionFactory is a thread-safe global object that is instantiated once.

session通过getCurrentSession被创建出来,并由hibernate帮忙绑定到当前线程上,一旦事务结束、提交、回滚,session就自动取消绑定,并关闭它,如果你重新调用getCurrentSession,他获取新的一个session。

org.hibernate.Session begins when the first call to getCurrentSession() is made for the current thread. It is then bound by Hibernate to the current thread. When the transaction ends, either through commit or rollback, Hibernate automatically unbinds the org.hibernate.Session from the thread and closes it for you. If you call getCurrentSession() again, you get a new org.hibernate.Session and can start a new unit of work.

 

3、比较下下面两段代码的区别,并说明结果:(实验验证通过)

 

 写道
private void addPersonToEvent(Long personId, Long eventId) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();

Person aPerson = (Person) session.load(Person.class, personId);
Event anEvent = (Event) session.load(Event.class, eventId);
aPerson.getEvents().add(anEvent);

session.getTransaction().commit();
}

上面这段由于session未关闭,且load出来的对象处于持久状态,你调用了.aPerson.getEvents().add方法,此持久态的对象发生变化,对于这种hibernate会自动更新数据库。


private void addPersonToEvent(Long personId, Long eventId) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();

Person aPerson = (Person) session
.createQuery("select p from Person p left join fetch p.events where p.id = :pid")
.setParameter("pid", personId)
.uniqueResult(); // Eager fetch the collection so we can use it detached
Event anEvent = (Event) session.load(Event.class, eventId);

session.getTransaction().commit();

// End of first unit of work

aPerson.getEvents().add(anEvent); // aPerson (and its collection) is detached

// Begin second unit of work

Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
session2.beginTransaction();
session2.update(aPerson); // Reattachment of aPerson

session2.getTransaction().commit();
}

由于在调用add方法之前session已经关闭,此时的对象是游离态,他如何改变都不会自动更新同步到数据库,只有手动使用update的方式,他才帮忙更新数据库

 

 

4、session最好是一个request过来,他打开一个

session-per-reques

 

 

 写道
Do not use a new Hibernate Session for every database operation. Use one Hibernate Session that is scoped to the whole request. Use getCurrentSession(), so that it is automatically bound to the current Java thread.
 

 

chapter 2

 

1、什么是sessionFactory?他是一切数据的开始,

 

 写道
1、它是线性安全的
2、它是一个永久的存储区,与单个数据库对应
3、维持二级缓存
4、生成session实例
5、是一个hibernate连接的客户端?//不知道怎么翻译了 A factory for, and pool of, JDBC connections 是连接池的一个工厂
A thread-safe, immutable cache of compiled mappings for a single database. A factory for org.hibernate.Session instances. A client of org.hibernate.connection.ConnectionProvider. Optionally maintains a second level cache of data that is reusable between transactions at a process or cluster level.
 

 

2、什么是Session?

 

 写道
1、单线程
2、生命周期短,是应用层和存储层的一个会话对象
3、封装了jdbc
4、是事务的工厂
5、维持着一级缓存(持久态对象和集合)
A single-threaded, short-lived object representing a conversation between the application and the persistent store. Wraps a JDBC java.sql.Connection. Factory for org.hibernate.Transaction. Maintains a first level cache of persistent the application's persistent objects and collections; this cache is used when navigating the object graph or looking up objects by identifier

 

chapter 3 这里讲解配置的

 

1、SessionFactory哪里来?他是通过Configuration来获取的,这个对象他可以读取xml的配置文件,来得到sessionFactory

 

 写道
he org.hibernate.cfg.Configuration is used to build an immutable org.hibernate.SessionFactory. The mappings are compiled from various XML mapping files.

You can obtain a org.hibernate.cfg.Configuration instance by instantiating it directly and specifying XML mapping documents. If the mapping files are in the classpath, use addResource(). For example:

Configuration cfg = new Configuration()
.addResource("Item.hbm.xml")
.addResource("Bid.hbm.xml");

Hibernate will then search for mapping files named /org/hibernate/auction/Item.hbm.xml and/org/hibernate/auction/Bid.hbm.xml in the classpath.

如何获取sessionFactory了?

SessionFactory sessions = cfg.buildSessionFactory();

 

 

第四章 持久类

 

1、所有的持久类都必须有默认的构造方法,有了它,hibernate才能使用反射机制来创建对象。意思是说需要注意的

 

public ClassA()//构造方法不能带有参数,有参数他会报错。。。

例如:

org.hibernate.InstantiationException: No default constructor for entity: spring.model.Student

 

 写道
All persistent classes must have a default constructor (which can be non-public) so that Hibernate can instantiate them using java.lang.reflect.Constructor.newInstance().

 

2、尽量要把实例类添加equals方法和hashCode方法,因为hibernate会帮你在一个session scope根据数据库中的id来判断两个实力是否相等,这个对于set中的对象操作是很重要的。当存在多个session scope的操作时候,或者实例处于游离态的时候,hibernate不会帮你判断。。这时候你必须使用equals方法来判断了

 

总之一句话,对于model需要天假equals方法和hashCode方法。比较使用类的属性来判断

 

public class Cat {

    ...
    public boolean equals(Object other) {
        if (this == other) return true;
        if ( !(other instanceof Cat) ) return false;

        final Cat cat = (Cat) other;

        if ( !cat.getLitterId().equals( getLitterId() ) ) return false;
        if ( !cat.getMother().equals( getMother() ) ) return false;

        return true;
    }

    public int hashCode() {
        int result;
        result = getMother().hashCode();
        result = 29 * result + getLitterId();
        return result;
    }

}
 

 

 

 写道
You have to override the equals() and hashCode() methods if you:

intend to put instances of persistent classes in a Set (the recommended way to represent many-valued associations); and
intend to use reattachment of detached instances
 

 

Spring MVC那些事——基于注解

1、从tomcat的web.xml配置文件说起——控制器

 

<servlet>  
            <servlet-name>controller</servlet-name>  
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
            <load-on-startup>2</load-on-startup>  
        </servlet>  

 

 

我们在上面的配置文件中有上面这行org.springframework.web.servlet.DispatcherServlet。

a、它是什么?作用是什么?为什么tomcat要加载它?

解:因为我们要使用spring mvc框架,我们需要spring的(控制器C、视图V、逻辑层M),在MVC模型中,控制器是首当其冲的一个角色,一切从他开始。当然这里我们也不例外,我们可以把DispatcherServlet这个类看做一个控制器,他负责控制整个MVC的操作过程。

一个web链接过来交给tomcat,tomcat通过web.xml中的配置文件,如下:

 

        <servlet>  
            <servlet-name>controller</servlet-name>  
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
            <load-on-startup>2</load-on-startup>  
        </servlet>  
        <servlet-mapping>  
            <servlet-name>controller</servlet-name>  
            <url-pattern>/</url-pattern>  
        </servlet-mapping>  

 

      b、对于所有的链接都由这个控制器来处理,这个控制器接到链接之后他如何处理了?

解:一个http://www.****这样一个链接过来,他作为一个控制器,他就必须知道要找那个逻辑业务代码帮他处理。他就必须知道哪种地址能对应到哪个类(逻辑业务代码)来处理,必须要有一个“地址<--->类”对应的一张表来匹配,这个对应表的对应关系类似于map中进行的<key,value>,key代表连接、value代表这个链接被处理的那个类。这件事情是由HandleMapping这个类来管理对应关系,DispatcherServlet只是调用他就可以了。

我们知道DipatcherServlet调用HandleMapping来知道是哪一个类对这个链接进行处理,但是他并不知道精确到那个一方法,HandleMapping只精确到类,所以必须还要有一个类来帮忙对应到方法。这个类就是HandlerAdaptor

关于适配器:(看他的名字就知道是适配器,这里为什么需要用适配器了,我写出我个人看法,也不知道对不对:我们知道中国的电压是220V,美国的电压110V,你把支持110V的电脑从美国带回到国内,你一插上去,估计就立马冒火花了,因为他的电源超过他最大的范围。要处理这个问题,我们就想到了一个变压器(这个就是适配器,不改变电脑,不改变两地的电压,只是多增加一个变压器即可使用),这个变压器接受了220V,然后返回110V),这个就像HandlerAdaptor类一样,他可以接受不同的电压,返回一个可以给你使用的电压110V。

在逻辑业务类的方法,他可以返回四种类型:modelAndView、model、String、void。我们知道MVC,要把视图传给控制器DispatcherServlet(即调用完逻辑业务类后,要返回),我了个去了,你有4种返回值,我还不知道你什么时候会返回哪一个了。所以了,他就要求了,我只接受modelAndView这种返回值(110V电压),其他类型返回值(220V,110V,380V等),你自己看着办,于是就需要一个适配器,能够接受各种电压,并返回统一的110V(modelAndView类型)。

在HandlerAdaptor,他既然是适配器,他应该有一个接受各种电压的入口吧(也就是DipatcherServlet调用完HandleMapping返回给出的一个Handle逻辑类),在内部肯定有一个处理方法,返回一个统一的ModelAndView吧。

 

ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object Handle) throws Exception {
   //1、看这里有Object Handle就是dispatcher调用HandleMapping之后的业务逻辑类给他。2、 ModleAndView也是在这里实例化的,所以我们在写业务逻辑层的时候,我们可以直接使用他。3、他返回一个统一的ModelAndView
}

   c、把HandlerAdaptor替handle把ModelAndView传给了Dispatcher。Dispatcher利用这个ModleAndView返回到相应的页面(比如jsp页面)

问题1:我在Handle方法中返回的是void,即使你HandlerAdaptor帮我封装成ModleAndView,你怎么知道我返回到哪一个页面咯?我又不是返回string,直接在Handle方法里面返回一个页面的名称。

spring框架说,我来告诉你吧:你如果返回ModleMap或者void,我将会根据请求路径,按照默认规则提取相应的逻辑视图名来返回。

@RequestMapping("/a.action") 

public ModelMap fafa() {
  return ...ModelMap的实例
}

//他会返回名字叫做a的视图

  d、我只返回了一个名称,你怎么知道是哪个文件夹下面,哪个后缀名的文件了?这件事情跟HandleMapping一样,要定位到具体精确的页面。HandleAdaptor返回了ModelAndView给Dispatcher之后,Dispatcher会调用一个ViewResolver来处理这个对应,你如果使用jsp作为视图的,他常用这个类:

<bean id="jspViewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/" />
		<property name="suffix" value=".jsp" />
	</bean>

//这个也是spring默认的一个视图定位器

 他的主要最用就是找视图了。

e、Dispatchet调用ViewResolver得到一个view实例的引用,然后把渲染的工作交给View实例。View就是把jsp模板和解析jstl数据表达式结合之后发给tomcat,tomcat把他发送给我们客户就可以了。。这里的jstl数据形如:${a.name},这样的,这个有view来处理。。

 

 

 

from:http://zhidao.baidu.com/question/3298976.html  各种版本说明

 

 

 α版

  此版本表示该软件仅仅是一个初步完成品,通常只在软件开发者内部交流,也有很少一部分发布给专业测试人员。一般而言,该版本软件的bug较多,普通用户最好不要安装。

  β(beta)版

  该版本相对于α版已有了很大的改进,消除了严重的错误,但还是存在着一些缺陷,需要经过大规模的发布测试来进一步消除。这一版本通常由软件公司免费发布,用户可从相关的站点下载。通过一些专业爱好者的测试,将结果反馈给开发者,开发者们再进行有针对性的修改。该版本也不适合一般用户安装。

  γ版

  该版本已经相当成熟了,与即将发行的正式版相差无几,如果用户实在等不及了,尽可以装上一试。

  trial(试用版)

  试用版软件在最近的几年里颇为流行,主要是得益于互联网的迅速发展。该版本软件通常都有时间限制,过期之后用户如果希望继续使用,一般得交纳一定的费用进行注册或购买。有些试用版软件还在功能上做了一定的限制。

  unregistered(未注册版)

  未注册版与试用版极其类似,只是未注册版通常没有时间限制,在功能上相对于正式版做了一定的限制,例如绝大多数网络电话软件的注册版和未注册版,两者之间在通话质量上有很大差距。还有些虽然在使用上与正式版毫无二致,但是动不动就会弹出一个恼人的消息框来提醒你注册,如看图软件acdsee、智能陈桥汉字输入软件等。

  demo版

  也称为演示版,在非正式版软件中,该版本的知名度最大。demo版仅仅集成了正式版中的几个功能,颇有点像unregistered。不同的是,demo版一般不能通过升级或注册的方法变为正式版。

  以上是软件正式版本推出之前的几个版本,α、β、γ可以称为测试版,大凡成熟软件总会有多个测试版,如windows 98的β版,前前后后将近有10个。这么多的测试版一方面为了最终产品尽可能地满足用户的需要,另一方面也尽量减少了软件中的bug。而trial、unregistered、demo有时统称为演示版,这一类版本的广告色彩较浓,颇有点先尝后买的味道,对于普通用户而言自然是可以免费尝鲜了。

  ·正式版

  不同类型的软件的正式版本通常也有区别。

  release

  该版本意味“最终释放版”,在出了一系列的测试版之后,终归会有一个正式版本,对于用户而言,购买该版本的软件绝对不会错。该版本有时也称为标准版。一般情况下,release不会以单词形式出现在软件封面上,取而代之的是符号(r),如windows nt(r) 4.0、ms-dos(r) 6.22等。

  registered

  很显然,该版本是与unregistered相对的注册版。注册版、release和下面所讲的standard版一样,都是软件的正式版本,只是注册版软件的前身有很大一部分是从网上下载的。

  standard

  这是最常见的标准版,不论是什么软件,标准版一定存在。标准版中包含了该软件的基本组件及一些常用功能,可以满足一般用户的需求。其价格相对高一级版本而言还是“平易近人”的。

  deluxe

  顾名思义即为“豪华版”。豪华版通常是相对于标准版而言的,主要区别是多了几项功能,价格当然会高出一大块,不推荐一般用户购买。此版本通常是为那些追求“完美”的专业用户所准备的。

  reference

  该版本型号常见于百科全书中,比较有名的是微软的encarta系列。reference是最高级别,其包含的主题、图像、影片剪辑等相对于standard和deluxe版均有大幅增加,容量由一张光盘猛增至三张光盘,并且加入了很强的交互功能,当然价格也不菲。可以这么说,这一版本的百科全书才能算是真正的百科全书,也是发烧友们收藏的首选。

  professional(专业版)

  专业版是针对某些特定的开发工具软件而言的。专业版中有许多内容是标准版中所没有的,这些内容对于一个专业的软件开发人员来说是极为重要的。如微软的visual foxpro标准版并不具备编译成可执行文件的功能,这对于一个完整的开发项目而言显然是无法忍受的,若客户机上没有foxpro将不能使用。如果用专业版就没有这个问题了。

  enterprise(企业版)

  企业版是开发类软件中的极品(相当于百科全书中的reference版)。拥有一套这种版本的软件可以毫无障碍地开发任何级别的应用软件。如著名的visual c++的企业版相对于专业版来说增加了几个附加的特性,如sql调试、扩展的存储过程向导、支持as/400对ole db的访问等。而这一版本的价格也是普通用户无法接受的。如微软的visual studios 6.0 enterprise中文版的价格为23000元。

  ·其他版本

  除了以上介绍的一些版本外,还有一些专有版本名称。

  update(升级版)

  升级版的软件是不能独立使用的,该版本的软件在安装过程中会搜索原有的正式版,如果不存在,则拒绝执行下一步。如microsoft office 2000升级版、windows 9x升级版等等。

  oem版

  oem版通常是捆绑在硬件中而不单独销售的版本。将自己的产品交给别的公司去卖,保留自己的著作权,双方互惠互利,一举两得。

  单机(网络)版

  网络版在功能、结构上远比单机版复杂,如果留心一下软件的报价,你就会发现某些软件单机版和网络版的价格相差非常大,有些网络版甚至多一个客户端口就要加不少钱。

  普及版

  该版本有时也会被称为共享版,其特点是价格便宜(有些甚至完全免费)、功能单一、针对性强(当然也有占领市场、打击盗版等因素)。与试用版不同的是,该版本的软件一般不会有时间上的限制。当然,如果用户想升级,最好还是去购买正式版。

  以上是一些常见软件版本的简要介绍,随着软件市场行为的变化,现在也出现了一些新的版本命名方式,比如windows xp中的xp是取自于experience中的第二、第三个字母。
  • 大小: 33.7 KB
  • 大小: 83.1 KB
分享到:
评论
7 楼 hjrichcs 2014-09-19  
controller-servlet.xml 这里面的配置没写  该怎么配置
6 楼 du_bo 2013-04-17  
gsdhaiji_cai 写道
du_bo 写道
发布下源码就更好了

这个不需要源码,只是框架包的配置。。基本配置文件都在上面了

好了我的也搭建好了
5 楼 gsdhaiji_cai 2013-04-16  
du_bo 写道
发布下源码就更好了

这个不需要源码,只是框架包的配置。。基本配置文件都在上面了
4 楼 du_bo 2013-04-16  
发布下源码就更好了
3 楼 hemin108 2013-03-22  
2 楼 xunke515 2013-02-15  
楼主,精神可嘉啊.估计重新启动服务器也要不少时间吧.
1 楼 qhdlgd110 2012-11-24  
多谢楼主分享,楼主可以公布一下源代码吗?非常感谢

相关推荐

Global site tag (gtag.js) - Google Analytics