Java笔记 | Spring
- Spring IOC
IOC(Inversion of Control,控制反转),是面向对象编程中的一种设计原则,可以用来降低代码间的耦合度。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
- Spring AOP
AOP(Aspect Oriented Programming,面向切面编程),底层使用的是动态代理,有两种实现方式:
--JDK动态代理
利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用 InvokeHandler 来处理。
--CGlib动态代理
以 CGLIB(Code Generation Library)的方式进行代理,它采用底层字节码技术,将代理对象类的 class 文件加载进来,通过修改其字节码生成子类来处理。
JDK 代理只能对实现接口的类生成代理;CGLIB 是针对类实现代理,继承指定类并生成一个子类,因此不能代理 final 修饰的类。
如果目标对象实现了接口,默认会采用 JDK 的动态代理,但也可以强制使用 CGLIB;如果目标对象没有实现了接口,则必须采用 CGLIB 库。Spring 会自动在 JDK 动态代理和 CGLIB 之间转换。
- Bean 的生命周期
--实例化 Bean
对于 BeanFactory 容器,当向容器请求一个尚未初始化的 bean 时,或初始化 bean 的时候需要注入另一个尚未初始化 bean 的依赖时,容器就会调用 createBean 进行实例化;
对于 ApplicationContext 容器,当容器启动结束后,通过获取 BeanDefinition 对象中的信息,实例化所有的 bean。
--设置对象属性(依赖注入)
实例化后的 Bean 被封装在 BeanWrapper 对象中,然后 Spring 根据 BeanDefinition 中的信息以及通过 BeanWrapper 提供的设置属性的接口完成依赖注入。
--处理 Aware 接口
Spring 会检测该 Bean 是否实现了 xxxAware 接口,并将相关的 xxxAware 实例注入给 Bean:
① 如果该 Bean 实现了 BeanNameAware 接口,会调用它实现的 setBeanName (String beanId) 方法,入参是 Spring 配置文件中 Bean 的 id 值;
② 如果该 Bean 实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory () 方法,传递的是 Spring 工厂自身。
③ 如果该 Bean 已经实现了 ApplicationContextAware 接口,会调用 setApplicationContext (ApplicationContext) 方法,入参是 Spring 上下文;
--处理 BeanPostProcessor 接口
如果该 Bean 实现了实现了 BeanPostProcessor 接口,那将会调用 postProcessBeforeInitialization (Object obj, String s) 方法;
-- InitializingBean 与 init-method
如果该 Bean 在 xml 中配置了 init-method 属性,则会自动调用其配置的初始化方法。
以上5个步骤完成后,Bean 就已经被正确创建了,之后就可以使用这个 Bean 了。
--处理 DisposableBean 接口
当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 这个接口,会调用其实现的 destroy () 方法。
--处理 destroy-method 属性
最后,如果这个 Bean 的 Spring 配置中配置了 destroy-method 属性,会自动调用其配置的销毁方法。
- Spring支持的事务管理类型
(1)编程式事务管理:是指在代码中手动的管理事务的提交、回滚等操作;
(2)声明式事务管理:将事务管理作为一个“切面”代码单独编写,只用关心核心业务逻辑代码,然后通过 AOP 技术将事务管理的 “切面” 代码织入到业务类中。
声明式事务的缺点在于只能作用到方法级别,无法做到像编程式事务那样能控制到代码块级别;其优点则在于可以将业务代码和事务管理分离,编程式事务则对业务代码侵入式太强。
- Spring注解
@RestController
由 @Controller 和 @ResponseBody 组成。@Controller 将当前修饰的类注入 SpringBoot IOC 容器,使得从该类所在的项目跑起来的过程中,这个类就被实例化。当然也有语义化的作用,即代表该类是充当Controller的作用。@ResponseBody 将该类中所有的API接口返回的数据,以Json字符串的形式返回给客户端。
@RequestMapping
用于映射请求,也就是通过它来指定控制器可以处理哪些URL请求。value 或 path 定义URL地址,method 定义浏览器接收的请求类型,param 定义请求参数,即追加在URL上的键值对,headers 定义请求头。
@Autowired
对类成员变量、方法及构造函数进行标注,完成自动装配的工作。
用于配置Bean的注解:Component、@Controller、@Service、@Repository。@Controller通常用于控制器,@Service通常用于业务逻辑类,@Repository通常用于仓储类(例如我们的DAO实现类),@Component通常用于标注普通的类。
- Spring优势
--方便解耦,简化开发
--AOP编程的支持
--声明事物的支持
--方便程序的测试
--方便集成各种优秀框架
--降低Java EE API的使用难度
--Java 源码是经典学习范例
- Mybatis中 # 和 $ 的区别
# 和 $ 都是 Mybatis 的占位符。
-- # 变量在预编译阶段生效,此时会将 sql 中的 # 替换为 ? 号,调用 PreparedStatement 的 set 方法来赋值;$ 变量是在动态 SQL 解析阶段生效,直接进行字符串替换;
-- # 方式能够很大程度防止 sql 注入; $ 方式无法防止 Sql 注入;