【转】java 开发之 spring 面试题
1、谈谈对 IOC 的理解?
IOC,就是我们经常所说的控制反转,DI,就是依赖注入,这两个是对同一个事物从不同角度的解释。没有使用 spring 框架的时候,java培训我们需要使用一个对象,经常需要自己去手动 new,需要自己取管理对象。使用 spring 的 IOC 容器之后,对象交给 spring 的 IOC 容器管理,bean 的创建,初始化,结束,依赖注入等一系列,全部由 IOC 容器帮我们完成,我们在需要使用的时候,直接调用就行了。
2、多个 AOP 的顺序怎么定义
通过 Ordered 和 PriorityOrdered 接口进行排序。PriorityOrdered 接口的优先级比 Ordered 更高,如果同时实现 PriorityOrdered 或 Ordered 接口,则再按 order 值排序,值越小的优先级越高。
3、springBean 是线程安全的吗?
结论:Bean 是线程不安全的
Spring 容器中的 Bean 是否线程安全,容器本身并没有提供对 Bean 的线程安全策略,因此可以说 Spring 的 Bean 本身不具备线程安全的特性。
如果 Bean 是无状态的,那么 Bean 则是线程安全的
如果 Bean 是有状态的,那么 Bean 就不是线程安全的
另外,Bean 是不是线程安全,跟 Bean 的作用域没有关系,Bean 的作用域只是表示 Bean 的生命周期范围,对于任何生命周期 Bean 都是一个对象,这个对象是不是线程安全的,还是得看 Bean 里的这个对象本身
4、Spring 中的 bean 生命周期?
Bean 容器找到配置文件中 Spring Bean 的定义。
Bean 容器利用 Java Reflection API 创建一个 Bean 的实例。
如果涉及到一些属性值,利用 set()方法设置一些属性值。
如果 Bean 实现了 BeanNameAware 接口,调用 setBeanName()方法,传入 Bean 的名字。
如果 Bean 实现了 BeanClassLoaderAware 接口,调用 setBeanClassLoader()方法,传入 ClassLoader 对象的实例。
如果 Bean 实现了 BeanFactoryAware 接口,调用 setBeanClassFacotory()方法,传入 ClassLoader 对象的实例。
与上面的类似,如果实现了其他*Aware 接口,就调用相应的方法。
如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行 postProcessBeforeInitialization()方法。
如果 Bean 实现了 InitializingBean 接口,执行 afeterPropertiesSet()方法。
如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。
如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcess 对象,执行 postProcessAfterInitialization()方法。
当要销毁 Bean 的时候,如果 Bean 实现了 DisposableBean 接口,执行 destroy()方法。
当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法。
5、Spring 框架中都用到了哪些设计模式?
工厂模式:BeanFactory 就是简单工厂模式的体现,用来创建对象的实例;
单例模式:Bean 默认为单例模式。
代理模式:Spring 的 AOP 功能用到了 JDK 的动态代理和 CGLIB 字节码生成技术;
模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。
观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如 Spring 中 listener 的实现–ApplicationListener。
6、@Autowired 和 @Resource 之间的区别
@Autowired 可用于:构造函数、成员变量、Setter 方法
@Autowired 和 @Resource 之间的区别
@Autowired 默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它 required 属性为 false)。
@Resource 默认是按照名称来装配注入的,只有当找不到与名称匹配的 bean 才会按照类型来装配注入。
7、Spring 支持的事务管理类型?
Spring 支持两种类型的事务管理:
编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和 XML 配置来管理事务。
8、你更倾向用那种事务管理类型?
大多数 Spring 框架的用户选择声明式事务管理,因为它对应用代码的影响最小,因此更符合一个无侵入的轻量级容器的思想。声明式事务管理要优于编程式事务管理,虽然比编程式事务管理(这种方式允许你通过代码控制事务)少了一点灵活性。唯一不足地方是,最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。
9、Spring 事务中有哪几种事务传播行为?
在 TransactionDefinition 接口中定义了八个表示事务传播行为的常量。
支持当前事务的情况:
PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)。
不支持当前事务的情况:
PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
其他情况:
PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 PROPAGATION_REQUIRED。
10、Spring 通知有哪些类型?
在 AOP 术语中,切面的工作被称为通知,实际上是程序执行时要通过 SpringAOP 框架触发的代码段。
Spring 切面可以应用 5 种类型的通知:
前置通知(Before):在目标方法被调用之前调用通知功能;
后置通知(After):在目标方法完成之后调用通知,此时不会关心方法的输出是什么;
返回通知(After-returning ):在目标方法成功执行之后调用通知;
异常通知(After-throwing):在目标方法抛出异常后调用通知;
环绕通知(Around):通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为。
原创作者:老约翰
评论