本文记录一些spring开发过程中的小细节。

1、Spring2.5中引入了@Autowired这个注释,它可以将类成员变量、方法、构造函数进行标注,来完成自动装配的工作。也就是说,标注了@Autowiredd类的bean里面再也不需要其他属性了,@Autowired就会把需要的东西自动转配好的。

2、Spring是通过一个BeanPostProcessor对@Autowired注释进行解析的,所以如果想让@Autowired注释起作用,必须事先在spring容器中声明AutowiredAnnotationBeanPostProcessor这个bean,让系统认识@Autowired,才能让@Autowired工作起来。

3、报错信息:Spring 容器抛出BeanCreationException 异常,并指出必须至少拥有一个匹配的 Bean。

原因:在默认情况下使用 @Autowired 注释进行bean的自动装配时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。
当找不到一个匹配的 Bean 时,就会抛出这个异常。

解决方法:在需要自动注入该类 的Bean 的地方使用 @Autowired(required = false)(在java代码中,不是配置文件中)。当不能确定 Spring 容器中一定拥有某个类的 Bean 时,这样的写法就等于告诉 Spring:在找不到匹配的 Bean 时,也不报错。

4、报错信息:Spring 容器抛出BeanCreationException 异常。

原因:与3中的原因正好相反的情况。Spring 容器中拥有了多个候选 的Bean,Spring 容器在启动时不知道装入哪一个bean,所以也会抛出 BeanCreationException 异常。

解决方法:通过 @Qualifier("XXX") 注释(在java代码写参数的地方,不是配置文件中),指定注入 Bean 的名称(代码中的XXX),这样歧义就消除了。

5、由3、4中的小知识可以看出,@Autowired 和@Qualifier 结合使用时,自动注入的策略就从 byType 转变成 byName 了。@Autowired 可以对成员变量、方法以及构造函数进行注释,而@Qualifier 的标注对象是成员变量、方法入参、构造函数入参。正是由于注释对象的不同,所以 Spring 没有将 @Autowired 和@Qualifier 统一成一个注释类。

6、Sping的声明式事务,就是在配置文件中采用配置的方式对事务进行管理,不用自己编写代码,全靠配置就能完成事务控制。Spring中的AOP就是完成事务管理工作的(还有日志管理工作、安全管理工作)。

7、 乱码处理

      1). post乱码

           在web.xml添加post乱码filter:CharacterEncodingFilter

      2). 对于get请求中文参数出现乱码解决方法有两个:

           a. 修改tomcat配置文件,添加编码与工程编码一致,如下:

               <Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

           b. 对参数进行重新编码:

               String userName = new  String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")

               ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码

8、上传图片

      1). 在页面form中提交enctype="multipart/form-data"的数据时,需要springMVC对multipart类型的数据进行解析。

      2). 在springmvc.xml中配置multipart类型解析器。

spring小知识点

3). 方法中使用:MultipartFile attach (单个文件上传) 或者  MultipartFile[] attachs (多个文件上传)。

9、异常处理

      springMVC提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。系统遇到异常,在程序中手动抛出,dao抛给service、service给controller、controller抛给前端控制器,前端控制器调用全局异常处理器。

spring小知识点

10、 数据回显 

      1). @ModelAttribute还可以将方法的返回值传到页面:在方法上加注解@ModelAttribute

      2). 使用最简单方法使用model,可以不用@ModelAttribute:model.addAttribute("id", id);

      3). springMVC默认对pojo数据进行回显。pojo数据传入controller方法后,springMVC自动将pojo数据放到request域,key等于pojo类型(首字母小写)

      4). public String testParam(PrintWriter out, @RequestParam("username") String username) { //out直接输出}

11、spring 校验           

      1). 项目中,通常使用较多是前端的校验,比如页面中js校验。对于安全要求较高的项目,建议在服务端进行校验。

      2). springmvc使用hibernate的校验框架validation(和hibernate没有任何关系)。校验思路:页面提交请求的参数,请求到controller方法中,使用validation进行校验。如果校验出错,将错误信息展示到页面。

12、 集合类型绑定

      1). 数组绑定:

           controller方法参数使用:(Integer[] itemId)

           页面统一使用:itemId 作为name

      2). list绑定:

           pojo属性名为:itemsList

           页面:itemsList[index].属性名

      3). map 绑定:

           pojo属性名为:Map<String, Object> itemInfo = new HashMap<String, Object>(); 

           页面: <td>姓名:<inputtype="text"name="itemInfo['name']"/>

13、 Json处理

1). 加载json转换的jar包:springmvc中使用jackson的包进行json转换(@requestBody和@responseBody使用下边的包进行json转)

2). 配置json转换器。在注解适配器RequestMappingHandlerAdapter中加入messageConverters。如果使用<mvc:annotation-driven/> 则会自动加入。

3). ajax代码:

spring小知识点

4). Controller (ResponseBody、RequestBody)

spring小知识点

5). 注意ajax中contentType如果不设置为json类型,则传的参数为key/value类型。上面设置后,传的是json类型。

14、 拦截器:

      1). 定义拦截器,实现HandlerInterceptor接口。接口中提供三个方法。

            a. preHandle :进入 Handler方法之前执行,用于身份认证、身份授权,比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行

            b. postHandle:进入Handler方法之后,返回modelAndView之前执行,应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图

            c. afterCompletion:执行Handler完成执行此方法,应用场景:统一异常处理,统一日志处理

      2). 配置拦截器:

           a. 针对HandlerMapping配置(不推荐):springmvc拦截器针对HandlerMapping进行拦截设置,如果在某个HandlerMapping中配置拦截,经过该 HandlerMapping映射成功的handler最终使用该拦截器。  (一般不推荐使用)

        b. 类似全局的拦截器:springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中。多省事儿。

spring小知识点

15、 如何启用注解:

      <context:annotation-config/>

   如果使用<context:component-scan base-package="com.tgb.web.controller.annotation"> </context:component-scan>  则上面内容可以省略,推荐使用<mvc:annotation-driven/>代替注解映射器和注解适配器配置。

16、默认情况下,web.xml文件将保存Web应用程序的WebContent/WEB-INF目录。在名为HelloWeb DispatcherServlet初始化时,框架将尝试从位于应用程序的WebContent/WEB-INF目录中的名为[servlet-name]-servlet.xml的文件加载应用程序上下文。在这个示例中,使用的文件将是HelloWeb-servlet.xml

接下来,<servlet-mapping>标记指示哪些URL将由DispatcherServlet处理。 这里所有以.jsp结尾的HTTP请求都将由HelloWeb DispatcherServlet处理。

如果不想使用默认文件名为[servlet-name]-servlet.xml和默认位置为WebContent/WEB-INF,可以通过在web.xml文件中添加servlet侦听器ContextLoaderListener来自定义此文件名和位置。

17、web.xml 是用来初始化配置信息的,这些配置信息的加载顺序如下:context-param > listener > fileter > servlet。

18、DispatcherServlet应用的其实就是一个"前端控制器"的设计模式(其他很多优秀的web框架也都使用了这个设计模式):

①请求驱动;

②所有设计都围绕着一个中央Servlet来展开,它负责把所有请求分发到控制器;

③同时提供其他web应用开发所需要的功能。

19、WebApplicationContext继承自ApplicationContext,它提供了一些web应用经常需要用到的特性。它与普通的ApplicationContext不同的地方在于,它支持主题的解析,并且知道它关联到的是哪个servlet(它持有一个该ServletContext的引用)。

20、HandlerExceptionResolver和web.xml中配置的error-page,两者会有冲突吗?

①如果resolveException异常返回了ModelAndView的话,那就会优先根据返回值中的页面来显示的。不过,resolveException也可以返回null,此时则展示web.xml中的error-page的500状态码配置的页面。

②那么,当web.xml中有相应的error-page配置,在实现resolveException方法的时候就可以选择返回null了,反正会展示web.xml中的error-page的500状态码配置的页面。

21、Spring支持三种依赖注入方式,分别是属性(Setter方法)注入,构造注入和接口注入。在Spring中,那些组成应用的主体,即由Spring IOC容器所管理的对象被称之为Bean。

22、Spring的IOC容器通过反射的机制实例化Bean并建立Bean之间的依赖关系。

23、Bean就是由Spring IOC容器初始化、装配及被管理的对象。获取Bean对象的过程,首先通过Resource加载配置文件并启动IOC容器,然后通过getBean方法获取bean对象,就可以调用他的方法。

24、Spring Bean的作用域

  1. Singleton:Spring IOC容器中只有一个共享的Bean实例,一般都是Singleton作用域。
  2. Prototype:每一个请求,会产生一个新的Bean实例。
  3. Request:每一次http请求会产生一个新的Bean实例。

25、AOP就是纵向的编程,如业务1和业务2都需要一个共同的操作,与其往每个业务中都添加同样的代码,不如写一遍代码,让两个业务共同使用这段代码。这样就提高了代码的复用性,也实现了与业务的解耦。在日常有订单管理、商品管理、资金管理、库存管理等业务,都会需要到类似日志记录事务控制、权限控制、性能统计、异常处理及事务处理等功能。AOP把所有共有代码全部抽取出来,放置到某个地方集中管理,然后在具体运行时,再由容器动态织入这些共有代码。

26、Spring AOP应用场景
性能检测,访问控制,日志管理,事务等。
默认的策略是如果目标类实现接口,则使用JDK动态代理技术,如果目标对象没有实现接口,则默认会采用CGLIB代理。

相关文章: