这里记录关于Spring的一些零散的知识点,以免自己日后忘记。
===============================
1. ModelAndView的addObject()方法.
Spring MVC里一般使用ModelAndView的addObject()方法将信息添加到Model里,可以在jsp页面通过request.getAttribute()方法获取(就是放到了request域里面去了),这里相当于是转发,注意转发时是把ModelAndView里的信息放到了request的attribute里面。
但是如果在ModelAndView后,使用了重定向,那么ModelAndView的信息得通过request.getParameter()方法获得(就是放到了url请求参数里),此时由于视图解析器会将Map的value放入到url作为参数,所以无论什么类型的value,都会变成String,因此,此时放入Model中的value,只能是基本数据类型和String类型,不能是自定义类型的对象数据。下面的代码运行后,重定向后浏览器地址栏为“http://localhost:8080/SecondWeb/index.jsp?param=RedictView%3F%3F%3F%3F%3F%3F%3F%3FaddObject%3F%3F%3F%3FRequest%3FParameter%3F”
package com.viewResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
public class MyController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// TODO Auto-generated method stub
ModelAndView mv = new ModelAndView("redict");
mv.addObject("param", "RedictView重定向时,使用的addObject都放到了Request的Parameter里");
return mv;
}
}
<?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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<bean id="/myController.view" class="com.viewResolver.MyController"/>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean id="redict" class="org.springframework.web.servlet.view.RedirectView">
<property name="url" value="http://localhost:8080/SecondWeb/index.jsp"></property>
</bean>
</beans>
2. @RequestMapping里使用通配符“*”需要注意的事项:
package practice.handlers;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/home/hello")//RequestMapping放在类上面叫做命名空间
public class HelloSpringController {
@RequestMapping({"/first.ann","/hello.ann"})
public ModelAndView doFirst(HttpServletRequest request, HttpServletResponse response) {
ModelAndView mv = new ModelAndView("/WEB-INF/jsp/welcome.jsp");
mv.addObject("message", "执行doFirst方法");
return mv;
}
@RequestMapping("/second.ann")
public ModelAndView doSecond(HttpServletRequest request, HttpServletResponse response) {
ModelAndView mv = new ModelAndView("/WEB-INF/jsp/welcome.jsp");
mv.addObject("message", "执行doSecond方法");
return mv;
}
//这里third前面有且只能有一级,不管这级是什么
//比如url为http://localhost:8080/项目名/home/hello/test/third.do
//如果没有test这级,就无法访问到
//如果是/**/third.ann,那么这里third前面可以有任意级别,包括零级
//这种情况下,下面的url都可以访问到doThird方法
//http://localhost:8080/项目名/home/hello/third.do
//http://localhost:8080/项目名/home/hello/test/third.do
//http://localhost:8080/项目名/home/hello/test1/test2/third.do
@RequestMapping("/*/third.ann")
public ModelAndView doThird(HttpServletRequest request, HttpServletResponse response) {
ModelAndView mv = new ModelAndView("/WEB-INF/jsp/welcome.jsp");
mv.addObject("message", "执行doThird方法");
return mv;
}
}
3. Bean的生命周期.
Spring中,Bean实例从创建到销毁,需要经过很多过程,执行很多生命周期方法,其从创建到执行改实例的实例方法,再到最后销毁,全过程如下图:
(1)容器实例化这个Bean实例,即通过new的方法实例化一个对象;
(2)调用改Bean实例的Setter方法将属性注入值,如果没有Setter方法,这一步就没有;
(3)如果该Bean类实现了BeanNameAware接口,则会执行接口方法setBeanName(String name)
,这里实际上传入的是该Bean实例的id,如果没有id,则传入name;
(4)如果该Bean类实现了BeanFactoryAware接口,则会执行接口方法setBeanFactory(BeanFactory factory)
,使该Bean类获取到BeanFactory对象;
(5)如果该Bean类实现了ApplicationContextAware接口,则会执行接口方法setApplicationContext(ApplicationContext applicationContext)
,使该Bean类获取到ApplicationContext对象;
注:(4)和(5)的区别在于实现BeanFactoryAware 主要目的是为了获取Spring容器,如Bean通过Spring容器发布事件等;ApplicationContextAware接口作用与BeanFactory类似都是为了获取Spring容器;不同的是Spring容器在调用setApplicationContext方法时会把它自己作为setApplicationContext 的参数传入,而Spring容器在调用setBeanDactory前需要程序员自己指定(注入)setBeanDactory里的参数BeanFactory
(6)如果容器里定义并注册了BeanPostProcessor,则执行接口方法postProcessBeforeInitialization(Object bean, String beanName)
,注意该方法最后一定要将参数bean
返回,不能为默认的null
;
(7)如果该Bean类实现了接口InitializingBean接口,则执行接口方法afterPropertiesSet()
,
(8)如果该Bean实例在容器里注册时设置了init-method属性,那么执行init-method属性指定的方法;
(9)如果容器里定义并注册了BeanPostProcessor,则执行接口方法postProcessAfterInitialization(Object bean, String beanName)
,注意该方法最后一定要将参数bean
返回,不能为默认的null
;
到这里为止,该Bean实例就准备好了,可以开始使用其自己的实例方法了,也就是第(10)步:
(10)可以执行该Bean实例的实例方法,不需要执行实例方法,就可以通过手动关闭容器来销毁这个Bean实例,也就是接下来的两步;
(11)如果该Bean类实现了DisposableBean接口,则执行接口方法destroy()
;
(12)如果该Bean类实例在容器里注册时指定了属性destroy-method,那么执行该属性指定的方法。
注:最后两步需要手动关闭容器,即调用close()
方法,但是ApplicationContext接口实际上没有定义这个方法,所以一般需要将容器的引用向下强转类型,除此之外,只有singleton bean实例能够手动销毁,prototype bean是无法手动销毁的,也就是说prototype bean没有后两步的现象!!!
4. bean的name属性和id属性的区别
同名bean:多个bean 有相同的 name 或者 id,称之为同名bean。
<bean>
的id 和 name的区别
id和name都是spring 容器中bean 的唯一标识符。
(1)id:一个bean的唯一标识,命名格式必须符合XML ID属性的命名规范 ,总结起来就相当于一个Java变量的命名:不能以数字,符号打头,不能有空格,如123,?ad,”ab “等都是不规范的,Spring在初始化时就会报错;
(2)name:可以用特殊字符,你可以使用几乎任何的名称,如?ab,123等,但不能带空格,如”a b”,” abc”,这时,虽然初始化时不会报错,但在getBean()则会报错,并且一个bean可以用多个名称:name=“bean1,bean2,bean3” ,用逗号或者分号或者空格隔开。如果没有id,则name的第一个名称默认是id。
spring 容器如何处理同名bean?
(1)同一个spring配置文件中,bean的 id、name是不能够重复的,否则spring容器启动时会报错。
(2)如果一个spring容器从多个配置文件中加载配置信息,则多个配置文件中是允许有同名bean的,并且后面加载的配置文件的中的bean定义会覆盖前面加载的同名bean。
spring 容器如何处理没有指定id、name属性的bean?
(1)如果一个 <bean>
标签未指定 id、name 属性,则 spring容器会给其一个默认的id,值为其类全名。
(2)如果有多个<bean>
标签未指定 id、name 属性,则spring容器会按照其出现的次序,分别给其指定 id 值为 “类全名#1”, “类全名#2”。
#配置文件
<bean class="com.xxx.UserInfo">
<property name="accountName" value="no-id-no-name0"></property>
</bean>
<bean class="com.xxx.UserInfo">
<property name="accountName" value="no-id-no-name1"></property>
</bean>
<bean class="com.xxx.UserInfo">
<property name="accountName" value="no-id-no-name2"></property>
</bean>
#Java代码
UserInfo u4 = (UserInfo)ctx.getBean("com.xxx.UserInfo");
UserInfo u5 = (UserInfo)ctx.getBean("com.xxx.UserInfo#1");
UserInfo u6 = (UserInfo)ctx.getBean("com.xxx.UserInfo#2");
5. Maven搭建Spring和Spring MVC依赖
一、Spring依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
spring-context的jar包:
二、Spring MVC依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.8.RELEASE</version>
</dependency>
spring-webmvc的jar包: