Spring控制反转心得
核心:Spring=Beans+xml
Spring通过一个beanFactory的容器来管理bean。Spring为其设计了一个子接口ApplicationContext ,这个接口提供了更多的方法,ApplicationContext 的常用类是org.spring-framework.context.support.FileSystemXmlApplicationContext.
如何将beanFactory和配置文件绑定在一起?
FileSystemXmlApplicationContext appContext = new FileSystemXmlApplicationContext(“build.xml”);
BeanFactory beanFactory = (BeanFactory)appContext;
如何在xml文件中配置bean ?
注意:配置bean至少需要id和class两个属性,其中某个类的类路径,不能是一个接口,因为需要实例化,而且是通过调用无参构造函数来进行的。
beanFactory实例化对象方式?
Spring容器提供singeton和一种non-singeton,默认是singeton,如需改成non-singeton,只需要:
<bean id=”” class=”” singeton=”false” />
如何将静态工厂注入到Spring配置文件,并且还要明确静态的工厂方法,通过factory-method。
<beans>
<bean id=”greeter” class=”test.GreetFactory” factory-method=”getGreeter”>
<!—配置参数à
<constructor-tag><value>world</value></constructor>
</bean>
</beans>
如何将实例工厂注入到Spring配置文件,并且还要明确静态的工厂方法,通过factory-method。
<beans>
<!—配置非静态工厂Beanà
<bean id=”GreetFactory” class=”test.GreetFactory”></bean>
<!—factory-bean必须是一个已经存在的Beanà
<bean id=”greeter” factory-bean=”GreetFactory” factory-method=”getGreeter”>
<!—配置参数à
<constructor-tag><value>world></value></constructor>
</bean>
</beans>
Bean的生命周期:
注意:只针对singeton来讲。
当一个bean注册完毕之后,只有当配置文件被加载的时候,单件实例才会被创建(如果使用BeanFactory管理Bean的时候只有当客户访问这个bean的时候才实例化,而如果使用的是BeanFactory的子接口ApplicationContext容器进行管理,则在加载完配置文件后就完成了所有单例Bean的实例化。如果需要在实际使用的时候在进行实例化,则需要使用懒加载,在对应的Bean的lazy-load设置true)
New FileSystemXmlApplicationContext(“src/applicationContext.xml”);
<bean id=”” class=”” lazy-init=”true”></bean>
Bean的属性值注入后行为?
<!—配置一个单件bean通过指定init-method值来指定一个初始化方法à
<bean id=”” class=”” init-method=”init”></bean>
从中可以跟踪执行的先后顺序,先创建实例,在设置属性,在调用初始化。
而Spring还提供了一种方法已达到同样的效果。即实现org.springframework.beans.factory.InitializingBean这个接口,这个接口中定义了afterPropertiesSet方法,相当于init方法
Bean销毁前行为
同样也有两种方法:在配置文件中定义destory-method或者实现org.springframework.beans.factory.DisposableBean这个接口,通过实现destory这个方法
注意:如果同时实现接口方法,并且在配置文件中进行配置。则先执行接口方法。
Bean属性注入的其他问题
前提:前面介绍了使用value方式进行属性注入,但是value方式只能接收字符串。然后Spring容器将java.lang.String类型转化成其他的类型,对于基本类型转化不会有问题.但是对于像Date类型就会出现问题。那么Spring如何为Date注入一个可以接受的值呢?在这种情况下,hello这个Bean不能单独的存在一个容器中,他需要别的bean的支持。
<bean id=”hello” class=”test.HelloWorld”>
<propertynbame=”date”>
<bean class=”java.util.Date”></bean>
</property>
</bean>
注解:里面的那个bean是存在于hello这个bean里面的,一般叫做局部bean,和普通的bean
的差别就是它只对所在的bean可见。如果希望其他文件可以访问它,则:
<bean id=”now” class=”java.util.Date”></bean>
<bean id=”hello” class=”test.HelloWorld”>
<propertynbame=”date”>
<bean ref=”now” />
</property>
</bean>
针对集合属性的注入:
Private List<String> alist;
Private Map<String,String> amap;
Private Set<String> aset;
Private Properties aproperty;
<!—配置list属性的注入à
<property name=”alist”>
<list>
<value>list元素1</value>
<value>list元素2</value>
<value>list元素3</value>
</list>
</property>
<!—配置map属性的注入à
<property name=”amap”>
<map>
<entry key=”map_key1”>
<value>map值1</value>
</entry>
<entry key=”map_key2”>
<value>map值2</value>
</entry>
<entry key=”map_key3”>
<value>map值3</value>
</entry>
<map>
</property>
<!—set属性注入à
<property name=”aset”>
<set>
<value>set值1</value>
<value>set值2</value>
<value>set值3</value>
</set>
</property>
<!—props注入à
<property name=”AProperty”>
<props>
<prop key=”pkey1”>prop值1</prop>
<prop key=”pkey2”>prop值2</prop>
<prop key=”pkey3”>prop值3</prop>
</props>
</property>
依赖检查:
Spring通过bean元素的dependcy-check属性进行依赖检查。共有4种模式,simple,object,all,none。在默认情况下不进行依赖检查。
Simple模式:他仅对于基本数据类型,字符串类型和集合类型进行依赖检查。
<bean id=”” class=”” dependcy-check=”simple”></bean> 并且不能直接给属性直接赋值,必须得在配置文件中进行赋值
Object模式:Object模式针对非基本类型的一般对象进行依赖检查
<bean id=”” class=”” dependcy-check=”objects”></bean>
All模式:同时运行了Simple模式和Object模式
None模式:不进行验证
Spring中的mvc框架
Spring中的web框架使Spring的7大模块之一
Spring中的控制器也能通过截取*.do URL进行请求响应
创建Spring框架中的控制层:
在web目录中创建Controller,这个具体类通过实现Spring web Libararies里面提供的Controller接口成为一个Spring控制器,这个接口只含有一个方法。
Public ModelAndView handleRequest(HttpServletRequest,HttpServletResponse response) throws Exception 这个方法来处理请求,非常类似于servlet中的doPost和doGet。不同的是返回一个ModelAndView对象,ModelAndView优点类似Struts中的ActionMapping,通过它可以实现页面的跳转,并将信息封装在request对象中一并传递。
还有一点需要注意:如果视图层提交过来的字段比较多的话,使用从request获取字段值比较繁琐,解决方法是Spring专门提供了表单处理控制器SimpleFormController。
注意:这里要专门讲一下ModelAndView,它只是一个存储器,用Map作为容器,将信息存储在里面供高层调用,这个使用者一般为后台的Servlet,这个Servlet负责将里面的内容取出来并封装在request对象里面,最后跳转到指定的页面。
创建Spring框架的模型层:
Spring事实上没有实现模型层,一般使用javabean等技术作为模型层。
编写配置文件
(这里配置需要和后台处理的Servlet)
<!—配置Spring的后台servletà
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!—指定Spring配置文件的路径à
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!—拦截所有以.do结尾的请求,可以修改à
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
这个web.xml文件没有和spring无关的其他配置,dispatcherServlet是一个监听器,这个监听器里面包含了spring的容器,它负责拦截所有的请求并管理spring中的bean。
Spring配置文件
<!-- 映射处理器 -->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<!-- login.do由id为login的bean处理 -->
<prop key="login.do">login</prop>
</props>
</property>
</bean>
<bean id="login" class="controller.LoginController">
<property name="errorPage">
<value>error.jsp</value>
</property>
<property name="successPage">
<value>success.jsp</value>
</property>
</bean>