SpringMVC初体验---HELLOWORLD

 

SpringMVC最近大有赶超struts2的趋势。

乘着在学校有空对该框架做一定的熟悉和了解,争取毕业设计用这个框架完成

第一部建立一个web项目

maven构建语句,构建出一个空的web项目

 

mvn archetype:create -DgroupId=packageName -DartifactId=webappName -DarchetypeArtifactId=maven-archetype-webapp -Dwtpversion=1.0 

 

接着在pom中加入spring MVC的依赖

 


  4.0.0
  com.springframework.mvc
  mvc
  war
  1.0-SNAPSHOT
  mvc Maven Webapp
  http://maven.apache.org
  
		1.6
		3.1.0.RELEASE
		1.6.10
		1.6.1
	
	
		
		
			org.springframework
			spring-context
			${org.springframework-version}
			
				
				
					commons-logging
					commons-logging
				 
			
		
		
			org.springframework
			spring-webmvc
			${org.springframework-version}
		
		
		
			org.aspectj
			aspectjrt
			${org.aspectj-version}
			
		
		
		
			org.slf4j
			slf4j-api
			${org.slf4j-version}
		
		
			org.slf4j
			jcl-over-slf4j
			${org.slf4j-version}
			runtime
		
		
			org.slf4j
			slf4j-log4j12
			${org.slf4j-version}
			runtime
		
		
			log4j
			log4j
			1.2.16
			runtime
		

		
		
			javax.inject
			javax.inject
			1
		
				
		
		
			javax.servlet
			servlet-api
			2.5
			provided
		
		
			javax.servlet.jsp
			jsp-api
			2.1
			provided
		
		
			javax.servlet.jsp.jstl
			jstl-api
			1.2
				
		
			org.glassfish.web
			jstl-impl
			1.2
		

		
		
			org.codehaus.jackson
			jackson-mapper-asl
			1.8.1
		

		
		
			net.java.dev.rome
			rome
			1.0.0
		
		
		
		
			javax.validation
			validation-api
			1.0.0.GA
		
		
			org.hibernate
			hibernate-validator
			4.1.0.Final
		
		
			
		
			joda-time
			joda-time
			1.6.2
		

		
		
			commons-fileupload
			commons-fileupload
			1.2.2
			
		
			commons-io
			commons-io
			2.0.1
		
			
		
		
			junit
			junit
			4.8.2
			test
		
        
	
		
		
		
			org.springframework.maven.snapshot
			Spring Maven Snapshot Repository
			http://maven.springframework.org/snapshot
			false
			true
		
		
		
			org.springframework.maven.milestone
			Spring Maven Milestone Repository
			http://maven.springframework.org/milestone
			false
		
	
 
		
			
				org.apache.maven.plugins
				maven-compiler-plugin
				2.3.2				
				
					${java-version}
					${java-version}
				
			
			
				org.apache.maven.plugins
				maven-dependency-plugin
				
					
						install
						install
						
							sources
						
					
				
			
			
				org.codehaus.mojo
				aspectj-maven-plugin
				
				1.2
				
					
					
						org.aspectj
						aspectjrt
						${org.aspectj-version}
					
					
						org.aspectj
						aspectjtools
						${org.aspectj-version}
					
				
				
					
						
							compile
							test-compile
						
					
				
				
					true
					${java-version}
					${java-version}
				
			
			
				org.codehaus.mojo
				tomcat-maven-plugin
				1.1
				
		
	

 

这样我们的依赖已经配置齐全了,接下来就是配置前端控制器FrontController在SpringMVC中是DispatcherServlet

他位于org.springframework.web.servlet.DispatcherServlet

在web.xml中配置


	
		FrontController
		org.springframework.web.servlet.DispatcherServlet
		
                        //会反射注入
			contextConfigLocation
			/WEB-INF/spring/appServlet/servlet-context.xml
		
		1
	

	
		FrontController
		/
	

 我们看一下init-param为什么必须得叫做contextConfigLocation

首先看DispatcherServlet的构造方法

 

public DispatcherServlet() {
		super();
	}

 查看父类发现有setContextConfigLocation方法

/**
	 * Set the context config location explicitly, instead of relying on the default
	 * location built from the namespace. This location string can consist of
	 * multiple locations separated by any number of commas and spaces.
	 */
	public void setContextConfigLocation(String contextConfigLocation) {
		this.contextConfigLocation = contextConfigLocation;
	}

 查看是谁调用了这个方法

SpringMVC初体验---HELLOWORLD_第1张图片

没人调用这个方法,那么假定这个方法是被反射调用的

再往父类上查找,可以在setContextConfigLocation处加一个断点,debug的时候就能看到是如何被调用的

/**
	 * Map config parameters onto bean properties of this servlet, and
	 * invoke subclass initialization.
	 * @throws ServletException if bean properties are invalid (or required
	 * properties are missing), or if subclass initialization fails.
	 */
	@Override
	public final void init() throws ServletException {
		if (logger.isDebugEnabled()) {
			logger.debug("Initializing servlet '" + getServletName() + "'");
		}

		// Set bean properties from init parameters.
		try {
                        //获得所有的属性值
                        PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
			BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
			ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
			bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.environment));
			initBeanWrapper(bw);
			bw.setPropertyValues(pvs, true);
		}
		catch (BeansException ex) {
			logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
			throw ex;
		}

		// Let subclasses do whatever initialization they like.
		initServletBean();

		if (logger.isDebugEnabled()) {
			logger.debug("Servlet '" + getServletName() + "' configured successfully");
		}
	}

 通过AbstractPropertyAccessor往里面填充属性

public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
			throws BeansException {

		List propertyAccessExceptions = null;
		List propertyValues = (pvs instanceof MutablePropertyValues ?
				((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
		for (PropertyValue pv : propertyValues) {
			try {
				// This method may throw any BeansException, which won't be caught
				// here, if there is a critical failure such as no matching field.
				// We can attempt to deal only with less serious exceptions.
                                //往里面填充属性的核心方法
                                 setPropertyValue(pv);


			}
			catch (NotWritablePropertyException ex) {
				if (!ignoreUnknown) {
					throw ex;
				}
				// Otherwise, just ignore it and continue...
			}
			catch (NullValueInNestedPathException ex) {
				if (!ignoreInvalid) {
					throw ex;
				}
				// Otherwise, just ignore it and continue...
			}
			catch (PropertyAccessException ex) {
				if (propertyAccessExceptions == null) {
					propertyAccessExceptions = new LinkedList();
				}
				propertyAccessExceptions.add(ex);
			}
		}

		// If we encountered individual exceptions, throw the composite exception.
		if (propertyAccessExceptions != null) {
			PropertyAccessException[] paeArray =
					propertyAccessExceptions.toArray(new PropertyAccessException[propertyAccessExceptions.size()]);
			throw new PropertyBatchUpdateException(paeArray);
		}
	}

 可以看到在BeanWrapperImp当中实现了setPropertyValue(String propertyName, Object value)方法

public void setPropertyValue(String propertyName, Object value) throws BeansException {
		BeanWrapperImpl nestedBw;
		try {
			nestedBw = getBeanWrapperForPropertyPath(propertyName);
		}
		catch (NotReadablePropertyException ex) {
			throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
					"Nested property in path '" + propertyName + "' does not exist", ex);
		}
		PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedBw, propertyName));
		nestedBw.setPropertyValue(tokens, new PropertyValue(propertyName, value));


	}

 可以看到这里的确是反射调用的.

这样就完成了springMVC资源的载入

看下之前载入的资源文件做了什么



        
	
	
	
	
	

 再看一下controllers.xml




   	
   	
   	

 包扫描把所有有@controller注解的类spring会对其进行加载

@Controller  //注解表示自己是controller
public class SimpleController {
	//对应映射的路径  这里就表示 http://localhost/项目名/simple会映射到该控制器
	@RequestMapping("/simple")  
        //@ResponseBody表示这个返回的string将会当成输出值返回给浏览器
	public @ResponseBody String simple() {
		return  "hello world!";
	}

}

 所有的处理完毕~ 放入tomcat第一个springMVC的Helloworld就诞生啦~

你可能感兴趣的:(spring)