Spring面试题

1、Spring bean的几种定义方式

1)声明式:基于XML的方式

    <bean id="user" class="com.test.User"/>

2)声明式:基于@Component注解

@Component
public class User {}

3)声明式:基于@Bean注解

@Component
public class Config { 
    @Bean
    public User user() {
         return new User();
     }
}

4)编程式:通过BeanDefinition注册bean信息

public class Test{

    public static void main (String[] args) {
          DefaultListableBeanFactory context = new DefaultListableBeanFactory();

          //构造bean定义
          BeanDefinition bd = new GenericBeanDefinition();
          gbd.setBeanClass(User.class);
          context.registerBeanDefinition("user", bd);

          User user = context.getBean(User.class);
      }
}

5)使用FactoryBean创建实例

public class Test implements FactoryBean<User> {
    public Color getObject() throws Exception {
        return new User();
    }
    public Class<?> getObjectType() {
        return User.class;
    }
    public boolean isSingleton() {
        return true;
    }
}

2、Spring bean的生命周期

Spring Bean的生命周期有四大步骤:实例化 -> 属性赋值 ->初始化 ->销毁

1、实例化前后是InstantiationAwareBeanPostProcessor的before和after方法

2、属性赋值后会执行各种Aware接口、InitializingBean的afterPropertiesSet和自定义的init-method

3、初始化前后是BeanPostProcessor的before和after方法(这里 的before方法是在Aware接口后面执行)

4、销毁时执行Disposable的destroy方法和自定义的destroy-method方法

生命周期中主要的接口和方法:

(1) Bean级别的接口

     Bean类中定义的方法或者实现了接口的方法,即init-method和destroy-method指定的方法,还有实现了BeanNameAware,BeanFactoryAware,InitializingBean,DiposableBean等接口的方法。

(2) 容器全局后处理器接口

     包括了BeanFactoryPostProcessor,InstantiationAwareBeanPostProcessor,BeanPostProcessor这两个接口,它们是容器全局级别的接口。

 

 

 

3、Spring bean的循环依赖

循环依赖:A 依赖 B,B 依赖 A

 Spring的单例对象的初始化主要分为三步: 
bean初始化

 

一级缓存 singletonObjects:存放已初始化完毕的bean对象

二级缓存 earlySingletonObjects :存放bean的代理对象(如不需要代理,则直接存放原始对象)

三级缓存 singletonFactories :存放通过构造器实例出来的原始对象

@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 从一级缓存缓存加载bean
    Object singletonObject = this.singletonObjects.get(beanName);
    // 缓存中的bean为空,且当前bean正在创建(说明存在循环引用)
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        // 加锁
        synchronized (this.singletonObjects) {
            // 从二级缓存中获取(如果二级缓存获取到直接返回)
            singletonObject = this.earlySingletonObjects.get(beanName);
            // 缓存中中没有,且允许提前创建(allowEarlyReference说明需要AOP代理,需提前创建好代理对象放到二级缓存中)
            if (singletonObject == null && allowEarlyReference) {
                // 从三级缓存中获取对应的ObjectFactory(从三级缓存中获取原始对象作为代理对象的target)
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    //从单例工厂中获取bean
                    singletonObject = singletonFactory.getObject();
                    // 添加到二级缓存
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    // 从三级缓存中删除
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}

 

 

 

 

参考:https://www.cnblogs.com/weiqihome/p/12359641.html

 

作者:月伴飞鱼
链接:https://www.zhihu.com/question/276741767/answer/1192059681
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

posted @ 2022-01-23 18:38  安小  阅读(49)  评论(0编辑  收藏  举报