Spring
bean的生命周期
循环依赖问题
spring cloud(如项目中有用过)
AOP的实现
AOP (Aspect Orient Programming),一般称为面向切面编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理、日志、缓存等等。AOP 实现的关键在于 AOP 框架自动创建的 AOP 代理,AOP 代理主要分为静态代理和动态代理。静态代理的代表为Aspectj,动态代理则以 Spring AOP 为代表。静态代理是编译期实现的,动态代理是运行期实现的。
在目标对象(target object)的某些方法(jointpoint)添加不同种类的操作(通知、增强操处理),最后通过某些方法(weaving、织入操作)实现一个新的代理目标对象。
Spring AOP 中的动态代理主要有两种方式,JDK 动态代理和 CGLIB 动态代理。JDK 动态代理通过反射来接受被代理的类,并且要求被代理的类必须实现一个接口。JDK 动态代理的核心是 InvocationHandler 接口和 Proxy 类。
如果目标没有实现接口,那么Spring AOP 会选择使用 CGLIB 来动态代理目标类。CGLIB(Code Generration Library)是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为 finnal,那么它是无法使用 CGLIB 做动态代理的,诸如 private 方法也是不可以作为切面的。
spring事务传播
TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。
TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED
常见问题
- java动态代理和cglib动态代理的区别(经常结合spring一起问所以就放这里了)
1. JDK动态代理只能对实现了接口的类生成代理,而不能针对类 ,使用的是 Java反射技术实现,生成类的过程比较高效。
2. CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 ,使用asm字节码框架实现,相关执行的过程比较高效,生成类的过程可以利用缓存弥补,因为是继承,所以该类或方法最好不要声明成final
3. JDK代理是不需要第三方库支持,只需要JDK环境就可以进行代理,使用条件:
实现InvocationHandler
使用Proxy.newProxyInstance产生代理对象
被代理的对象必须要实现接口
4. CGLib必须依赖于CGLib的类库,但是它需要类来实现任何接口代理的是指定的类生成一个子类,覆盖其中的方法,是一种继承但是针对接口编程的环境下推荐使用JDK的代理;
- spring中bean的生命周期是怎样的?
分为四个阶段。第一阶段:Bean的实例化,在该阶段主要是Bean的实例化。第二阶段是Bean的初始化,包括初始化方法和属性的填充。第三阶段是Bean的使用。第四阶段是Bean的销毁,该阶段是调用destroy方法等
Spring首先会调用BeanFactoryPostProcessor的postProcessBeanFactory方法,后初始化Bean(是通过反射机制调用其构造方法),有了对象后,开始属性的注入,注入属性之后,如果你这个Bean实现了Spring中相关的XXXaware接口,比如说:BeanNameAware,BeanFactoryAware,ApplicationContextAware来获取相关的对象,这一阶段是在Bean的实例化中操作的。
接下来,进入Bean的初始化阶段,首先会调用BeanPostProcess的前置处理(预初始化方法),后在调用初始化方法即InitlalizingBean的afterPropertiesSet方法,完成之后,调用自定义的init-method指定方法,最后调用BeanPostProcess的后置处理(与初始化后的方法)。
Bean的使用:其实是业务逻辑操作Bean的过程。
最后是Bean的销毁:该阶段销毁有两次销毁。一次是DisposableBean的Destroy的方法,后才调用destroy-method指定的方法。
- 属性注入和构造器注入哪种会有循环依赖的问题?
Spring中依赖注入的方式有两种,属性注入与构造器注入
如果循环依赖的bean都是通过构造器注入依赖,那么不管它们是singleton还是prototype,都会失败。
如果循环依赖的bean都是prototype,那么不管它们是通过构造器注入依赖还是通过属性注入依赖,都会失败。
如果循环依赖的bean既有构造器注入也有属性注入,既有singleton也有prototype,在容器启动后,只有当获取的第一个bean是通过属性注入依赖的singleton时,才会成功,别的情况都会失败。
- Mybatis的mapper代理,分页插件的代理实现