spring复习
spring是一个轻量级的,非侵入式的,IOC,AOP,一站式的,简化企业级开发而生的.
核心包非常小
业务代码中不侵入框架代码
IOC: 控制反转 将生成对象的权利 反转给了spring框架 依赖注入DI 为属性注入值
AOP: 面向切面编程, 将一些与业务代码无关的公共部分抽取出来,使用时,通过代理对象调用,从而达到不修改源代码的基础上增加功能,代码的耦合度降低.
一站式框架: 数据持久层,web控制层…
如何搭建
创建spring配置文件 spring.xml文件
在spring.xml文件中配置 需要让spring管理的类 <bean id class scope …>
spring框架读取xml文件,解析xml
通过工厂模式+反射机制 创建对象 + 代理模式
在需要使用对象时,从spring容器注入对象即可.
spring中常用的注解标签
1.@Controller
在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model 返回给对应的View 进行展示。在SpringMVC 中提供了一个非常简便的定义Controller 的方法,你无需继承特定的类或实现特定的接口,只需使用@Controller 标记一个类是Controller ,然后使用@RequestMapping 和@RequestParam 等一些注解用以定义URL 请求和Controller 方法之间的映射,这样的Controller 就能被外界访问到。此外Controller 不会直接依赖于HttpServletRequest 和HttpServletResponse 等HttpServlet 对象,它们可以通过Controller 的方法参数灵活的获取到。
@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解。@Controller 只是定义了一个控制器类,而使用@RequestMapping 注解的方法才是真正处理请求的处理器。单单使用@Controller 标记在一个类上还不能真正意义上的说它就是SpringMVC 的一个控制器类,因为这个时候Spring 还不认识它。spring认识他的两种方式
(1)在SpringMVC 的配置文件中定义MyController 的bean 对象。
(2)在SpringMVC 的配置文件中告诉Spring 该到哪里去找标记为@Controller 的Controller 控制器。
spring+jdbc
<!-- 开启全局spring注解扫描--><context:component-scan base-package="ssm"></context:component-scan>
<bean class="ssm.controller.Admincontroller"/>
2.@RequestMapping
RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
questMapping注解有六个属性:
1、 value, method;
value: 指定请求的实际地址,指定的地址可以是URI Template 模式;
method: 指定请求的method类型, GET、POST等;
2、consumes,produces
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
3、params,headers
params: 指定request中必须包含某些参数值是,才让该方法处理。
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
3、@Resource和@Autowired
@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。
1、共同点
两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。
2、不同点
(1)@Autowired
@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。
@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。
(2)@Resource
@Resource默认按照ByName自动注入,由J2EE提供,需要导入包javax.annotation.Resource。@Resource有两个重要的属性:name和type,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。
@Resource装配顺序:
①如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
②如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
③如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。
④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。
@Resource的作用相当于@Autowired,只不过@Autowired按照byType自动注入。
4、@ModelAttribute和 @SessionAttributes
代表的是:该Controller的所有方法在调用前,先执行此@ModelAttribute方法,可用于注解和方法参数中,可以把这个@ModelAttribute特性,应用在BaseController当中,所有的Controller继承BaseController,即可实现在调用Controller时,先执行@ModelAttribute方法。
@SessionAttributes即将值放到session作用域中,写在class上面。
具体示例参见下面:使用 @ModelAttribute 和 @SessionAttributes 传递和保存数据
5、@PathVariable
用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数
6、@requestParam
@requestParam主要用于在SpringMVC后台控制层获取参数,类似一种是request.getParameter(“name”),它有三个常用参数:defaultValue = “0”, required = false, value = “isApp”;defaultValue 表示设置默认值,required 铜过boolean设置是否是必须要传入的参数,value 值表示接受的传入的参数类型。
7、@ResponseBody
作用: 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;
8、@Component
相当于通用的注解,当不知道一些类归到哪个层时使用,一般在model中。
9、@Repository
用于注解dao层,在dao类上面注解。
JdbcTemplate 管理数据源(阿里巴巴 Druid) 事务管理
事务管理的最基本的原理是使用AOP.
声明式事务和编程式事务
事务传播行为 是spring框架自身对事物进行功能上的增强
A 方法 调用 B方法 那么B方法的事务应该如何执行( 把B事务加入到A事务中执行还是 B方法自己创建一个新的独立于A事务)
spring+mybatis
springMVC
执行流程
BeanFactory 和 ApplicationContext 区别
new User() 创建了一个User对象
把由spring框架创建的对象称为一个bean.
BeanFactory 接口是spring框架中最基础的接口, 定义了如何获取bean的方法.
ApplicationContext接口间接的继承了BeanFactory 接口,在此基础之上扩展功能.
BeanFactory 和ApplicationContext
BeanFactory 是最基础的,面向spring框架本身的. 在使用对象时才去创建
ApplicationContext是面向应用的,增加了功能(支持AOP 事务), 适合与web应用程序,在服务器启动时就创建.
springBean 的生命周期
一个对象什么时候生(创建) 什么时候销毁
spring中的bean可能经过5个阶段
1.实例化 创建一个原始的对象 例如 new对象 通过反射机制实现的(框架可以读到类名)
2.属性赋值 为对象的属性进行赋值
UserService
注入UserDao userDao
3.初始化 最早在Serlvet 先创建一个对象 然后调用init()进行初始化
我们的bean如果实现了某些接口,就可以去执行这些方法,用来初始化我们的对象重点在于对类进行功能提升.
如果此类有增强(aop),就是在此处为bean添加功能.
4.使用
5.销毁
细化
细化
1.instantiate bean 对象实例化
2.populate properties 属性赋值
3.1 如果 Bean 实现 BeanNameAware 执行 setBeanName
3.2 如果 Bean 实现 BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext 对象.
初始化
…
3.3 如果存在类实现 BeanPostProcessor(AOP) ,执行
postProcessBeforeInitialization
3.4 如果 Bean 实现 InitializingBean 执行 afterPropertiesSet
如果配置了自己的初始化方法
3.5 如果存在类实现 BeanPostProcessor(AOP) ,执行
postProcessAfterInitialization
4.完整的 bean 创建好,将 bean 对象放入到容器中,可以使用
5.销毁 如果 Bean 实现 DisposableBean 执行 destroy
如果配置了自己的销毁方法
指定销毁方法 customerDestroy.
在这里插入图片描述
Spring 中的 bean 是线程安全的吗?
servlet是线程安全的吗? serlvet是线程不安全的
servlet是单例的还是多例的?
是单例 com.
在服务器启动时由服务器创建,只创建了一个
class UserController{
User user; //是单例bean 把一次请求看做是一个线程 很多个请求,那就是有多个线程 多个线程共享一个 bean
//原型bean 是每次使用时,会创建一个对象,不共享 是线程安全
UserService userService;
}
单例bean就是线程不安全的, 单例bean,多个线程共享同一个.
bean分为 有状态bean 这个变量可以存储数据.
无状态bean 不存储数据的bean
假设UserController,User,UserService 都是单例的
class UserController{
User user; //User作为数据存储的对象,存储用户信息的 是有状态的,不安全
UserService userService; //不存储数据, 是无状态的, 安全的.
}
原型bean是线程安全的.
Bean 循环依赖
什么是循环依赖
class A{
自动注入
B b; //此时B对象有可能还没有创建 ?
}
class B{
自动注入
A a;
}
此情况只在spring中出现,因为spring创建对象时,可以为属性自动注入值, 注入时就需要查找所依赖的对象
解决方法:
在spring中提供一个3级缓存机制
每一个缓存可以理解为一个map容器(把不同的对象做一个临时存储)
一级缓存: 存放创建,初始化完成的完整的bean.
二级缓存: 存储原始的对象
三级缓存: 假如B类如果有需要增强的功能,那么把这个半成品的B对象继续放在3级缓存中去增强功能.
Servlet 的过滤器与 Spring 拦截器区别
区别主要在底层实现方式上有所不同:
过滤器实现是依赖于tomcat,请求会先到达过滤器,然后进入Servlet.
spring拦截器: 是框架内部封装的, 请求是先到达servlet, 根据映射地址,去匹配拦截器,最终到达控住器
实现原理不同
过滤器和拦截器 底层实现方式大不相同,过滤器 是基于函数回调的,拦截器 则
是基于 Java 的反射机制(动态代理)实现的。
使用范围不同
我们看到过滤器 实现的是 javax.servlet.Filter 接口,而这个接口是在 Servlet
规范中定义的,也就是说过滤器 Filter 的使用要依赖于 Tomcat 等容器,导致
它只能在 web 程序中使用。
触发时机不同
过滤器 Filter 是在请求进入容器后,但在进入 servlet 之前进行预处理,请求结
束是在 servlet 处理完以后。
拦截器 Interceptor 是在请求进入 servlet 后,在进入 Controller 之前进行预
处理的,Controller 中渲染了对应的视图之后请求结束。
拦截的请求范围不同
过滤器几乎可以对所有进入容器的请求起作用,而拦截器只会对 Controller 中
请求或访问 static 目录下的资源请求起作用
建模语言
Unified Modeling Language,UML 类图
以可视化图形方式来表述类与类之间的关系,方便理解.
类图的基本元素
类
接口
属性
方法
类之间的关系
依赖关系
在A类中的某个方法中把B类作为参数使用,具有临时性.
关联关系
在一个类中,把另一个类当做属性
**聚合关系 ** 表示一种强关联关系 学校和老师 学校不存在,老师依然存在
组合关系 更强烈的关联关系 头和嘴 头不存在了 嘴也就没有存在的意义
泛化
类继承类, 接口继承接口
实现
类实现接口
面向对象设计原则
继承 多态 提高程序代码复用性和可扩展性
单一职责
一个类负责做一件事. 低耦合,高内聚。
开闭原则
对扩展开发,对修改关闭
抽象功能,具体的实现可以扩展子类.
里氏替换原则
在任何父类出现的地方都可以用它的子类来替换,且不影响功能(多态)
Animal a = new Dog();
依赖倒置
高层模块不应该依赖底层模块,两者都应该依赖其抽象;抽象不应该依赖细节;
细节应该依赖抽象。
在顶层不适合定义太多的功能,底层实现有的可能用不到的.
在中间设计接口,抽象类去扩展功能,底层按照自己的需要去实现即可.
迪米特原则
一个对象应当对其他对象尽可能少的了解,降低耦合。
使用代理的思想,不直接对其他类进行访问
组合/聚合复用原则
class cpu{ }
class 内存{ }
class 硬盘{ }
电脑
cpu
内存
硬盘