java面试常见问题

spring:

1、spring的@configration与@bean和@component其他注解的区别?

  • @configration是通过cglib的代理产生对象。(cglib的代理通过集成代理类,并注入beanFactory获取对象。)
  • @configration确保产生对象的单例性。
  • @componet调用创建类中的构造方法,创建实例,与普通创建实例一样。(就是new一个实例)
  • @Component注解表明一个类会作为组件类,并告知Spring要为这个类创建bean。
  • @Bean注解告诉Spring这个方法将会返回一个对象,这个对象要注册为Spring应用上下文中的bean。通常方法体中包含了最终产生bean实例的逻辑。
public class WireThirdLibClass {
    @Bean
    public ThirdLibClass getThirdLibClass() {
        return new ThirdLibClass();
    }
}

2、spring的生命周期和作用于?

Spring框架中Bean的5个作用域

  • singleton单例:是spring默认缺省的,全局只有一个对象。
  • prototype原型:每次都是新的Bean实例,有状态的Bean建议用此类型。相当于new 实例。
  • request:一次Http请求中,容器返回同一实例Bean,仅在当前Http Request内有效
  • session:一次Http Session中,容器返回同一实例Bean,仅在当前Session内有效。
  • global session:一个全局的Http Session中,容器返回同一个实例Bean。

spring的生命周期
Spring容器可以管理singleton作用域下Bean的生命周期,在此作用域下,Spring能够精确地知道Bean何时被创建,何时初始化完成,以及何时被销毁。而对于prototype作用域的Bean,Spring只负责创建,当容器创建了Bean的实例后,Bean的实例就交给了客户端的代码管理,Spring容器将不再跟踪其生命周期,并且不会管理那些被配置成prototype作用域的Bean的生命周期。
1.Spring对Bean进行实例化(默认是单例)
2.Spring对Bean进行依赖注入(常用Setter)
3.如果bean视线里BeanNameAware接口,则容器将bean的id传给setBeanName()方法
4.如果bean实现了BeanFactoryAware接口,则spring调用setBeanFactory()方法,将BeanFactory实例传递进来
5.如果bean实现了ApplicationContextAware接口,其setApplicationContext()将会调用,将上下文的引用传入bean
6.如果bean实现了BeanPostProcesser接口,其postProcessBeforeInitializaition方法将会被调用
7.如果bean实现了InitializingBean接口,spring将调用它的afterPropertiesSet接口方法,类似的如果bean使用了init-method属性声明了初始化方法,该方法也会被调用;
8.如果bean实现了BeanPostProcessor接口,它的postProcessAfterInitialization接口方法将被调用;
9.此时bean已经准备就绪,可以被应用程序使用了,他们将一直驻留在应用上下文中,直到该应用上下文被销毁;
10.若bean实现了DisposableBean接口,spring将调用它的distroy()接口方法。同样的,如果bean使用了destroy-method属性声明了销毁方法,则该方法被调用;
3、Spring单例bean与线程安全?
Spring使用ThreadLocal解决线程安全问题。
spring中bean分为有状态和无状态,只有有状态的bean才会有线程安全的问题。

  • 有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象,可以保存数据,是非线程安全的。

  • 无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象.不能保存数据,是不变类,是线程安全的。
    ThreadLocal会为每一个线程提供一个独立的“变量副本”,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

java线程同步的方法和什么情况下进行线程同步

ThreadLocal和线程同步机制(synchronized)都可以解决多线程中“相同变量”的访问冲突问题。

  • 线程同步机制(synchronized)通过“对象锁”,保证同一时间只有一个线程访问变量,让不同的线程排队访问。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。

  • ThreadLocal会为每一个线程提供一个独立的“变量副本”,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,这个全局变量是线程安全的。若有多个线程同时执行写操作,则需要考虑线程同步,否则就可能影响线程安全。
① 常量始终是线程安全的,因为只存在读操作。
② 每次调用方法前都新建一个实例是线程安全的,因为不会访问共享的资源。
③ 局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量和方法内变量。

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读