Spring 学习笔记

时间:2020-03-10
本文章向大家介绍Spring 学习笔记,主要包括Spring 学习笔记使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1.Spring 

    工作原理:让一个对象的创建不用new就可以自动的生产,在运行时与xml Spring的配置文件来动态的创建对象和调用对象,而不需要通过代码来关联;

    概念:一种多层的J2EE应用程序框架,其核心就是提供一种新的机制管理业务对象及其依赖关系

              一种容器框架(IOC(DI)和AOP),用于创建bean,维护bean之间的关系,它可以管理web层,持久层,业务层等,可以配置各个层的组件并且维护各个层的关系

2.Spring 特性

   非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API

   控制反转:IOC——Inversion of Control,指的是将对象的创建权交给Spring去创建;动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟xml Spring的配置文件来动态的创建对象和调用对象里的方法的 。

   依赖注入:DI——Dependency Injection,是指依赖的对象不需要手动调用setXX方法去设置,而是通过配置赋值。

   面向切面编程:Aspect Oriented Programming——AOP,可以为某一类对象进行监督和控制(也就是在调用这类对象的具体方法的前后去调用你指定的模块)从而达到对一个模块扩充的功能

   容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期

  组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。

  一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)
3.Spring Bean的作用域和生命周期

    bean 就是由 IOC 容器初始化、装配及管理的对象;

    不仅可以控制注入到对象中的各种依赖和配置值,还可以控制该对象的作用域

    作用域: request、session 和 global session 三种作用域仅在基于web的应用中使用(不必关心你所采用的是什么web应用框架),只能用在基于 web 的 Spring ApplicationContext 环境。

 4.Spring  SpringMVC请求到响应流程

    1)用户向服务器发送请求,请求被Spring的前端控制器DispatcherServlet截获,它会负责调用系统的其他模块来真正处理用户的请求。 

    2)DispatcherServlet对请求URL(统一资源定位符)进行解析,得到URI(请求资源标识符),然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关对象,包括Handler对象以及Handler对象对应的拦截器,并将这些对象封装到一个HandlerExecutionChain对象当中返回。
    3)DispatcherServlet根据获得的Handler,选择一个合适的HandlerAdapter。HandlerAdapter(适配器)会被用于处理多种Handler,调用Handler实际处理请求的方法。
    4)提取请求中的模型数据,开始执行Handler(Controller),在填充Handler的入参过程中,根据配置,Spring将做一些额外的工作。
        消息转换:将请求消息转换成一个对象,将对象转换为指定的响应信息。
        数据转换:对请求消息进行数据转换,如String转换成Integer等。
        数据格式化:对请求信息进行数据格式化,如将字符串转换成格式化数字或格式化日期等。
        数据验证:验证数据的有效性,验证结果存储到BindingResult或Error中。
    5)Handler执行完成后,向DispatcherServlet返回一个ModelAndView对象,ModelAndView对象中包含视图名或视图名和模型。
    6)根据返回的ModelAndView对象,选择一个合适的ViewResolver(视图解析器)返回给DispatcherServlet。
    7)ViewResolver结合Model和View来渲染视图。
    8)将视图渲染结果返回给客户端。

 5.Spring AOP(面向对象切面编程)

     AOP机制可以让开发者把业务流程中的通用功能抽取出来,单独编写功能代码。在业务流程执行过程中,Spring框架会根据业务流程要求,自动把独立编写的功能代码切入到流程的合适位置,例如:权限验证、登录、日志管理等

    AOP(Aspect-Oriented Programming)指一种程序设计范型,该范型以一种称为切面(aspect)的语言构造为基础,切面是一种新的模块化机制,用来描述分散在对象、类或方法中的横切关注点(crosscutting concern)

  "横切关注"是会影响到整个应用程序的关注功能,它跟正常的业务逻辑是正交的,没有必然的联系,但是几乎所有的业务逻辑都会涉及到这些关注功能。通常,事务、日志、安全性等关注就是应用中的横切关注功能。

 6.Spring SpringMVC常用注解

   1)@Controller  标记的类就是一个SpringMVC Controller 对象,分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解;@Controller 只是定义了一个控制器类,而使用@RequestMapping 注解的方法才是真正处理请求的处理器。

  2)@RequestMapping(value="实际地址",method="请求方式")  一个用来处理请求地址映射的注解,可用于类或方法上。

  3)@Resource  并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入;

                          Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。

  4)@Autowired  Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired

  5)@PathVarible  取出uri模板中的变量作为参数

  6)@CookieValue  用来获取Cookie中的值(value:参数名称   required:是否必须  defaultValue:默认值)

  7)@RequestParam  用于将请求参数区数据映射到功能处理方法的参数上

  8)@ResponseBody  注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区

                  返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用

  9)@SessionAttributes   将值放到session作用域中,写在class上面

10)@Service  标记业务组件【标注的类职责是一个业务类【即 service 组件】】

11)@Component  指组件,当组件不好归类的时候,我们可以使用这个注解进行标注

12)@Respository  标记组件为数据访问层[Dao,mybatis 称之为 Mapper]

13)@CrossOrigin  跨源资源共享(CORS) 

14)@ModelAttributes  该Controller的所有方法在调用前,先执行此@ModelAttribute方法,可用于注解和方法参数中,可以把这个@ModelAttribute特性,应用在BaseController当中,所有的Controller继承BaseController,即可实现在调用Controller时,先执行@ModelAttribute方法

@Controller
@RequestMapping("/springmvc")
public class ModelAttributeTest {

    private static final String SUCCESS = "success";
    
    /**
     * 1.有 @ModelAttribute 标记的方法,会在每个目标方法执行之前被 SpringMVC 调用
     * 2.@ModelAttribute注解也可以修饰目标方法POJO类形的入参,其value的属性值有如下作用:
     *     1)SpringMVC会使用value属性值在implicitModel中查找对应的对象,若存在则直接传入到目标方法的入参中
     *     2)SpringMVC会以value为key,POJO类型的对象为value,存入的request中
     * 
     * @param id
     * @param map
     */
    @ModelAttribute
    public void getUser(@RequestParam(value = "id", required = false) int id,
            Map<String, Object> map) {
        //模拟数据库中获取对象
        User user = new User(1, "刘邦", "123", "023", "重庆");
        System.out.println("从数据库中获取一个对象:" + user);
        map.put("abc", user);
    }
    
    /**
     * 运行流程:
     *         1.执行@ModelAttribute注解修饰的方法,从数据库中取出对象,把对象放入Map中,键为:user;
     *         2.SpringMVC从Map中取出User对象,并把表单的请求参数赋值给该User对象的对应属性;
     *         3.SpringMVC把上述对象传入目标方法的参数。
     * 
     * 注意:在@ModelAttribute修饰的方法中,放入到Map时的键需要和目标方法入参类型的第一个字母小写的字符串一致
     * 
     * @param user
     * @return
     */
    @RequestMapping("/testModelAttribute")
    public String testModelAttribute(@ModelAttribute("abc") User user) {
        System.out.println("修改:" + user);
        return SUCCESS;
    }
}

7.Spring Bean的生命周期

1)Spring IoC 容器找到关于 Bean 的定义并实例化该 Bean。
2)Spring IoC 容器对 Bean 进行依赖注入。
3)如果 Bean 实现了 BeanNameAware 接口,则将该 Bean 的 id 传给 setBeanName 方法。
4)如果 Bean 实现了 BeanFactoryAware 接口,则将 BeanFactory 对象传给 setBeanFactory 方法。
5)如果 Bean 实现了 BeanPostProcessor 接口,则调用其 postProcessBeforeInitialization 方法。
6)如果 Bean 实现了 InitializingBean 接口,则调用其 afterPropertySet 方法。
7)如果有和 Bean 关联的 BeanPostProcessors 对象,则这些对象的 postProcessAfterInitialization 方法被调用。
8)当销毁 Bean 实例时,如果 Bean 实现了 DisposableBean 接口,则调用其 destroy 方法。
8.Spring AOP几种通知(advice)
 本质都是拦截器
 1)Around advice  包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型。 环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行。
//摘自Spring reference
public
interface MethodInterceptor extends Interceptor { Object invoke(MethodInvocation invocation) throws Throwable; } public class DebugInterceptor implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("Before: invocation=[" + invocation + "]"); //(1) Object rval = invocation.proceed(); System.out.println("Invocation returned"); //(2) return rval; } }

    @Around(execution):唯一可以使用ProceedingJoinPoint参数来控制流程的advice,在方法执行前拦截,可以在切面逻辑中手动释放拦截,且可以在其后加入逻辑代码,该代码段会在方法执行后执行;

  2)Before Advice  在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。

public interface MethodBeforeAdvice extends BeforeAdvice {
    void before(Method m, Object[] args, Object target) throws Throwable;
}

    @Before(execution)  在方法执行前拦截

3)After Returning Advice  在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。

public interface AfterReturningAdvice extends Advice {
    void afterReturning(Object returnValue, Method m, Object[] args, Object target) throws Throwable;
}

   @AfterReturning(execution)   在方法正常return结束后拦截

4)After Throwing Advice  在方法抛出异常退出时执行的通知

//ThrowsAdvice 是一个空接口,起标识作用
public interface ThrowsAdvice extends Advice {

}
//所给对象必须实现一个或者多个针对特定类型的异常通知方法,格式如下
afterThrowing([Method], [args], [target], subclassOfThrowable)
//只有最后一个参数是必须的。因此异常通知方法对方法及参数的需求,方法的签名将从一到四个参数之间变化。

  @AfterThrowing(execution)  在方法抛出异常时拦截

5)After Advice  当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)

  @After(execution)  在方法结束后拦截,无论正常结束还是异常结束

9.Spring 事务管理

      Spring 支持编程式事务管理声明式事务管理
      事务分为全局事务和局部事务:全局事务由应用服务器管理,需要底层服务器 JTA 支持(如 WebLogic、WildFly 等);
                                                   局部事务和底层采用的持久化方案有关,例如使用 JDBC 进行持久化时,需要使用 Connetion 对象来操作事务;而采用 Hibernate 进行持久化时,需要使用 Session 对象来操作事务  
      Spring 的事务管理机制是一种典型的策略模式,PlatformTransactionManager 代表事务管理接口,该接口定义了三个方法,该接口并不知道底层如何管理事务,但是它的实现类必须提供 getTransaction()方法(开启事务)、commit()方法(提交事务)、rollback()方法(回滚事务)的多态实现,这样就可以用不同的实现类代表不同的事务管理策略。使用 JTA 全局事务策略时,需要底层应用服务器支持,而不同的应用服务器所提供的 JTA 全局事务可能存在细节上的差异,因此实际配置全局事务管理器是可能需要使用 JtaTransactionManager 的子类,如:WebLogicJtaTransactionManager(Oracle 的 WebLogic 服务器提供)、UowJtaTransactionManager(IBM 的 WebSphere服务器提供)等。
          这些事务的父接口都是 PlatformTransactionManager
10.Spring 事务传播方式
     REQUIRED   如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
     NOT_SUPPORTED   容器不为这个方法开启事务
     REQUIRES_NEW  不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
     MANDATORY   必须在一个已有的事务中执行,否则抛出异常
     NEVER   必须在一个没有的事务中执行 , 否则抛出异常 ( 与Propagation.MANDATORY 相反)
     SUPPORTS  如果其他 bean 调用这个方法,在其他 bean 中声明事务,那就用事务.如果其他 bean 没有声明事务,那就不用事务
11.Spring 事务隔离级别      
     READ_UNCOMMITTED  读取未提交数据(会出现脏读, 不可重复读)
     READ_COMMITTED  读取已提交数据(会出现不可重复读和幻读)
     REPEATABLE_READ 可重复读(会出现幻读)
     SERIALIZABLE 串行化
      mysql 默认为 REPEATABLE_READ
  

原文地址:https://www.cnblogs.com/dxjx/p/12457242.html