美文网首页
spring面试题

spring面试题

作者: kingTao_ | 来源:发表于2020-08-06 14:36 被阅读0次

    SpringAop和AspectJ区别

    1.Spring AOP是属于运行时增强,而AspectJ是编译时增强。Spring AOP基于代理(Proxying),而AspectJ基于字节码操作(Bytecode Manipulation)

    2.Spring AOP已经集成了AspectJ,AspectJ应该算得上是Java生态系统中最完整的AOP框架了。AspectJ相比于Spring AOP功能更加强大,但是Spring AOP相对来说更简单。

    3.如果我们的切面比较少,那么两者性能差异不大。但是,当切面太多的话,最好选择AspectJ,它比SpringAOP快很多。

    SpringBean的作用域有哪些

    1.<B>singleton</B>:唯一bean实例,Spring中的bean默认都是单例的。

    2.<B>prototype</B>:每次请求都会创建一个新的bean实例。

    3.<B>request</B>:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。

    4.<B>session</B>:每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP session内有效。

    5.global-session:全局session作用域,仅仅在基于Portlet的Web应用中才有意义,Spring5中已经没有了。Portlet是能够生成语义代码(例如HTML)片段的小型Java Web插件。它们基于Portlet容器,可以像Servlet一样处理HTTP请求。但是与Servlet不同,每个Portlet都有不同的会话。

    SpringMVC工作原理

    1.客户端(浏览器)发送请求,直接请求到DispatcherServlet。

    2.DispatcherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler。

    3.解析到对应的Handler(也就是我们平常说的Controller控制器)。

    4.HandlerAdapter会根据Handler来调用真正的处理器来处理请求和执行相对应的业务逻辑。

    5.处理器处理完业务后,会返回一个ModelAndView对象,Model是返回的数据对象,View是逻辑上的View。

    6.ViewResolver会根据逻辑View去查找实际的View。

    7.DispatcherServlet把返回的Model传给View(视图渲染)。

    8.把View返回给请求者(浏览器)。

    Spring中用到了哪些涉及模式

    1.工厂设计模式:Spring使用工厂模式通过BeanFactory和ApplicationContext创建bean对象。

    2.代理设计模式:Spring AOP功能的实现。

    3.单例设计模式:Spring中的bean默认都是单例的。

    4.模板方法模式:Spring中的jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类,它们就使用到了模板模式。

    5.包装器设计模式:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。

    6.观察者模式:Spring事件驱动模型就是观察者模式很经典的一个应用。

    7.适配器模式:Spring AOP的增强或通知(Advice)使用到了适配器模式、Spring MVC中也是用到了适配器模式适配Controller。

    @Component和@Bean的区别是什么

    1.作用对象不同。@Component注解作用于类,而@Bean注解作用于方法。

    2.@Component注解通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中(我们可以使用@ComponentScan注解定义要扫描的路径)。@Bean注解通常是在标有该注解的方法中定义产生这个bean,告诉Spring这是某个类的实例,当我需要用它的时候还给我。

    3.@Bean注解比@Component注解的自定义性更强,而且很多地方只能通过@Bean注解来注册bean。比如当引用第三方库的类需要装配到Spring容器的时候,就只能通过@Bean注解来实现。

    Spring标记一个类为Bean的注解有哪些

    我们一般使用@Autowired注解去自动装配bean。而想要把一个类标识为可以用@Autowired注解自动装配的bean,可以采用以下的注解实现:

    1.<B>@Component</B>注解。通用的注解,可标注任意类为Spring组件。如果一个Bean不知道属于哪一个层,可以使用@Component注解标注。

    2.<B>@Repository</B>注解。对应持久层,即Dao层,主要用于数据库相关操作。

    3.<B>@Service</B>注解。对应服务层,即Service层,主要涉及一些复杂的逻辑,需要用到Dao层(注入)。

    4.<B>@Controller</B>注解。对应Spring MVC的控制层,即Controller层,主要用于接受用户请求并调用Service层的方法返回数据给前端页面。

    Spring管理事务的方式有几种

    1.编程式事务:在代码中硬编码(不推荐使用)。

    2.声明式事务:在配置文件中配置(推荐使用),分为基于XML的声明式事务和基于注解的声明式事务。

    Spring的事务隔离级别有哪几种

    在TransactionDefinition中定义了五个事务隔离级别

    <B>ISOLATION_DEFAULT</B> 使用后端数据库默认的隔离级别,Mysql默认采用的REPEATABLE_READ隔离级别;Oracle默认采用的READ_COMMITTED隔离级别。

    <B>ISOLATION_READ_UNCOMMITED</B> 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读

    <B>ISOLATION_READ_COMMITED</B> 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生

    <B>ISOLATION_REPEATABLE_READ</B> 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

    <B>ISOLATION_SERIALIZABLE</B> 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

    Spring事务的传播行为

    在TransactionDefinition接口中定义了八个表示事务传播行为的常量

    支持当前事务的情况:默认 PROPAGATION_REQUIRED

    <B>PROPAGATION_REQUIRED</B> 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。

    <B>PROPAGATION_SUPPORTS</B> 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

    <B>PROPAGATION_MANDATORY</B> 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)

    不支持当前事务的情况:

    <B>PROPAGATION_REQUEIRED_NEW</B> 创建一个新的事务,如果当前存在事务,则把当前事务挂起。

    <B>PROPAGATION_NOT_SUPPORTS</B> 以非事务方式运行,如果当前存在事务,则把当前事务挂起。

    <B>PROPAGATION_NEVER</B> 以非事务方式运行,如果当前存在事务,则抛出异常

    <B>PROPAGATION_NESTED</B> 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于PROPAGATION_REQUIRED。

    使用示例

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void insert(){}
    

    BeanFactory和FactoryBean是什么,有什么区别

    1、 BeanFactory
    BeanFactory定义了 IOC 容器的最基本形式,并提供了 IOC 容器应遵守的的最基本的接口,也就是 Spring IOC 所遵守的最底层和最基本的编程规范。在 Spring 代码中, BeanFactory 只是个接口,并不是 IOC 容器的具体实现,但是 Spring 容器给出了很多种实现,如 DefaultListableBeanFactory 、 XmlBeanFactory 、 ApplicationContext 等,都是附加了某种功能的实现。

    ackage org.springframework.beans.factory;  
    import org.springframework.beans.BeansException;  
    public interface BeanFactory {  
        String FACTORY_BEAN_PREFIX = "&";  
        Object getBean(String name) throws BeansException;  
        <T> T getBean(String name, Class<T> requiredType) throws BeansException;  
        <T> T getBean(Class<T> requiredType) throws BeansException;  
        Object getBean(String name, Object... args) throws BeansException;  
        boolean containsBean(String name);  
        boolean isSingleton(String name) throws NoSuchBeanDefinitionException;  
        boolean isPrototype(String name) throws NoSuchBeanDefinitionException;  
        boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;  
        Class<?> getType(String name) throws NoSuchBeanDefinitionException;  
        String[] getAliases(String name);  
    } 
    

    2、 FactoryBean

    一般情况下,Spring 通过反射机制利用 <bean> 的 class 属性指定实现类实例化 Bean ,在某些情况下,实例化 Bean 过程比较复杂,如果按照传统的方式,则需要在 <bean> 中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。 Spring 为此提供了一个 org.springframework.bean.factory.FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 Bean 的逻辑。

    FactoryBean接口对于 Spring 框架来说占用重要的地位, Spring 自身就提供了 70 多个 FactoryBean 的实现。它们隐藏了实例化一些复杂 Bean 的细节,给上层应用带来了便利。从 Spring 3.0 开始, FactoryBean 开始支持泛型,即接口声明改为 FactoryBean<T> 的形式:

    package org.springframework.beans.factory;  
    public interface FactoryBean<T> {  
        T getObject() throws Exception;  
        Class<?> getObjectType();  
        boolean isSingleton();  
    } 
    

    在该接口中还定义了以下3 个方法:

    T getObject():返回由 FactoryBean 创建的 Bean 实例,如果 isSingleton() 返回 true ,则该实例会放到 Spring 容器中单实例缓存池中;

    boolean isSingleton():返回由 FactoryBean 创建的 Bean 实例的作用域是 singleton 还是 prototype ;

    Class<T> getObjectType():返回 FactoryBean 创建的 Bean 类型。

    当配置文件中<bean> 的 class 属性配置的实现类是 FactoryBean 时,通过 getBean() 方法返回的不是 FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的对象,相当于 FactoryBean#getObject() 代理了 getBean() 方法。

    例:如果使用传统方式配置下面Cat 的 <bean> 时, Cat 的每个属性分别对应一个 <property> 元素标签。

    package  com.kingtao.factorybean;  
    public   class  Cat  {  
        private   int color ;  
        private  String age ;  
        private   double price ;  
        public   int  getColor ()   {  
            return   this . color ;  
        }  
        public   void  setColor ( int  color )   {  
            this . color  = color;  
        }  
        public  String getAge ()   {  
            return   this .age ;  
        }  
        public   void  setBrand ( String age
            this . age  = age;  
        }  
        public   double  getPrice ()   {  
            return   this . price ;  
        }  
        public   void  setPrice ( double  price )   {  
            this . price  = price;  
       }  
    

    }

    如果用FactoryBean 的方式实现就灵活点,下例通过逗号分割符的方式一次性的为 Cat 的所有属性指定配置值:

    package  com.kingtao.factorybean;  
    import  org.springframework.beans.factory.FactoryBean;  
    public   class  CatFactoryBean  implements  FactoryBean<Cat>  {  
        private  String catInfo ;  
        public  Cat getObject ()   throws  Exception  {  
            Cat cat =  new  Cat () ;  
            String []  infos =  catInfo .split ( "," ) ;  
            cat.setCOlor ( infos [ 0 ]) ;  
            cat.setAge ( Integer. valueOf ( infos [ 1 ])) ;  
            cat.setPrice ( Double. valueOf ( infos [ 2 ])) ;  
            return  cat;  
        }  
        public  Class<Cat> getObjectType ()   {  
            return  Cat. class ;  
        }  
        public   boolean  isSingleton ()   {  
            return   false ;  
        }  
        public  String getCatInfo ()   {  
            return   this . catInfo ;  
        }  
      
        // 接受逗号分割符设置属性信息  
        public   void  setCatInfo ( String catnfo )   {  
            this . catInfo  = catInfo;  
        }  
    }   
    

    有了这个CatrFactoryBean 后,就可以在配置文件中使用下面这种自定义的配置方式配置 Cat Bean 了:

    <bean id="cat" class="com.kingtao.factorybean.CatFactoryBean"

    P:catInfo="yellow ,2,2000000"/>
    

    当调用getBean("cat") 时, Spring 通过反射机制发现 CatFactoryBean 实现了 FactoryBean 的接口,这时 Spring 容器就调用接口方法 CatFactoryBean#getObject() 方法返回。如果希望获取 CatFactoryBean 的实例,则需要在使用 getBean(beanName) 方法时在 beanName 前显示的加上 "&" 前缀:如 getBean("&cat");

    3、 区别

    BeanFactory是个 Factory ,也就是 IOC 容器或对象工厂, FactoryBean 是个 Bean 。在 Spring 中,所有的 Bean 都是由 BeanFactory( 也就是 IOC 容器 ) 来进行管理的。但对 FactoryBean 而言,这个 Bean 不是简单的 Bean ,而是一个能生产或者修饰对象生成的工厂 Bean, 它的实现与设计模式中的工厂模式和修饰器模式类似。

    相关文章

      网友评论

          本文标题:spring面试题

          本文链接:https://www.haomeiwen.com/subject/oowzrktx.html