赞
踩
1、spring的好处/特点
简单的理解就是,原先将本程序中所使用到的对象,的生命周期交给容器去维护和管理。这就是IOC。SpringIOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。
对于DI的理解是,本类中所使用到的其他对象,在程序代码中只需要声明一下,相关实例化的工作交给了容器,容器会在运行期new出相应的对象,并赋值给程序代码。这个过程类似于注入的过程。
表格 1 BeanFactory和ApplicationContext对比
特性 | BeanFactory | ApplicationContext |
Bean实例化/装配 | Yes | Yes |
自动BeanPostProcessor注册 | No | Yes |
自动BeanFactoryPostProcessor注册 | No | Yes |
便捷的MessageSource访问(i18n) | No | Yes |
ApplicationEvent发送 | No | Yes |
说明:实现该接口的setApplicationContext(ApplicationContextcontext)方法,并保存ApplicationContext 对象。Spring初始化时,会通过该方法将ApplicationContext对象注入。
两种依赖方式都可以使用,构造器注入和Setter方法注入。最好的解决方案是用构造器参数实现强制依赖,setter方法实现可选依赖。
Springbeans是那些形成spring应用的主干的Java对象。它们被SpringIOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中<bean/>的形式定义。
Spring框架定义的beans都是单例beans。在beantag中有个属性”singleton”,如果它被赋为TRUE,bean 就是单例,否则就是一个prototype bean。默认是TRUE,所以所有在Spring框架中的beans缺省都是单例。
一个SpringBean的定义包含容器必知的所有配置元数据,包括如何创建一个bean,它的生命周期详情及它的依赖。
这里有三种重要的方法给Spring容器提供配置元数据。
Spring framework支持五种作用域(其中有三种只能用在基于web的SpringApplicationContext)。
表格 2 spring scope作用域详解
singleton | 在每个Spring IoC容器中一个bean定义对应一个对象实例。 |
prototype | 一个bean定义对应多个对象实例。 |
request | 在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例,它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext情形下有效。 |
session | 在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。 |
global session | 在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。 |
不,Spring框架中的单例bean不是线程安全的。
Spring的内部Bean在做注入时,只能用于当前的Bean属性注入,在外不可以引用。在Spring的 基于XML的 配置元数据中,可以在<property/>或<constructor-arg/> 元素内使用<bean/> 元素,内部bean通常是匿名的,它们的Scope一般是prototype。
Spring提供以下几种集合的配置元素:
bean 装配:是指在Spring容器中把bean组装到一起,前提是容器需要知道bean的依赖关系,如何通过依赖注入来把它们装配到一起。
Spring容器能够自动装配相互合作的bean,这意味着容器不需要<constructor-arg>和<property>配置,能通过Bean工厂自动处理bean之间的协作。
有五种自动装配的方式,可以用来指导Spring容器用自动装配方式来进行依赖注入。
自动装配的局限性是:
20 基于Java的spring注解配置(给一些注解的例子)
基于Java的配置,允许你在少量的Java注解的帮助下,进行你的大部分Spring配置而非通过XML文件。
以@Configuration注解为例,它用来标记类可以当做一个bean的定义,被SpringIOC容器使用。另一个例子是@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。(一般很少用java代码对元数据进行配置)
相对于XML文件,注解型的配置依赖于通过字节码元数据装配组件,而非尖括号的声明。开发者通过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用xml表述bean的装配关系。
注解装配在默认情况下是不开启的,为了使用注解装配,我们必须在Spring配置文件中配置<context:annotation-config/> 元素。(<context:annotation-config/>标签可以开启自动扫描,同时也开启注解装配)
@Autowired()
@Qualifier("baseDao")
private BaseDao baseDao;
@Resource(name="baseDao")
private BaseDao baseDao;
推荐使用:@Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与spring的耦合。这样代码看起就比较优雅。
24 spring对DAO的支持
Spring对数据访问对象(DAO)的支持旨在简化它和数据访问技术如JDBC,Hibernateor JDO 结合使用。这使我们可以方便切换持久层。编码时也不用担心会捕获每种技术特有的异常。
不变:资源的获取,资源的释放,异常转化(Spring提供了模板类对此负责)。
变化:SQL,变量,结果集的提取。
简化对JDBC的操作
应用
DAO中获得JdbcTemplate的两种方式:
在Spring中有两种方式访问hibernate:
用Spring的SessionFactory调用LocalSessionFactory。集成过程分三步:
Spring支持两种类型的事务管理:
表格3 Spring事务配置选项
属性 | 类型 | 默认值 | 说明 |
propagation | Propagation枚举 | REQUIRED | 事务传播属性 |
isolation | isolation枚举 | DEFAULT(所用数据库默认级别) | 事务隔离级别 |
readOnly | boolean | false | 是否用优化的只读事务 |
timeout | int | -1 | 超时(秒) |
rollbackFor | Class[] | {} | 需要回滚的异常类 |
rollbackForClassName | String[] | {} | 需要回滚的异常类名 |
noRollbackFor | Class[] | {} | 不需要回滚的异常类 |
noRollbackForClassName | String[] | {} | 不需要回滚的异常类名 |
33 spring AOP的概念
面向切面的编程,是一种编程技术,是OOP(面向对象编程)的补充和完善。OOP的执行是一种从上往下的流程,并没有从左到右的关系。因此在OOP编程中,会有大量的重复代码。而AOP则是将这些与业务无关的重复代码抽取出来,然后再嵌入到业务代码当中。常见的应用有:权限管理、日志、事务管理等。
实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。Spring AOP实现用的是动态代理的方式。
引入(Introduction):添加方法或字段到被通知的类。Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现IsModified接口,来简化缓存。Spring中要使用Introduction,可有通过DelegatingIntroductionInterceptor来实现通知,通过DefaultIntroductionAdvisor来配置Advice和代理类要实现的接口。
代理器有三类:
所有的自动代理创建器,都是实现了BeanPostProcessor。spring容器在实例化Bean时,BeanPostProcessor会对其加工,对满足匹配规则的Bean自动创建代理对象。
织入(Weaving):把切面(Aspect)应用到目标对象来创建新的代理对象的过程,织入一般发生在如下几个时机:
2、@AspectJ注解驱动的切面:基于注解的开发(推荐使用),在项目中需要开启AOP自动代理<aop:aspectj-autoproxy/>。
3、XML Schema方式:需要实现相应的增强接口,如BeforeAdvice、AfterAdvice等。然后利用一下配置如:
41 spring MVC原理
Spring工作流程描述
1、用户向服务器发送请求,请求被Spring前端控制DispatcherServlet捕获;
2、DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
3、DispatcherServlet根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)
4、提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
HttpMessageConveter:将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息。
数据转换:对请求消息进行数据转换。如String转换成Integer、Double等。
数据根式化:对请求消息进行数据格式化。如将字符串转换成格式化数字或格式化日期等。
数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中。
5、Handler执行完成后,向DispatcherServlet返回一个ModelAndView对象;
6、根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet;
7、ViewResolver结合Model和View,来渲染视图。
8、将渲染结果返回给客户端。
Spring的MVC框架是围绕DispatcherServlet来设计的,它用来处理所有的HTTP请求和响应。DispatcherServlet主要用作职责调度工作,本身主要用于控制流程,主要职责如下:
1、文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析;
2、通过HandlerMapping,将请求映射到处理器(返回一个HandlerExecutionChain,它包括一个处理器、多个HandlerInterceptor拦截器);
3、通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器);
4、通过ViewResolver解析逻辑视图名到具体视图实现;
5、本地化解析;
6、渲染具体的视图等;
7、如果执行过程中遇到异常将交给HandlerExceptionResolver来解析。
WebApplicationContext继承了ApplicationContext并增加了一些WEB应用必备的特有功能,它不同于一般的ApplicationContext,因为它能处理主题,并找到被关联的servlet。
1、首先,对于一个Web应用来说,Web容器提供一个全局的上下文环境(servletContext),为后面的SpringIOC容器作为宿主环境。
2、然后,在web.xml中会有提供ContextLoaderListener。在web容器启动的过程当中,会监听到servletContext的变化,其contextInitialized方法会被调用。在这个方法中,Spring会启动一个跟上下文(WebApplicationContext/XmlWebApplicationContext)。这个就是SpringIOC容器,对应的Bean定义的配置由web.xml中的context-param标签指定。在这个IoC容器初始化完毕后,spring以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE为属性Key,将其存储到ServletContext中,便于获取;
3、最后,contextLoaderListener监听器初始化完毕后,开始初始化web.xml中配置的Servlet,这个servlet可以配置多个,以最常见的DispatcherServlet为例,这个servlet实际上是一个标准的前端控制器,用以转发、匹配、处理每个servlet请求。DispatcherServlet上下文在初始化的时候会建立自己的IoC上下文,用以持有springmvc相关的bean。在建立DispatcherServlet自己的IoC上下文时,会利用WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE先从ServletContext中获取之前的根上下文(即WebApplicationContext)作为自己上下文的parent上下文。有了这个parent上下文之后,再初始化自己持有的上下文。这个DispatcherServlet初始化自己上下文的工作在其initStrategies方法中可以看到,大概的工作就是初始化处理器映射、视图解析等。这个servlet自己持有的上下文默认实现类也是XmlWebApplicationContext。初始化完毕后,spring以与servlet的名字相关(此处不是简单的以servlet名为Key,而是通过一些转换,具体可自行查看源码)的属性为属性Key,也将其存到ServletContext中,以便后续使用。这样每个servlet就持有自己的上下文,即拥有自己独立的bean空间,同时各个servlet共享相同的bean,即根上下文(第2步中初始化的上下文)定义的那些bean。
@Controller:该注解表明该类扮演控制器的角色,Spring不需要你继承任何其他控制器基类或引用ServletAPI。
@RequestMapping:该注解是用来映射一个URL到一个类或一个特定的方处理法上。
@RequestParam:绑定HttpServletRequest请求参数到控制器方法参数。(默认在方法入参中按参数名绑定)
@RequestHeader:注解绑定HttpServletRequest头信息到Controller方法参数。
@CookieValue:绑定cookie的值到Controller方法参数。
支持的方法参数类型
(1)HttpServlet对象,主要包括HttpServletRequest、HttpServletResponse和HttpSession对象。这些参数Spring在调用处理器方法的时候会自动给它们赋值,所以当在处理器方法中需要使用到这些对象的时候,可以直接在方法上给定一个方法参数的申明,然后在方法体里面直接用就可以了。但是有一点需要注意的是在使用HttpSession对象的时候,如果此时HttpSession对象还没有建立起来的话就会有问题。
(2)Spring自己的WebRequest对象。使用该对象可以访问到存放在HttpServletRequest和HttpSession中的属性值。
(3)InputStream、OutputStream、Reader和Writer。InputStream和Reader是针对HttpServletRequest 而言的,可以从里面取数据;OutputStream和Writer 是针对HttpServletResponse而言的,可以往里面写数据。
(4)使用@PathVariable、@RequestParam、@CookieValue和@RequestHeader标记的参数。
(5)使用@ModelAttribute标记的参数。
(6)Java.util.Map、Spring封装的Model和ModelMap。这些都可以用来封装模型数据,用来给视图做展示。
(7)实体类。可以用来接收上传的参数。
(8)Spring封装的MultipartFile。用来接收上传文件的。
(9)Spring封装的Errors和BindingResult对象。这两个对象参数必须紧接在需要验证的实体对象参数之后,它里面包含了实体对象的验证结果。
支持的返回类型
(1)一个包含模型和视图的ModelAndView对象。
(2)一个模型对象,这主要包括Spring封装好的Model和ModelMap ,以及java.util.Map,当没有视图返回的时候视图名称将由RequestToViewNameTranslator来决定。
(3)一个View对象。这个时候如果在渲染视图的过程中模型的话就可以给处理器方法定义一个模型参数,然后在方法体里面往模型中添加值。
(4)一个String字符串。这往往代表的是一个视图名称。这个时候如果需要在渲染视图的过程中需要模型的话就可以给处理器方法一个模型参数,然后在方法体里面往模型中添加值就可以了。
(5)返回值是void。这种情况一般是我们直接把返回结果写到HttpServletResponse中了,如果没有写的话,那么Spring将会利用RequestToViewNameTranslator来返回一个对应的视图名称。如果视图中需要模型的话,处理方法与返回字符串的情况相同。
(6)如果处理器方法被注解@ResponseBody标记的话,那么处理器方法的任何返回类型都会通过HttpMessageConverters转换之后写到HttpServletResponse中,而不会像上面的那些情况一样当做视图或者模型来处理。
(7)除以上几种情况之外的其他任何返回类型都会被当做模型中的一个属性来处理,而返回的视图还是由RequestToViewNameTranslator来决定,添加到模型中的属性名称可以在该方法上用@ModelAttribute(“attributeName”)来定义,否则将使用返回类型的类名称的首字母小写形式来表示。使用@ModelAttribute标记的方法会在@RequestMapping 标记的方法执行之前执行。
SpringMVC支持使用@ModelAttribute和@SessionAttributes在不同的模型和控制器之间共享数据。
@ModelAttribute:一种是标注在方法上,另一种是标注在Controller方法参数上。
当@ModelAttribute标记单独使用时,被标注的方法将在处理器方法执行之前执行,然后把返回的对象存放在模型属性中,传给标注在方法入参上的变量。
@SessionAttributes:用于标记需要在Session中使用到的数据,包括从Session中取数据和存数据。@SessionAttributes一般是标记在Controller类上的,可以通过名称、类型或者名称加类型的形式来指定哪些属性是需要存放在session中的。
当使用@SessionAttributes时,如没有@ModelAttribute标注的方法,则去session中寻找。当controller类中的方法的变量,能匹配到@SessionAttributes中的名称或类型时,在方法返回后会将变量存放在Session中。
Spring 3.0以后,可以继承org.springframework.core.convert.converter接口,实现对应的转换器,然后,
1、通过XMLSchema注册到ConversionService。
2、通过ConfigurableWebBindingInitializer注册ConversionService。
3、注册ConfigurableWebBindingInitializer到RequestMappingHandlerAdapter。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。