• java框架


    框架面试题:(5条消息) java框架常见的面试题_wy_0830的博客-CSDN博客_java框架面试题

    1、springbean 生命周期及作用域

    作用域:5个 singleton  protype  request  session  globalsession

    • singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例

    • prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例

    • request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效

    • session:对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效

    • globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效

    生命周期

     bean创建、使用、销毁

    详细过程:

     IOC与DI:

    所以控制反转IOC(Inversion of Control)是说创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己把控的,而现在这种权力转移到第三方,比如转移交给了IOC容器,它就是一个专门用来创建对象的工厂,你要什么对象,它就给你什么对象,有了 IOC容器,依赖关系就变了,原先的依赖关系就没了,它们都依赖IOC容器了,通过IOC容器来建立它们之间的关系。
      DI(依赖注入)其实就是IOC的另外一种说法,DI是由Martin Fowler 在2004年初的一篇论文中首次提出的。他总结道:控制的什么被反转了?就是获得依赖对象的方式反转了。

    注入方式:

    1、构造器注入

    2、set方法注入

    3、p名称空间注入 (5条消息) Spring IOC p名称空间的使用-了解_苏凯的博客-CSDN博客

    4、静态工厂,实例工厂注入。 (5条消息) spring--静态工厂方法和实例工厂方法注入_江春c的博客-CSDN博客_spring 工厂方法注入

    BeanFactory与ApplicationContext:

    BeanFactory:是IOC容器的核心接口, 它定义了IOC的基本功能,我们看到它主要定义了getBean方法。getBean方法是IOC容器获取bean对象和引发依赖注入的起点。方法的功能是返回特定的名称的Bean。

    BeanFactory 是初始化 Bean 和调用它们生命周期方法的“吃苦耐劳者”。注意,BeanFactory 只能管理单例(Singleton)Bean 的生命周期。它不能管理原型(prototype,非单例)Bean 的生命周期。这是因为原型 Bean 实例被创建之后便被传给了客户端,容器失去了对它们的引用。

    BeanFactorty接口提供了配置框架及基本功能,但是无法支持spring的aop功能和web应用。而ApplicationContext接口作为BeanFactory的派生,因而提供BeanFactory所有的功能。而且ApplicationContext还在功能上做了扩展,相较于BeanFactorty,ApplicationContext还提供了以下的功能: 

    (1)MessageSource, 提供国际化的消息访问  
    (2)资源访问,如URL和文件  
    (3)事件传播特性,即支持aop特性
    (4)载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层 

    1.BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化,这样,我们就不能发现一些存在的Spring的配置问题。而ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。 相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。

    BeanFacotry延迟加载,如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常;而ApplicationContext则在初始化自身是检验,这样有利于检查所依赖属性是否注入;所以通常情况下我们选择使用 ApplicationContext。
    应用上下文则会在上下文启动后预载入所有的单实例Bean。通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。

    2.BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。(Applicationcontext比 beanFactory 加入了一些更好使用的功能。而且 beanFactory 的许多功能需要通过编程实现而 Applicationcontext 可以通过配置实现。比如后处理 bean , Applicationcontext 直接配置在配置文件即可而 beanFactory 这要在代码中显示的写出来才可以被容器识别。 )

    3.beanFactory主要是面对与 spring 框架的基础设施,面对 spring 自己。而 Applicationcontex 主要面对与 spring 使用的开发者。基本都会使用 Applicationcontex 并非 beanFactory 。

    SPringAOP失效的原因:

    spring aop使用动态代理,一旦失效,会导致@Transactional  @Caching @Async等基于aop实现的注解失效。

    1、当在动态代理方法中调用当前实例的 Transactional 或 Async 标记的方法时,注解不会生效;
    原因:在此条件下调用注解标记的方法相当于调用实例本身的方法 this.func(),此时不会通过 Spring Aop 的增强,所以注解不生效

    • 配置 <aop:aspectj-autoproxy expose-proxy="true" /> 暴露代理对象,Spring Boot 中可使用 @EnableAspectJAutoProxy(exposeProxy=true) 注解
    • 将方法中的 this.func() 调用修改为以下形式
    // 从AppContext中获取当前代理对象(ThreadLocal)
    Object proxy = AppContext.currentProxy;
    // 调用代理方法
    proxy.func();

    2、与shiro整合时常常需要在Realm中注入service,shiro加载很早,导致service类还没有执行代理就注入了,后续也不会再次创建service类,所以aop也失效了。改为@lazy即可。

    Spring事务的隔离级别,传播行为。

    SpringMVC

    1、执行流程

    (1)用户发送请求至前端控制器DispatcherServlet;
    (2) DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
    (3)处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
    (4)DispatcherServlet 调用 HandlerAdapter处理器适配器;
    (5)HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);
    (6)Handler执行完成返回ModelAndView;
    (7)HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
    (8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
    (9)ViewResolver解析后返回具体View;
    (10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
    (11)DispatcherServlet响应用户。

     

    3、Springmvc的优点:

    (1)可以支持各种视图技术,而不仅仅局限于JSP;

    (2)与Spring框架集成(如IoC容器、AOP等);

    (3)清晰的角色分配:前端控制器(dispatcherServlet) , 请求到处理器映射(handlerMapping), 处理器适配器(HandlerAdapter), 视图解析器(ViewResolver)。

    (4) 支持各种请求资源的映射策略。

    4、Spring MVC的主要组件?

    (1)前端控制器 DispatcherServlet(不需要程序员开发)

    作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。

    (2)处理器映射器HandlerMapping(不需要程序员开发)

    作用:根据请求的URL来查找Handler

    (3)处理器适配器HandlerAdapter

    注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。

    (4)处理器Handler(需要程序员开发)

    (5)视图解析器 ViewResolver(不需要程序员开发)

    作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view)

    (6)视图View(需要程序员开发jsp)

    View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)

    如何解决POST请求中文乱码问题,GET的又如何处理呢?

    (1)解决post请求乱码问题:

    在web.xml中配置一个CharacterEncodingFilter过滤器,设置成utf-8;

    <filter>

        <filter-name>CharacterEncodingFilter</filter-name>

        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

        <init-param>

            <param-name>encoding</param-name>

            <param-value>utf-8</param-value>

        </init-param>

    </filter>

    <filter-mapping>

        <filter-name>CharacterEncodingFilter</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

    (2)get请求中文参数出现乱码解决方法有两个:

    ①修改tomcat配置文件添加编码与工程编码一致,如下:

    <ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

     ②另外一种方法对参数进行重新编码:

    String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")

    ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码。

    Spring的自动装配:

    在spring中,对象无需自己查找或创建与其关联的其他对象,由容器负责把需要相互协作的对象引用赋予各个对象,使用autowire来配置自动装载模式。

    在Spring框架xml配置中共有5种自动装配:

    (1)no:默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean。

    (2)byName:通过bean的名称进行自动装配,如果一个bean的 property 与另一bean 的name 相同,就进行自动装配。 

    (3)byType:通过参数的数据类型进行自动装配。

    (4)constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配。

    (5)autodetect:自动探测,如果有构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配。

    基于注解的方式:

    使用@Autowired注解来自动装配指定的bean。在使用@Autowired注解之前需要在Spring配置文件进行配置,<context:annotation-config />。在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性。在使用@Autowired时,首先在容器中查询对应类型的bean:

    如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据;

    如果查询的结果不止一个,那么@Autowired会根据名称来查找;

    如果上述查找的结果为空,那么会抛出异常。解决方法时,使用required=false。

    @Autowired可用于:构造函数、成员变量、Setter方法

    注:@Autowired和@Resource之间的区别

    (1) @Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。

    (2) @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。

    Spring 框架中都用到了哪些设计模式?

    (1)工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;

    (2)单例模式:Bean默认为单例模式。

    (3)代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;

    (4)模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。

    (5)观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现--ApplicationListener。

    Spring事务的实现方式和实现原理:

    Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的

    Spring框架中有哪些不同类型的事件

    Spring 提供了以下5种标准的事件:

    (1)上下文更新事件(ContextRefreshedEvent):在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。

    (2)上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。

    (3)上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。

    (4)上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。

    (5)请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。

    如果一个bean实现了ApplicationListener接口,当一个ApplicationEvent 被发布以后,bean会自动被通知。

    解释一下Spring AOP里面的几个名词:

    (1)切面(Aspect):被抽取的公共模块,可能会横切多个对象。 在Spring AOP中,切面可以使用通用类(基于模式的风格) 或者在普通类中以 @AspectJ 注解来实现。

    (2)连接点(Join point):指方法,在Spring AOP中,一个连接点 总是 代表一个方法的执行。 

    (3)通知(Advice):在切面的某个特定的连接点(Join point)上执行的动作。通知有各种类型,其中包括“around”、“before”和“after”等通知。许多AOP框架,包括Spring,都是以拦截器做通知模型, 并维护一个以连接点为中心的拦截器链。

    (4)切入点(Pointcut):切入点是指 我们要对哪些Join point进行拦截的定义。通过切入点表达式,指定拦截的方法,比如指定拦截add*、search*。

    (5)引入(Introduction):(也被称为内部类型声明(inter-type declaration))。声明额外的方法或者某个类型的字段。Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象。例如,你可以使用一个引入来使bean实现 IsModified 接口,以便简化缓存机制。

    (6)目标对象(Target Object): 被一个或者多个切面(aspect)所通知(advise)的对象。也有人把它叫做 被通知(adviced) 对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个 被代理(proxied) 对象。

    (7)织入(Weaving):指把增强应用到目标对象来创建新的代理对象的过程。Spring是在运行时完成织入。

    切入点(pointcut)和连接点(join point)匹配的概念是AOP的关键,这使得AOP不同于其它仅仅提供拦截功能的旧技术。 切入点使得定位通知(advice)可独立于OO层次。 例如,一个提供声明式事务管理的around通知可以被应用到一组横跨多个对象中的方法上(例如服务层的所有业务操作)。

     AOP的通知

     BeanFactory与FactoryBean

    FactoryBean 是spirng提供的工厂bena的一个接口

    FactoryBean 接口提供三个方法,用来创建对象,
    FactoryBean 具体返回的对象是由getObject 方法决定的。

    BeanFactory是个bean 工厂,是一个工厂类(接口), 它负责生产和管理bean的一个工厂
    是ioc 容器最底层的接口,是个ioc容器,是spring用来管理和装配普通bean的ioc容器(这些bean成为普通bean)。

    FactoryBean是个bean,在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式,是一个可以生产对象和装饰对象的工厂bean,由spring管理后,生产的对象是由getObject()方法决定的(从容器中获取到的对象不是
    “ FactoryBeanTest ” 对象)。

    Spring启动流程
     
    在web中的监听器中,一共有6个监听器,监听器用于去监听web的域对象,包括ServletContext、HttpServletRequest
    、HttpSession这三个域对象。
    监听器也是需要在服务器中运行,所以也需要在web.xml中配置去交给服务器管理
    ServletContext:
    ServletContextListener
    作用:监听ServletContext对象的创建和销毁,在web应用加载或者服务器启动时创建,在web应用卸载或服务器停止时销毁
    ServletContextAttributeListener
    作用:对ServletContext对象里面的属性进行增删改功能
    ServletRequest:
    ServletRequestListener
    作用:监听request对象的创建和销毁,在用户发出请求时创建,在请求完毕后销毁
    ServletRequestAttributeListener
    作用:对request对象里面的属性进行增删改功能
    HttpSession:
    HttpSessionListener
    作用:监听session对象创建和销毁,在每个用户第一次调用request.getSession()方法时创建,销毁的方式有多种:默认等30分钟、设置等待的时间
    setMaxInactiveInteval(xxx)、在全局配置上配置等待时间<session-config><session-timeout></session-config>、还有就是手动销毁invalidate()
    HttpSessionAttributeListener

    作用:对session对象里面的属性增删改操作

    对于web程序,IOC容器启动过程即是建立上下文的过程,web容器会提供一个全局的servletContext上下文环境。

    其启动过程主要包含三个类,ContextLoaderListener,ContextLoader和XmlWebApplicationContext。

    在web.xml中提供ContextLoaderListener上下文监听器,在web容器启动时,会触发容器初始化事件,ContextLoaderListener会监听到这个事件,从而触发ContextInitialized方法完成上下文初始化,这个方法中调用父类ContextLoader的方法完成上下文初始化。ContextLoader类中主要完成三件事:1)创建WebApplicationContext;2)加载对应的Spring配置文件中的bean;(refresh方法,完成bean的加载)3)将WebApplicationContext放入servletContext中。

    ContextLoaderListener监听器初始化完之后,开始初始化web.xml中配置的servlet,如DispatcherSevlet
    ContextLoaderListener监听器监听的是servletContext,当web容器初始化后,servletContext发生变化时,会触发相应事件。

    触发的事件
    ContextClosedEvent
    ContextRefreshedEvent
    ContextStartedEvent
    ContextStoopedEvent
    RequestHandleEvent
    Spring容器启动后会触发ContextRefreshedEvent事件,想要在某个类加载完毕是干某事,但用了Spring管理对象,这个类又引用了其他类,比较复杂,可以写一个类继承Spring的ApplicationListener监听并监控ContextRefreshedEvent事件。
     
     

    SpringMVC容器启动流程及Controller的加载

    (5条消息) Spring容器 SpringMVC容器 web容器的关系_行动派-CSDN博客_springmvc容器

    (5条消息) Spring与SpringMVC父子容器的关系与初始化_菜到怀疑人生的博客-CSDN博客_springmvc父子容器

    Java过滤器与SpringMVC拦截器之间的关系与区别

    过滤器和拦截器的区别:

    1 拦截器是基于java的反射机制的,而过滤器是基于函数回调

    2 过滤器是servlet规范规定的只能用于web程序中,而拦截器是在spring容器中它不依赖servlet容器

    3 过滤器可以拦截几乎所有的请求(包含对静态资源的请求),而拦截器只拦截action请求(不拦截静态资源请求)。

    4 拦截器可以访问action上下文值栈里的对象,而过滤器不能访问。

    在action的生命周期中拦截器可以多次被调用,而过滤器只能容器初始化时调用一次

    6 拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service可以调用业务逻辑

    7 拦截器是被包裹在过滤器之中

     Mybatis:

    1. 最佳实践中,通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?

      答:Dao接口,就是人们常说的Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement,举例:com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到namespace为com.mybatis3.mappers.StudentDao下面id = findStudentById的MappedStatement。在Mybatis中,每一个<select>、<insert>、<update>、<delete>标签,都会被解析为一个MappedStatement对象。

      Dao接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。

      Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。

    2、Mybatis是如何进行分页的?分页插件的原理是什么?

      答:Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

      分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

    举例:select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,10

    3、简述Mybatis的插件运行原理,以及如何编写一个插件。

      答:Mybatis仅可以编写针对ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口的插件,Mybatis使用JDK的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这4种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,当然,只会拦截那些你指定需要拦截的方法。

    实现Mybatis的Interceptor接口并复写intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。

    5、Mybatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?

      答:Mybatis动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能,Mybatis提供了9种动态sql标签trim|where|set|foreach|if|choose|when|otherwise|bind。

    其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。

    Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?

      答:第一种是使用<resultMap>标签,逐一定义列名和对象属性名之间的映射关系。第二种是使用sql列的别名功能,将列别名书写为对象属性名,比如T_NAME AS NAME,对象属性名一般是name,小写,但是列名不区分大小写,Mybatis会忽略列名大小写,智能找到与之对应对象属性名,你甚至可以写成T_NAME AS NaMe,Mybatis一样可以正常工作。

      有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。

    8、Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?

    答:Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。

    它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。

    当然了,不光是Mybatis,几乎所有的包括Hibernate,支持延迟加载的原理都是一样的。

    mybatis延迟加载:Mybatis之延迟加载机制 - blue星空 - 博客园 (cnblogs.com)

    11、Mybatis都有哪些Executor执行器?它们之间的区别是什么?

    答:Mybatis有三种基本的Executor执行器,SimpleExecutor、ReuseExecutor、BatchExecutor。

    SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。

    ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map<String, Statement>内,供下一次使用。简言之,就是重复使用Statement对象。

    BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。

    作用范围:Executor的这些特点,都严格限制在SqlSession生命周期范围内。

     

    Mybatis缓存

    MyBatis将数据缓存设计成两级结构,分为一级缓存、二级缓存:

           一级缓存是Session会话级别的缓存,位于表示一次数据库会话的SqlSession对象之中,又被称之为本地缓存。一级缓存是MyBatis内部实现的一个特性,用户不能配置,默认情况下自动支持的缓存,用户没有定制它的权利(不过这也不是绝对的,可以通过开发插件对它进行修改);

           二级缓存是Application应用级别的缓存,它的是生命周期很长,跟Application的声明周期一样,也就是说它的作用范围是整个Application应用。

    一级缓存的工作机制:

          一级缓存是Session会话级别的,一般而言,一个SqlSession对象会使用一个Executor对象来完成会话操作,Executor对象会维护一个Cache缓存,以提高查询性能。关于一级缓存的详细实现,我已经在《深入理解mybatis原理》 MyBatis的一级缓存实现详解 及使用注意事项 一文中有非常详尽的讨论,读者可以前去了解。

    二级缓存的工作机制:

           如上所言,一个SqlSession对象会使用一个Executor对象来完成会话操作,MyBatis的二级缓存机制的关键就是对这个Executor对象做文章。如果用户配置了"cacheEnabled=true",那么MyBatis在为SqlSession对象创建Executor对象时,会对Executor对象加上一个装饰者:CachingExecutor,这时SqlSession使用CachingExecutor对象来完成操作请求。CachingExecutor对于查询请求,会先判断该查询请求在Application级别的二级缓存中是否有缓存结果,如果有查询结果,则直接返回缓存结果;如果缓存中没有,再交给真正的Executor对象来完成查询操作,之后CachingExecutor会将真正Executor返回的查询结果放置到缓存中,然后在返回给用户。

         MyBatis的二级缓存设计得比较灵活,你可以使用MyBatis自己定义的二级缓存实现;你也可以通过实现org.apache.ibatis.cache.Cache接口自定义缓存;也可以使用第三方内存缓存库,如Memcached等,这个我们会在后续的文章中详细讨论。

     一级缓存默认开启,可以在查询时使用flushCache=true关闭,一级缓存是针对sqlsession级别的。

    二级缓存默认关闭,配置打开

     同时在mapper中添加<cache/>才能开启。

         默认的二级缓存的效果:

         所有的Select语句将会被缓存

         映射语句中所有的insert,update,delete操作会刷新缓存

         缓存会使用LRU算法来回收

         缓存会存储集合或对象的1024个引用

         缓存会被视为read/write的

    12、Mybatis中如何指定使用哪一种Executor执行器?

    答:在Mybatis配置文件中,可以指定默认的ExecutorType执行器类型,也可以手动给DefaultSqlSessionFactory的创建SqlSession的方法传递ExecutorType类型参数。

    13、Mybatis是否可以映射Enum枚举类?

    答:Mybatis可以映射枚举类,不单可以映射枚举类,Mybatis可以映射任何对象到表的一列上。映射方式为自定义一个TypeHandler,实现TypeHandler的setParameter()和getResult()接口方法。TypeHandler有两个作用,一是完成从javaType至jdbcType的转换,二是完成jdbcType至javaType的转换,体现为setParameter()和getResult()两个方法,分别代表设置sql问号占位符参数和获取列查询结果。

    14、Mybatis映射文件中,如果A标签通过include引用了B标签的内容,请问,B标签能否定义在A标签的后面,还是说必须定义在A标签的前面?

    答:虽然Mybatis解析Xml映射文件是按照顺序解析的,但是,被引用的B标签依然可以定义在任何地方,Mybatis都可以正确识别。

    原理是,Mybatis解析A标签,发现A标签引用了B标签,但是B标签尚未解析到,尚不存在,此时,Mybatis会将A标签标记为未解析状态,然后继续解析余下的标签,包含B标签,待所有标签解析完毕,Mybatis会重新解析那些被标记为未解析的标签,此时再解析A标签时,B标签已经存在,A标签也就可以正常解析完成了。

    15、简述Mybatis的Xml映射文件和Mybatis内部数据结构之间的映射关系?

    答:Mybatis将所有Xml配置信息都封装到All-In-One重量级对象Configuration内部。在Xml映射文件中,<parameterMap>标签会被解析为ParameterMap对象,其每个子元素会被解析为ParameterMapping对象。<resultMap>标签会被解析为ResultMap对象,其每个子元素会被解析为ResultMapping对象。每一个<select>、<insert>、<update>、<delete>标签均会被解析为MappedStatement对象,标签内的sql会被解析为BoundSql对象。

    16、为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?

    答:Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。

    17.当实体类中的属性名和表中的字段名不一样 ,怎么办 ?

    第1种: 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致

    <select id=”selectorder” parametertype=”int” resultetype=”me.gacl.domain.order”> 
           select order_id id, order_no orderno ,order_price price form orders where order_id=#{id}; 
    </select> 

     第2种: 通过<resultMap>来映射字段名和实体类属性名的一一对应的关系

    复制代码
    <select id="getOrder" parameterType="int" resultMap="orderresultmap">
            select * from orders where order_id=#{id}
        </select>
       <resultMap type=”me.gacl.domain.order” id=”orderresultmap”> 
            <!–用id属性来映射主键字段–> 
            <id property=”id” column=”order_id”> 
            <!–用result属性来映射非主键字段,property为实体类属性名,column为数据表中的属性–> 
            <result property = “orderno” column =”order_no”/> 
            <result property=”price” column=”order_price” /> 
        </reslutMap>

    8. 在mapper中如何将参数与sql占位内容绑定?

    单个参数的传递很简单没有什么好将的,这里主要说下多个参数的传递

    1.第一种方式 匿名参数 顺序传递参数

    注意这里按参数名去引用的话会报如下错误,mybatis错误提示很细致,这里明确给我们提示,匿名参数只能使用

    arg1, arg0, param1, param2 类似的形式

    这种传参方式的缺点是不够灵活,必须严格按照参数顺序来引用

    <select id="selectByGenderAndAge" resultMap="BaseResultMap" > select * from employee where gender = #{param1} and age = #{param2} </select>

    2.第二种方式 使用@Param注解

    使用@Param注解显示的告诉mybatis参数的名字,这样在xml中就可以按照参数名去引用了

    List<Employee> selectByGenderAndAge( @Param("gender") Short gender,@Param("age") String age );

    3.使用Map传递参数

    实际开发中使用map来传递多个参数是一种推荐的方式可以看到使用map来传递多个参数,可以直接使用参数名称进行引用

    4.用过java bean传递多个参数

    也可以使用bean的方式来传递多个参数,使用时parameterType指定为对应的bean类型即可

    这就传参方式的优点是比较方便,controller层使用@RequestBody接收到实体类参数后,直接传递给mapper层调用即可,不需要在进行参数的转换

    5.直接使用JSON传递参数

    这也是推荐的一种传参方式,controller层收到JSON型数据后,直接传递给mapper层进行查询操作,简单 方便

    <select id="findByJSONObject" resultMap="BaseResultMap" parameterType="com.alibaba.fastjson.JSONObject"> select * from employee where gender = #{gender} and age = #{age} </select>

    6.传递集合类型参数List、Set、Array

    在一些复杂的查询中(如 sql中的 in操作),传统的参数传递已无法满足需求,这时候就要用到List、Set、Array类型的参数传递,具体使用如下:

      <select id="findByList" resultMap="BaseResultMap" >
    SELECT * from employee where age in
        <foreach collection="list" open="(" separator="," close=")" item="age">
          #{age}
        </foreach>
      </select>

    这里foreach表示循环操作,具体的参数含义如下:

    foreach元素的属性主要有 item,index,collection,open,separator,close。
    item表示集合中每一个元素进行迭代时的别名,
    index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,
    open表示该语句以什么开始,
    separator表示在每次进行迭代之间以什么符号作为分隔符,

    close表示以什么结束

    在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:

    • 1.如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
    • 2.如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
    • 3.如果传入的参数是多个的时候,我们就需要把它们封装成一个Map或者Object

        

    7.参数类型为对象+集合

    该类参数与java Bean参数形式类似,只不过更复杂一些,如下面的Department类,除了基本字段还包括一个Employee的列表

    <select id="findByDepartment" resultMap="BaseResultMap" parameterType="com.wg.demo.po.Department">
        SELECT * from employee where dept_id =#{department.id} and age in
        <foreach collection="department.employees" open="(" separator="," close=")" item="employee">
            #{employee.age}
        </foreach>
    </select>

    单个参数可以随便写,但是不能用if标签判断。

    如上修改,给siteid @Param注入getter 即可。

    结论:如果xml的parameterType属性时Map,则不需要加@Param。如果是一个int,string这种类型的参数,需要在Dao层加@Param注解;
    只有一个参数,xml不用if,可不加。
    有多个参数,dao层每个参数都要加上@Param。
    如果传入的参数特别多,建议直接传入一个Map。

    21. 接口绑定有几种实现方式,分别是怎么实现的?

      接口绑定有两种实现方式:

    • 一种是通过注解绑定,就是在接口的方法上面加上@Select@Update等注解里面包含Sql语句来绑定
    • 另外一种就是通过xml里面写SQL来绑定,在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名.

    23. 分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

    举例:

    select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,10

    Mybatis #与$

    MyBatis/Ibatis中#和$的区别

    1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #{user_id},如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id".

    2. $将传入的数据直接显示生成在sql中。如:order by ${user_id},如果传入的值是111,那么解析成sql时的值为order by 111,  如果传入的值是id,则解析成的sql为order by id. 

    3. #方式因为默认增加了双引号,能够很大程度防止sql注入。

    4.$方式属于字符的动态拼接,无法防止SSQL注入。

    5.$方式一般用于传入数据库对象,例如动态传入表名,经常在分表中使用,根据分表规则动态的确定数据落入那个分表中。(动态分表的话要在mybatis中设置statementType=“STATEMENT” 非预编辑)。 

    6.一般能用#的就别用$. 

     

    SpringBoot

    springboot   springmvc spring有什么区别

    SpringFrame

    SpringFramework 最重要的特征是依赖注入。所有 SpringModules 不是依赖注入就是 IOC 控制反转。

    当我们恰当的使用 DI 或者是 IOC 的时候,我们可以开发松耦合应用。松耦合应用的单元测试可以很容易的进行。

    SpringMVC

    Spring MVC 提供了一种分离式的方法来开发 Web 应用。通过运用像 DispatcherServelet,MoudlAndView 和 ViewResolver 等一些简单的概念,开发 Web 应用将会变的非常简单。

    SpringBoot

    Spring 和 SpringMVC 的问题在于需要配置大量的参数。

    1.  
      <pre hljs-string" >inherit; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; font-size: 13px; word-break: initial; word-wrap: initial; white-space: pre; overflow: auto; margin: 16px 0px 14px; padding: 14px 15px 12px; border-radius: 3px; border: none; display: block; line-height: 1.6; background: rgb(246, 246, 246); color: rgb(61, 70, 77); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke- 0px; text-decoration-style: initial; text-decoration-color: initial;"><bean
    2.  
      class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    3.  
      <property name="prefix">
    4.  
      <value>/WEB-INF/views/</value>
    5.  
      </property>
    6.  
      <property name="suffix">
    7.  
      <value>.jsp</value>
    8.  
      </property>
    9.  
      </bean>
    10.  
      <mvc:resources mapping="/webjars/**" location="/webjars/"/></pre>

    Spring Boot 通过一个自动配置和启动的项来目解决这个问题。为了更快的构建产品就绪应用程序,Spring Boot 提供了一些非功能性特征。

    什么是 Spring Boot Stater 

    启动器是一套方便的依赖没描述符,它可以放在自己的程序中。你可以一站式的获取你所需要的 Spring 和相关技术,而不需要依赖描述符的通过示例代码搜索和复制黏贴的负载。

    例如,如果你想使用 Sping 和 JPA 访问数据库,只需要你的项目包含 spring-boot-starter-data-jpa 依赖项,你就可以完美进行。

    下面的截图是添加进我们应用程序的不同的依赖项

    史上最全Spring Boot面试题(含答案)看完就是Spring Boot专家!

    依赖项可以被分为

    • Spring - core,beans,context,aop
    • Web MVC - (Spring MVC)
    • Jackson - for JSON Binding
    • Validation - Hibernate,Validation API
    • Enbedded Servlet Container - Tomcat
    • Logging - logback,slf4j

    任何经典的 Web 应用程序都会使用所有这些依赖项。Spring Boot Starter Web 预先打包了这些依赖项。

    Spring Boot 也提供了其它的启动器项目包括,包括用于开发特定类型应用程序的典型依赖项。

    spring-boot-starter-web-services - SOAP Web Services

    spring-boot-starter-web - Web 和 RESTful 应用程序

    spring-boot-starter-test - 单元测试和集成测试

    spring-boot-starter-jdbc - 传统的 JDBC

    spring-boot-starter-hateoas - 为服务添加 HATEOAS 功能

    spring-boot-starter-security - 使用 SpringSecurity 进行身份验证和授权

    spring-boot-starter-data-jpa - 带有 Hibeernate 的 Spring Data JPA

    spring-boot-starter-data-rest - 使用 Spring Data REST 公布简单的 REST 服务

    Spring Boot 致力于快速产品就绪应用程序。为此,它提供了一些譬如高速缓存,日志记录,监控和嵌入式服务器等开箱即用的非功能性特征。用户可以专注于业务逻辑。

    spring-boot-starter-actuator - 使用一些如监控和跟踪应用的高级功能

    spring-boot-starter-undertow, spring-boot-starter-jetty, spring-boot-starter-tomcat - 选择您的特定嵌入式 Servlet 容器

    spring-boot-starter-logging - 使用 logback 进行日志记录

    spring-boot-starter-cache - 启用 Spring Framework 的缓存支持

     

    Spring Initializr 是创建 Spring Boot Projects 的唯一方法吗

    不是的。

    Spring Initiatlizr 让创建 Spring Boot 项目变的很容易,但是,你也可以通过设置一个 maven 项目并添加正确的依赖项来开始一个项目。

    在我们的 Spring 课程中,我们使用两种方法来创建项目。

    第一种方法是 start.spring.io 。

    另外一种方法是在项目的标题为“Basic Web Application”处进行手动设置。

    手动设置一个 maven 项目

    这里有几个重要的步骤:

    • 在 Eclipse 中,使用文件 - 新建 Maven 项目来创建一个新项目
    • 添加依赖项。
    • 添加 maven 插件。
    • 添加 Spring Boot 应用程序类。

    到这里,准备工作已经做好!

     

    为什么我们需要 spring-boot-maven-plugin

    要记住:spring-boot-maven-plugin插件在打Jar包时会引入依赖包

    可以打成直接运行的Jar包

      maven项目的pom.xml中,添加了org.springframework.boot:spring-boot-maven-plugin
    插件,当运行“mvn package”进行打包时,会打包成一个可以直接运行的 JAR 文件,使用“Java -jar”命令就可以直接运行。

    spring-boot-maven-plugin插件的作用 - 贾树丙 - 博客园 (cnblogs.com)

    springboot devtools

    热部署使用

    (5条消息) SpringBoot常见的经典面试题_小陈之JAVA-CSDN博客_springboot面试题

    Spring Boot 的核心配置文件有哪几个?它们的区别是什么?

    Spring Boot 的核心配置文件是 application 和 bootstrap 配置文件。

    application 配置文件这个容易理解,主要用于 Spring Boot 项目的自动化配置。

    bootstrap 配置文件有以下几个应用场景。

    1. 使用SpringCloudConfig配置中心时,这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息;
    2. 一些固定的不能被覆盖的属性;
    3. 一些加密/解密的场景;

    开启SpringBoot特性有哪几种方式?

    1)继承spring-boot-starter-parent项目

    <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>1.5.6.RELEASE</version>
    </parent>

    2)导入spring-boot-dependencies项目依赖

    <dependencyManagement>
       <dependencies>
           <dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-dependencies</artifactId>
               <version>1.5.6.RELEASE</version>
               <type>pom</type>
               <scope>import</scope>
           </dependency>
    </dependencyManagement>

    运行SpringBoot有哪几种方式?

    1)打包用命令或者放到容器中运行

    2)用 Maven/ Gradle 插件运行

    3)直接执行 main 方法运行

    @Import的作用:

    将一个没扫描到的没有用component注解的类加入容器。

    springboot自动配置原理

    (5条消息) SpringBoot自动配置的原理及实现_牧竹子-CSDN博客_springboot自动配置的原理

    通过@springbootapplication

      -- @Springbootconfiguration

       --@ComponentScan

       --@EnableAutoConfiguration

        --@import(AutoConfigurationImportSelector)

    Springboot  main方法执行后发生了什么?

    SpringApplication.run(BootblogApplication.class, args);

    执行RUN方法后,分别执行SpringApplication的初始化,及实例run方法的运行。

    初始化方法:

      1、判断当前应用是否是web应用,根据是否有响应的类比如dispatchservlet来判断。

      2、设置初始化器;

    3、设置监听器;

    4、获取运行的主类;

    private void initialize(Object[] sources) {
        // 在sources不为空时,保存配置类
        if (sources != null && sources.length > 0) {
            this.sources.addAll(Arrays.asList(sources));
        }
        // 判断是否为web应用
        this.webEnvironment = deduceWebEnvironment();
        // 获取并保存容器初始化类,通常在web应用容器初始化使用
        // 利用loadFactoryNames方法从路径MEAT-INF/spring.factories中找到所有的ApplicationContextInitializer
        setInitializers((Collection) getSpringFactoriesInstances(
            ApplicationContextInitializer.class));
        // 获取并保存监听器
        // 利用loadFactoryNames方法从路径MEAT-INF/spring.factories中找到所有的ApplicationListener
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        // 从堆栈信息获取包含main方法的主配置类
        this.mainApplicationClass = deduceMainApplicationClass();

    run方法:

    public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        FailureAnalyzers analyzers = null;
        // 配置属性
        configureHeadlessProperty();
        // 获取监听器
        // 利用loadFactoryNames方法从路径MEAT-INF/spring.factories中找到所有的SpringApplicationRunListener
        SpringApplicationRunListeners listeners = getRunListeners(args);
        // 启动监听
        // 调用每个SpringApplicationRunListener的starting方法
        listeners.starting();
        try {
            // 将参数封装到ApplicationArguments对象中
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                args);
            // 准备环境
            // 触发监听事件——调用每个SpringApplicationRunListener的environmentPrepared方法
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                applicationArguments);
            // 从环境中取出Banner并打印
            Banner printedBanner = printBanner(environment);
            // 依据是否为web环境创建web容器或者普通的IOC容器
            context = createApplicationContext();
            analyzers = new FailureAnalyzers(context);
            // 准备上下文
            // 1.将environment保存到容器中
            // 2.触发监听事件——调用每个SpringApplicationRunListeners的contextPrepared方法
            // 3.调用ConfigurableListableBeanFactory的registerSingleton方法向容器中注入applicationArguments与printedBanner
            // 4.触发监听事件——调用每个SpringApplicationRunListeners的contextLoaded方法
            prepareContext(context, environment, listeners, applicationArguments,
                printedBanner);
            // 刷新容器,完成组件的扫描,创建,加载等
            refreshContext(context);
            afterRefresh(context, applicationArguments);
            // 触发监听事件——调用每个SpringApplicationRunListener的finished方法
            listeners.finished(context, null);
            stopWatch.stop();
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass)
                    .logStarted(getApplicationLog(), stopWatch);
            }
            // 返回容器
            return context;
        }
        catch (Throwable ex) {
            handleRunFailure(context, listeners, analyzers, ex);
            throw new IllegalStateException(ex);
        }

    SpringApplication.run一共做了两件事

    1. 创建SpringApplication对象;在对象初始化时保存事件监听器,容器初始化类以及判断是否为web应用,保存包含main方法的主配置类。
    2. 调用run方法;准备spring的上下文,完成容器的初始化,创建,加载等。会在不同的时机触发监听器的不同事件。

    (5条消息) Tomcat在SpringBoot中是如何启动的_清风一阵吹我心-CSDN博客

    你如何理解 Spring Boot 中的 Starters?

    Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成 Spring 及其他技术,而不需要到处找示例代码和依赖包。如你想使用 Spring JPA 访问数据库,只要加入 spring-boot-starter-data-jpa 启动器依赖就能使用了。

    Starters包含了许多项目中需要用到的依赖,它们能快速持续的运行,都是一系列得到支持的管理传递性依赖。具体请看这篇文章《Spring Boot Starters启动器》。

    如何在 Spring Boot 启动的时候运行一些特定的代码?

    可以实现接口 ApplicationRunner 或者 CommandLineRunner,这两个接口实现方式一样,它们都只提供了一个 run 方法,具体请看这篇文章《Spring Boot Runner启动器》。

    springboot读取配置的方式

    Spring Boot读取配置的几种方式

     

    Spring Boot 支持哪些日志框架?推荐和默认的日志框架是哪个?

    Spring Boot 支持 Java Util Logging, Log4j2, Lockback 作为日志框架,如果你使用 Starters 启动器,Spring Boot 将使用 Logback 作为默认日志框架,Spring Boot支持Java Util Logging,Log4j2,Lockback作为日志框架,如果你使用starters启动器,Spring Boot将使用Logback作为默认日志框架。无论使用哪种日志框架,Spring Boot都支持配置将日志输出到控制台或者文件中。

    spring-boot-starter启动器包含spring-boot-starter-logging启动器并集成了slf4j日志抽象及Logback日志框架。

    你如何理解 Spring Boot 配置加载顺序?

    在 Spring Boot 里面,可以使用以下几种方式来加载配置。

    1)properties文件;

    2)YAML文件;

    3)系统环境变量;

    4)命令行参数;

    读取顺序

    如果在不同的目录中存在多个配置文件,它的读取顺序是:
    1、config/application.properties(项目根目录中config目录下)
    2、config/application.yml
    3、application.properties(项目根目录下)
    4、application.yml
    5、resources/config/application.properties(项目resources目录中config目录下)
    6、resources/config/application.yml
    7、resources/application.properties(项目的resources目录下)
    8、resources/application.yml

    这几个位置都会加载,但不会覆盖,使用第一个读到的属性。

    配置文件的生效顺序,会对值进行覆盖

    1. @TestPropertySource 注解
    2. 命令行参数
    3. Java系统属性(System.getProperties())
    4. 操作系统环境变量
    5. 只有在random.*里包含的属性会产生一个RandomValuePropertySource
    6. 在打包的jar外的应用程序配置文件(application.properties,包含YAML和profile变量)
    7. 在打包的jar内的应用程序配置文件(application.properties,包含YAML和profile变量)
    8. 在@Configuration类上的@PropertySource注解
    9. 默认属性(使用SpringApplication.setDefaultProperties指定)

    外部配置加载顺序

    SpringBoot也可以从以下位置加载配置,优先级从高到低,高优先级的配置覆盖低优先级的配置,所有的配置形成互补配置。

     1. 命令行参数

         eg:   java -jar  spring-boot-02-config-02.0.0.1-SNAPSHOT.jar --server.port=8087

     2. 来自java:comp/env的NDI属性

     3. Java系统属性(System.getProperties() )

     4. 操作系统环境变量

     5. RandomValuePropertySource配置的random.*属性值

     6. jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件

        将打好的jar包放在一个目录下,比如叫做 hello的文件夹,然后再该文件夹下新建一个名为application.yml的文件,其中指定

      port为8088 ,访问路径为/boot ,然后命令行直接启动项目。java  -jar spring-boot-02-config-02.0.0.1-SNAPSHOT.jar

    浏览器通过  localhost:8088/boot/hello 可以正常访问,表示同级目录下的配置文件生效了。

     7. jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件

     8. jar包外部的application.properties或application.yml(不带spring.profile)配置文件

    8. jar包外部的application.properties或application.yml(不带spring.profile)配置文件

     9. jar包内部的application.properties或application.yml(不带spring.profile)配置文件

     10. @Configuration注解类上的propertySource

     11. 通过SpringApplication.setDefaultProperties指定的默认属性。

    Spring Boot Reference Guide

    Spring Boot 如何定义多套不同环境配置?

    提供多套配置文件,如:

    applcation.properties

    application-dev.properties
    application-test.properties
    application-prod.properties


    18、Spring Boot 可以兼容老 Spring 项目吗,如何做?

    可以兼容,使用 @ImportResource 注解导入老 Spring 项目配置文件。

    保护 Spring Boot 应用有哪些方法?

    1. 在生产中使用HTTPS

    2. 使用Snyk检查你的依赖关系

    3. 升级到最新版本

    4. 启用CSRF保护

    5. 使用内容安全策略防止XSS攻击


    20、Spring Boot 2.X 有什么新特性?与 1.X 有什么区别?

    1. 配置变更
    2. JDK 版本升级
    3. 第三方类库升级
    4. 响应式 Spring 编程支持
    5. HTTP/2 支持
    6. 配置属性绑定

     

     

     

  • 相关阅读:
    对于想用OS但又觉得单片机资源太过紧张,状态机是个不错的选择分享一种状态机设计方法
    状态机实践入门
    Codewarrior 调试错误ILLEGAL_BP
    坑爹的AVR编译器中文路径问题
    跨入AVR
    atmega8 例程:USART串口通信
    2011总结
    atmega8 默认内部RC振荡 + 解锁
    关于AVR I/O 的驱动能力的介绍
    atmega8 例程:系统库函数的延迟
  • 原文地址:https://www.cnblogs.com/baldprogrammer/p/14039800.html
Copyright © 2020-2023  润新知