Spring
框架优点
- 低侵入式设计,代码的污染极低
- DI机制将对象之间的依赖关系交由框架处理,减低组件的耦合性
- 提供了AOP技术,支持将一些通用任务,如安全、事务、日志、权限等进行集中式管理,从而提供更好的复用
- 对于主流的应用框架提供了集成支持
AOP
- 面向切面,作为面向对象的一种补充,用于将那些与业务无关,却对多个对象产生影响的公共行为和逻辑,抽取封装成一个可重用的模块 - “切面”
- AOP主要一般应用于签名验签、参数校验、日志记录、事务控制、权限控制、性能统计、异常处理等
- 代理模式
- 静态代理 AspectJ
- AOP框架会在编译阶段生成AOP代理类(编译时增强),会在编译阶段将AspectJ(切面)织入到Java字节码中,运行时就是增强之后的AOP对象
- 动态代理 Spring AOP
- AOP框架不会修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,其中包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象方法
- JDK动态代理(不支持类的代理)
- InvocationHandler接口
- 通过invoke()方法反射来调用目标类中代码,动态将横切逻辑和业务编织在一起
- Proxy类
- 利用InvocationHandler动态创建一个符合某一接口的实例,生成目标类的代理对象
- CGLIB动态代理
- 如果代理类没有实现InvocationHandler接口,AOP会选择使用CGLIB来动态代理目标类
- 代码生成类库,在运行时动态生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。通过继承的方式做的动态代理
- JDK动态代理(不支持类的代理)
- AOP框架不会修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,其中包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象方法
- Pointcut
- execution(public * cn.wbnull.springbootdemo.controller..(…))
- 范围为controller包下所有的类的所有方法
- 作为切入点签名的方法必须返回void类型
- doBefore()方法使用@Before(“signAop()”)注解,表示前置通知(在某连接点之前执行的通知),但这个通知不能阻止连接点之前的执行流程,除非它抛出一个异常
- doAfterReturning()方法使用@AfterReturning(value = “signAop()”, returning = “params”)注解,表示后置通知(在某连接点正常完成后执行的通知)。在目标方法执行成功后才会执行
- @After:后置通知, 在方法执行之后执行,无论连接点方法执行成功还是出现异常
- @AfterThrowing:异常通知, 在方法抛出异常之后
- @Around:在原方法执行前执行,在原方法执行后再执行
- 执行顺序
- @Around
- @Before
- method
- @Around
- @After
- @AfterReturning
- @AfterThrowing
注解
- @Controller
- 视图解析器可以解析return的jsp,html页面,并且跳转到相应页面
- 若返回json到页面,则需要加@ResponseBody注解
- @RestController
- 组合了@Controller+@ResponseBody
- 自定义注解
- @Target
- 用户描述注解的作用范围
- CONSTRUCTOR:用于描述构造器
- FIELD:用于描述域
- LOCAL_VARIABLE:用于描述局部变量
- METHOD:用于描述方法
- PACKAGE:用于描述包
- PARAMETER:用于描述参数
- TYPE:用于描述类、接口(包括注解类型) 或enum声明
- 用户描述注解的作用范围
- @Retention
- 表示需要在什么级别保存该注释信息
- SOURCE:源文件保留
- CLASS:class保留
- RUNTIME:运行时保留(常用)
- 表示需要在什么级别保存该注释信息
- @Documented
- 标记注解
- @Inherited
- 用于声明一个注解
- 定义切面、切点
IOC
- IOC让对象的创建不用去new了,可以由spring自动生产,使用java的反射机制,根据配置文件在运行时动态的去创建对象以及管理对象,并调用对象的方法的
- 构造器注入
- setter方法注入
- 根据注解注入
- @Autowired
- 默认按类型进行自动装配(该注解属于Spring),默认情况下要求依赖对象必须存在,如果要允许为null,需设置required属性为false,例:@Autowired(required=false)
- @Resource
- 默认按照名称进行装配(该注解属于J2EE),名称可以通过name属性来指定。当找不到与名称相匹配的Bean时,会按照类型进行装配
- @Autowired
- .静态工厂注入
xml配置bean
<bean id="helloWorld" class="com.test.spring.beans.HelloWorld">
<property name="name" value="Spring"></property>
</bean>
- setter()方法注入使用 元素, 使用 name 属性指定 Bean 的属性名称,value 属性或 子节点指定属性值
<bean id="car" class="com.test.spring.beans.Car">
<constructor-arg value="Audi" index="0"></constructor-arg>
<constructor-arg value="ShangHai" index="1"></constructor-arg>
<constructor-arg value="300000" type="double"></constructor-arg>
</bean>
- 构造器注入在 元素里声明属性
- 中没有 name 属性
- 用value属性值或value子节点为属性赋值
- 使用索引 index 和type属性对应为哪个属性赋值
- index的值表示构造函数中参数的位置
- type表示成员属性的类型
- 使用property的ref属性建立bean之间的引用关系
- 标签
- 作为子标签
Spring Bean生命周期
- 实例化Bean
- 对于BeanFactory容器
- 当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化
- 对于ApplicationContext容器
- 当容器启动结束后,通过获取BeanDefinition对象中的信息,实例化所有的bean
- 依赖注入
- 实例化后的对象被封装在BeanWrapper对象中,紧接着,Spring根据BeanDefinition中的信息 以及 通过BeanWrapper提供的设置属性的接口完成依赖注入
- 处理Aware接口
- ①如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的就是Spring配置文件中Bean的id值
- ②如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,传递的是Spring工厂自身
- ③如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文
- BeanPostProcessor
- 如果想对Bean进行自定义处理,可以让Bean实现BeanPostProcessor接口,那将调用postProcessBeforeInitialization(Object obj, String s)方法
- InitializingBean 与 init-method
- 如果Bean在Spring配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法
- DisposableBean
- 当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法
- destroy-method
- 如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法
设计模式
- 工厂模式
- BeanFactory,用来创建对象的实例
- 单例模式
- Bean默认为单例模式
- 代理模式
- AOP用到了JDK动态代理和CGLIB字节码生成技术
Spring事务
- 编程式事务
- 在代码中调用beginTransaction()、commit()、rollback()等事务管理相关的方法
- 声明式事务
- 通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中;不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明或通过@Transactional注解的方式,便可以将事务规则应用到业务逻辑中
- 基于AspectJ的XML的声明式事务管理,不需要改动类,在XML文件中配置好即可
- 基于注解的声明式事务管理,配置简单,需要在业务层类中添加注解
- 事务的传播行为
- PROPAGATION_REQUIRED:如果有事务, 那么加入事务, 没有的话新建一个事务(默认)
- PROPAGATION_SUPPORTS:支持当前事务,如果当前不存在事务,就以非事务执行
- PROPAGATION_MANDATORY:支持当前事务,如果当前不存在事务,就抛出异常
- PROPAGATION_REQUIRES_NEW:无论当前存不存在事务,都创建新事务
- PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
- PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常
- PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行
- 事务的隔离级别
- ISOLATION_DEFAULT:这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别
- ISOLATION_READ_UNCOMMITTED:读未提交,允许另外一个事务可以看到这个事务未提交的数据
- ISOLATION_READ_COMMITTED:读已提交,保证一个事务修改的数据提交后才能被另一事务读取,而且能看到该事务对已有记录的更新
- ISOLATION_REPEATABLE_READ:可重复读,保证一个事务修改的数据提交后才能被另一事务读取,但是不能看到该事务对已有记录的更新
- ISOLATION_SERIALIZABLE:一个事务在执行的过程中完全看不到其他事务对数据库所做的更新