spring面试题汇总

1.Spring 中,有两个 id 相同的 bean,会报错吗,如果会报错,在哪个阶段报错?

    首先,在同一个XML配置文件里面,不能存在id相同的两个bean,否则spring容器启动的时候会报错。

   因为id这个属性表示一个Bean的唯一标志符号,所以Spring在启动的时候会去验证id的唯一性,一旦发现重复就会报错,

这个错误发生Spring对XML文件进行解析转化为BeanDefinition的阶段。

但是在两个不同的Spring配置文件里面,可以存在id相同的两个bean。 IOC容器在加载Bean的时候,默认会多个相同id的bean进行覆盖。

  在Spring3.x版本以后,这个问题发生了变化

我们知道Spring3.x里面提供@Configuration注解去声明一个配置类,然后使用@Bean注解实现Bean的声明,这种方式完全取代了XMl。

在这种情况下,如果我们在同一个配置类里面声明多个相同名字的bean,在Spring IOC容器中只会注册第一个声明的Bean的实例。

后续重复名字的Bean就不会再注册了。

存储时使用beanName作为key,内容作为value存储在Map中。流程:没有得时候进行实例化bean,存在场景下获取一下map,不在进行bean生命周期创建。

2.Spring ioc

    spring得ioc机制和aop机制算是核心,在面试过程中还是含含糊糊,特此整理。

    IOC全名inversion of controller 控制反转,

控制反转如何理解?

        主要是 bean 的创建、管理的权利,控制 bean 的整个生命周期。把这个权利交给了 Spring 容器,而不是自己去控制,就是反转。由之前的自己主动创建对象,变成现在被动接收别人给我们的对象的过程,这就是反转。

这样做得好处是什么?

      降低了业务对象之间的复杂性,让组件之间互相解耦

       ioc最重要得就是容器, 那么 Spring 如何设计容器的呢?

         使用 ApplicationContext,它是 BeanFactory 的子类,更好的补充并实现了 BeanFactory 的。

    BeanFactory 简单粗暴,可以理解为 HashMap:

  •      Key - bean name

  •      Value - bean object

         但它一般只有 get, put 两个功能,所以称之为“低级容器”。

        而 ApplicationContext 多了很多功能,因为它继承了多个接口,可称之为“高级容器”。在下文的搭建项目中,我们会使用它。
        控制反转是通过依赖注入实现的,依赖倒置原则(即程序不应依赖于实现,而应依赖于抽象)是IoC的设计原理,依赖注入是IoC的实现方式。 

        通常我们所使用得xml,注解都是通过依赖注入这种进行实现得。

3.FactoryBean和BeanFactory得区别?

      BeanFactory的代码如下:

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";

    Object getBean(String var1) throws BeansException;

    <T> T getBean(String var1, Class<T> var2) throws BeansException;

    Object getBean(String var1, Object... var2) throws BeansException;

    <T> T getBean(Class<T> var1) throws BeansException;

    <T> T getBean(Class<T> var1, Object... var2) throws BeansException;

    <T> ObjectProvider<T> getBeanProvider(Class<T> var1);

    <T> ObjectProvider<T> getBeanProvider(ResolvableType var1);

    boolean containsBean(String var1);

    boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;

    boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;

    @Nullable
    Class<?> getType(String var1) throws NoSuchBeanDefinitionException;

    @Nullable
    Class<?> getType(String var1, boolean var2) throws NoSuchBeanDefinitionException;

    String[] getAliases(String var1);
}

      

        FactoryBean的代码如下:

       

public interface FactoryBean<T> {
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

    @Nullable
    T getObject() throws Exception;

    @Nullable
    Class<?> getObjectType();

    default boolean isSingleton() {
        return true;
    }
}

     3.1区别        

         

1.作用不同

BeanFactory是Spring框架的基础设施,是IOC容器,它是用于管理bean的工厂容器。BeanFactory加载配置文件时不会初始化bean,而是在获取bean的时候才会初始化bean,而是在获取bean的实惠才会去实例化对象。BeanFactory只提供了基础的功能,如获取bean、检测bean、管理bean的生命周期等。

FactoryBean是一个bean,可以实现自己的逻辑去创建其他bean对象,是一个专门的工厂。FactoryBean的作用是在BeanFactory或者ApplicationContext获取其他bean之前进行额外的处理,例如:在获取某个bean之前需要进行一些特殊的计算或者加工操作。

2.返回值不同

BeanFactory获取的是bean的实例对象

FactoryBean获取的是FactoryBean本身的实例对象,也就是调用FactoryBean#getObject()方法后返回的对象。需要通过FactoryBean#getObject()方法获取FactoryBean中创建出来的bean实例对象。

3.配置不同

BeanFactory配置只需要在XML文件定义即可,可以通过ClassPathXmlApplicationContext、FileSystemXmlApplicationContext等来加载运行时资源。

FactoryBean配置时应当将自定义工厂定义为Spring容器中的一个普通bean,并且在该对象上指定FactoryBean的实现类路径,由Spring容器创建并管理。

4.生命周期不同

BeanFactory和ApplicationContext在容器启动时都会将所有单例bean预先实例化。当从BeanFactory中获取单例bean时,它们才会被实例化并放入BeanFactory中,这就意味着在使用者第一次调用之前,它们是不存在的。因此,BeanFactory对象只会一次性调用所有bean的初始化方法。

FactoryBean可以实现Bean的生命周期接口,从而改变Bean的初始化和销毁过程。

总结:如果只是想获取单例的bean对象,可以使用BeanFactory;如果需要在获取单例的bean前或根据不同情况获取不同的实例化对象,则需要使用FactoryBean。

4.Spring Aop

     aop(Aspect Orient Programming)面向切面编程。作为面向对象得补充。

      用于处理系统中分布于各个模块的横切关注点,比如事务管理、日志、缓存等等。AOP实现的关键在于AOP框架自动创建的AOP代理,AOP代理主要分为静态代理和动态代理,静态代理的代表为AspectJ;而动态代理则以Spring AOP为代表。

    目的:代码解耦,代码复用,并有利于可操作性和可维护性。

    核心思想:对目标对象得增强。

   Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

   Spring AOP中的动态代理主要有两种方式,JDK动态代理(用于接口类)和CGLIB动态代理(不是接口类)。

    JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口(Invocation翻译成调用,即调用handler)和Proxy类。

 Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

  5.spring bean加载过程?

         面试回答:spring 得bean加载过程分为2步,实例化和初始化,销毁。

        实例化:在堆空间申请一块内存,默认得属性值都是默认值(防止内存再分配)

        初始化:

            (1)属性赋值 1.如果bean得属性有@Autowired要注入得属性,则会进行属性填充

                                     2.进行属性填充的前提是要保证属性实例已经存在spring容器中,如果不存在会去先加载属性

            (2)调用执行aware接口的方法 调用invokeAwareMethods方法:2.1 实现BeanNameAware接口调用setBeanName方法 2.2实现BeanClassLoaderAware接口,调用setBeanClassLoader方法 2.3实现BeanFactoryAware接口实现setBeanFactory方法。(aware接口是可识别的,可意识的,让bean意识到有spring的存在)

             (3)执行BeanPostProcessor的前置方法 (Processor代表处理器的意思)

             (4)执行init-method方法

              (5)执行BeanPostProcessor的后置方法

6.bean扩展点?

        1.实现Aware接口 实现BeanNameAware接口的setBeanName方法

                                     实现BeanClassLoaderAware接口的setClassLoader方法

                                    实现BeanFactoryAware接口的setBeanFactory方法

         2.实现InitializingBean 和 DisposableBean 接口

        如果要在 Bean 初始化时添加自定义逻辑,可以实现 InitializingBean 接口。实现afterPropertiesSet方法        

        如果要在 Bean 销毁时添加自定义逻辑,可以实现 DisposableBean 接口。实现destory方法

        或者使用init-method注解,实现init方法和destory方法。

        3.实现BeanPostProcessor接口,实现postProcessBeaforeInitialization方法和postProcessAfterInitialization方法

7.SpringMVC请求处理过程?

            

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值