Spring学习心得(一)

    本人用Java做了不少的WEB工程,但都是用Java基本的servlet+DAO实现的,对几种web框架的认识算是小白级别。一直很想学习Spring框架的使用,但是网上的资料都是介绍Spring框架的优点,教程也繁杂臃肿,纯属备考模式,本人写这一系列博客就是为了和大家分享动手实战Spring框架时的一些经验和教训。

第一步,用eclipse建立一个普通的WEB工程,并在tomcat上测试运行。(本步骤时Java web基础,不再赘述,直接跳过)。

第二步,把Spring依赖的一些jar包导入,本文附件中有Spring所需要的大部分jar包,直接将所需要的jar复制到“WebRoot/WEB-INF/lib/”中即可,spring所依赖基本的jar有asm、beans、context、core、expression、web和commons-logging;如果做持久层还需要jdbc、transaction、dbcp、pool等jar。这些jar附件中都有,可以根据需要选择合适的版本使用。

第三步,配置Spring,就是在XML文件中对Spring做一些基本的配置,让web系统能识别Spring。

1.在web.xml文件中加入Spring配置文件信息

<display-name>MySpring</display-name>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring*.xml</param-value>
	</context-param>
        <listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

   其中<context-param>是工程全局配置,<param-name>要求是唯一的,对于Spring配置中<param-name>要求是contextConfigLocation,<param-value>则对应了spring配置XML文件的路径。<listener>中配置的class是继承了ServletContextListener类的监听器类,spring的ja包中的org.springframework.web.context.ContextLoaderListener即可。在tomcat启动web工程时会读取这些参数来初始化servlet上下文。

 2.在 在WEB-INF/ 下建一个 spring-conf.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">


	<bean id="TestBo" class="servlet.TestBo">
		<property name="name" value="123"></property>
	</bean>

	<bean id="TestAction" class="servlet.TestAction">
		<property name="name" value="abc"></property>
		<property name="testbo" ref="TestBo"></property>
	</bean>

</beans>

    现在我们已经完成了spring的基本配置,接下来写代码测试。

    第四步,TestServlet.java

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/**
 * Servlet implementation class TestServlet
 */
@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	TestAction ta;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public TestServlet() {
        super();
        // TODO Auto-generated constructor stub
    }
    
    /**
     * service
     * @throws IOException 
     */
    public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
    	PrintWriter pw=response.getWriter();
    	pw.write(ta.getTestbo().getName());
    	pw.flush();
    	pw.close();
    }

    public void init(ServletConfig servletConfig)
    	      throws ServletException{
    	     servletConfig.getServletContext();
    	     ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletConfig.getServletContext());
    	     this.ta = (TestAction) ctx.getBean("TestAction");
    	     this.ta.sayHello();
    	   System.out.println("TestServlet init");
//    	     TestAction ta = new TestAction();
//    	     ta.sayHello();
    	    }
}

   TestBo.java

package servlet;


import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;

public class TestBo {

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

   TestAction.java

package servlet;

public class TestAction {

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	private TestBo testbo;
	public void sayHello() {
		// TODO Auto-generated method stub
		System.out.println(name);
	}

	public TestBo getTestbo() {
		return testbo;
	}

	public void setTestbo(TestBo testbo) {
		this.testbo = testbo;
	}
	

	
}

后记:

1.本人一开始在启动tomcat时一直遇到以下错误:

严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'TestAction' defined in ServletContext resource [/WEB-INF/spring-conf.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'testbo' of bean class [servlet.TestAction]: Bean property 'testbo' is not writable or has an invalid setter method. Did you mean 'testbo1'?
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1279)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
	at java.security.AccessController.doPrivileged(Native Method)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
	at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4729)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5167)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'testbo' of bean class [servlet.TestAction]: Bean property 'testbo' is not writable or has an invalid setter method. Did you mean 'testbo1'?
	at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:801)
	at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:651)
	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:78)
	at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:59)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1276)
	... 25 more

   tomcat已经说得很清楚了,在TestAction类中的TestBo变量找不到注入方法,原因是我自己写的set方法命名有误,为了防止错误我们最好使用eclipse自动生成set、get方法。

2. spring的注入流程为:

ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletConfig.getServletContext());

 得到servlet的上下文环境,主要是得到spring配置文件路径。

this.ta = (TestAction) ctx.getBean("TestAction");

 根据TestAction的bean实例化TestAction对象,其中TestAction的bean中

<property name="testbo" ref="TestBo"></property>

 name必须和变量名一直,ref指向另一个Bean的id.

相关推荐