Spring 和 SpringMVC , SpringBoot 基础知识的认识 SpringBoot的主要的注解:  Spring boot 的starter 的作用? Spring MVC 的主要组件由几个?  对Spring的认识与理解?

  

springboot 注解;

springbootApplication 
    springbootConfiguration

    EnableAutoConfiguration  自动装配
        @import 是用于把类加入到bean的容器中, 或者是导入第三方的包等。
        @Import(EnableAutoConfigurationImportSelector.class)
            会获取到classpath下META-INF/spring.factories 下加载key对应的全限定名对应的值  放在一个list里面
        @AutoConfigurationpackage
            @Import(AutoConfigurationPackages.Registrar.class) 把要加入的包添加到bean的注册器中
            添加该注解的类所有的包都进行自动管理

    componentScan
        @repeatable  声明其他类型的注解的元注解,使用该注解后可重复, 该注解的值是一个注解可通过另一个注解来包含这个注解可重复。



springboot的执行流程
  springboot 的启动 主要创建了配置环境 事件监听 应用的上下文  初始化bean 

springcloud 的好处 

springcloud 是基于springboot 实现云应用开发的工具, 用于继承方便管理springboot的单个整体的框架。

  @SpringBootApplication 

   是SpringBoot启动类上的注解。 也是springboot 最核心的注解,它是由三个注解组成的 @Configuration , @EnableAutoConfiguration , @ComponentScan 三个注解组成。 所以SpringBoot 的统一注解就是SpringBootApplication

  @EnableAutoConfiguration 

   允许SpringBoot 自动配置注解,开启这个注解后,Springboot就根据当前类路径下的包或者类来配置Springbean。

  如:当前类路径下有mybatis的jar包。 MybatisAutoConfiguration 注解就能根据相关的参数来配置mybatis 的各个Springbean。

  @EnableAutoConfiguration 实现的关键在于引入了 AutoConfigurationImportSelector,  其核心的逻辑为selectImports 的方法。

  @SpringBootConfiguration

  这个注解就是@Configuration注解的变体, 只是用来修饰Spring boot的配置,或者可利于Springboot后续的扩展。

  @ComponentScan

  @ComponentScan主要就是定义扫描的路径从中找出标识了需要装配的类自动装配到spring的bean容器中

  @Configuration

  是spring的配置类    配置当前的类 相当于xml文件,

  @ConditionalOnBean

  @conditionalOnBean(A.class)  仅仅在当前上下文中存在A对象时,才会实例化一个Bean,也就是说只有当A.class 在Spring的ApplicationContext中存在时,这个当前的bean才能创建。

  @ConditionalOnMissingBean

  这个注解的意思是组合@Conditional 注解 和 @ConditiionalOnbean 注解相反, 仅仅在当前上下文不存在A对象,才会实例化一个bean。

  @ConditionalOnClass

  组合@conditional注解,可以仅当某些类存在于classpath上时候才创建某个bean。

  

  @Bean
  //当classpath中存在类HealthIndicator时,才创建HealthIndicator Bean对象
  @ConditionalOnClass(HealthIndicator.class)
  public HealthIndicator rocketMQProducerHealthIndicator(Map<String, DefaultMQProducer> producers) {
      if (producers.size() == 1) {
          return new RocketMQProducerHealthIndicator(producers.values().iterator().next());
      }
  

  @ConditionalOnMissingClass

  组合@Conditional注解,和 @ConditionalOnClass 注解相反,当classspath中没有指定的class才开启配置。

  @ConditionalOnWenApplication

  组合@Conditional注解,当前项目类型是web项目才会开启配置, 当项目由以下3中类型: ANY(任何web项目都匹配) , servlet (仅但基础的servlet项目才会匹配) REACTIVE(只有基于响应的web应用程序才匹配)。

  @ConditionalOnNotWebApplication

  组合@Conditional 注解 和 @ConditionalOnWebApplication 注解相反 当前项目类型不是web 项目才开启配置。

  @ConditionalOnProperty

  组合 @conditional 注解, 当指定的属性由指定的值时才开启配置,具体操作是通过其两个属性name 以及 havingValue 来实现的, 其中name用来从application.properties中读取某个属性值,如果属性值为空,则返回false ; 如果值不为空, 则将值于havingValue 指定的值进行比较,如果一样则返回true ; 否则返回false,如果返回值为false,则该configuration 不生效,  为true 则生效。

 @Bean
 //匹配属性rocketmq.producer.enabled值是否为true
 @ConditionalOnProperty(value = "rocketmq.producer.enabled", havingValue = "true", matchIfMissing = true)
 public RocketMQProducer mqProducer() {
     return new RocketMQProducer();
 }

  @ConditionalOnExpression

  组合@Conditional 注解, 当spEl 表达式为true是才开启配置。

@Configuration
@ConditionalOnExpression("${enabled:false}")
public class BigpipeConfiguration {
    @Bean
    public OrderMessageMonitor orderMessageMonitor(ConfigContext configContext) {
        return new OrderMessageMonitor(configContext);
    }
}

  @ConditionalOnJava

  组合@Conditional注解, 在运行Java jvm在指定的版本范围内开启配置。

   @ConditionalOnResource

  组合@Conditional注解 , 当类路径下由指定的资源才会开启配置。

@Bean
@ConditionalOnResource(resources="classpath:shiro.ini")
protected Realm iniClasspathRealm(){
  return new Realm();
}

  @ConditionalOnJndi

  组合Conditional注解, 当指定的 JNDI存在时才开启配置。

  @ConditionalOnCloudPlatform

  组合Conditional注解, 当指定的云平台激活时才开启配置。

  @ConditionalOnSingleCandidate

  组合Conditional注解 , 当指定的class在容器中只有一个bean, 或者同时由多个但为首选时才会开启配置。

  @ConditionalOnProperties

  spring boot 可以使用注解的方式将自定义的properties文件映射到实体bean中,

@Data
@ConfigurationProperties("rocketmq.consumer")
public class RocketMQConsumerProperties extends RocketMQProperties {
    private boolean enabled = true;

    private String consumerGroup;

    private MessageModel messageModel = MessageModel.CLUSTERING;

    private ConsumeFromWhere consumeFromWhere = ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET;

    private int consumeThreadMin = 20;

    private int consumeThreadMax = 64;

    private int consumeConcurrentlyMaxSpan = 2000;

    private int pullThresholdForQueue = 1000;

    private int pullInterval = 0;

    private int consumeMessageBatchMaxSize = 1;

    private int pullBatchSize = 32;
}

  @EnableConfigurationProperties

  当@EnableConfigurationProperties 注解一个用用到你的@Configuration时,任何被@ConfigurationProperties 注解beans 将自动被Environment 属性配置,这种风格的配置特别适合于SpringApplicationde 外部YAML配置经i选哪个配合使用。

@Configuration
@EnableConfigurationProperties({
    RocketMQProducerProperties.class,
    RocketMQConsumerProperties.class,
})
@AutoConfigureOrder
public class RocketMQAutoConfiguration {
    @Value("${spring.application.name}")
    private String applicationName;
}

  @AutoConfigureAfter

  用在自动配置类上面,表示该自动类需要在另外指定自动配置类配置完之后,

如 Mybatis 的自动配置类,需要在数据源自动配置类之后。

@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisAutoConfiguration {
}

  @AutoConfigureBefore

  这个和@AutoConfigureAfter注解使用相反, 表示该自动类配置类需要在另外指定的自动配置类之前。

  @AutoConfigureOrder

   Spring boot 中由一个新的 注解 @AutoConfigureOrder, 用于确定配置加载的优先级顺序。

 @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) // 自动配置里面的最高优先级
  @Configuration
  @ConditionalOnWebApplication // 仅限于web应用
  @Import(BeanPostProcessorsRegistrar.class) // 导入内置容器的设置
  public class EmbeddedServletContainerAutoConfiguration {
      @Configuration
      @ConditionalOnClass({ Servlet.class, Tomcat.class })
      @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
      public static class EmbeddedTomcat {
         // ...
      }

      @Configuration
      @ConditionalOnClass({ Servlet.class, Server.class, Loader.class, WebAppContext.class })
      @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
      public static class EmbeddedJetty {
         // ...
      }
}

 Spring boot 的starter 的作用?

starter的引入相关的一些依赖和一些初始化的配置。

Spring MVC 的主要组件由几个?

 一共由九个组件。

  1.  MultiparResolver (文件处理器) 
  2. localeResolver( 当前环境处理器)
  3. ThemeResolver ( 主题处理器)
  4. HandlerMappings (处理映射器)
  5. HandlerAdapters ( 处理适配器)
  6. HandlerExceptionResolvers (异常处理器)
  7. RequestToViewNameTranslator  ( 视图名称翻译器)
  8. ViewResolvers ( 页面渲染处理器)
  9. FlashMapManager ( 参数传递管理器)

Spring MVC 的执行过程:

  1. 客户端浏览器发送一个请求到前端控制器(dispatcherServlet) 的请求。
  2. dispatcherServlet 接收到请求后, 调用HandlerMapping 处理器映射器。
  3. HandlerMapping 根据请求url地址,查找响应的处理器(handler )如果由处理器对象或者是拦截器对象的话一并返回给dispatcherServlet。
  4. dispatcherServlet 拿到这些信息后,会调用handlerAdapter 会执行handler ,经过handler处理后生成了ModelAndView 对像返回给handlerAdapter。
  5. handlerAdapter 将modelAndView 返回给dispatcherServlet。
  6. dispatcherServlet 将modelAndView 对象发到视图解析器上ViewResolver。
  7. ViewResolver 将ModelAndView 对象进行解析,获取view对象,将view对象返回给dispatcherServlet 。
  8. dispatcherServlet 拿到view对象, 对页面进行渲染,然后返回给客户端浏览器上

 对Spring的认识与理解?

Spring的概述:spring的核心就是提供一种新的机制管理业务对象以及依赖关系,它是一种容器框架,用于创建bean,维护bean之间的关系。它可以管理web层,持久层,业务层,还可以配置各个层之间的关系。

Spring的特点:    

有以下几点:    1 轻量级    2 非入侵式    3 容器,spring有两种不同的容器, bean工厂 以及应用上下文,
    Spring的容器可以管理对象生命周期和对像之间的关系,也可以通过xml来设置对想的初始值和对象的关系,

spring的优点:

  1.   方便解耦,简化开发  : spring就是一个容器可以将所有的对象创建和依赖关系维护,交给spring处理,
  2.   AOP编程的支持  : AOP面向切面的编程, 是对程序的权限的拦截和运行的监控等,
  3.   声明式事务的支持  :只要通过配置就可以对事务完成管理,不用手动管理
  4.   方便程序的测试
  5.   方便集成各种优秀的框架
  6.   降低了javaEE api的使用难度

spring的工作原理:

    spring的核心就是ioc,动态的注入 ,让一个对象的创建不用在new了。可以自动生产,其实这里使用到的就是Java的反射, 反射就是在运行的时候动态的创建,调用对象,spring就是在运行的时候,跟xml Spring的配置文件来动态创建对象和调用对象里的方法,
    
    spring的ioc 动态注入, 就是使用了Java的反射来的动态的调用spring的xml配置文件来实现了对象的创建和对象里方法的调用,
    
    spring的aop面向切面编程,可以为某一类对象进行监督和控制,也就是说在嗲用这些类对象的具体方法的前后去调用你指定的模块, 从而达到对一个模块扩充的功能,这些都是通过配置类达到的。
    Spring 的目的 就是让对象与对象 或者是模块与模块  之间的关系没有通过代码来关联,都是通过配置类来说明管理的。


 Spring的ioc容器有两种不同类型的容器:


  一个是Spring  beanFactory    一个是 Spring ApplicationContext

  applicatonContext容器包括了BeanFactory 容器的所有功能,

  BeanFactory 和相关的接口,比如BeanFactoryAware、DisposableBean、InitializingBean,仍旧保留在 Spring 中,主要目的是向后兼容已经存在的和那些 Spring 整合在一起的第三方框架。


  FileSystemXmlApplicationContext 需要一个完成的路径绝对路径,

package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new FileSystemXmlApplicationContext
            ("C:/Users/ZARA/workspace/HelloSpring/src/Beans.xml");
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();
   }
}

  ClassPathXmlApplicationContext 只要一个相对的路径

  WebXmlApplicationContext:该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。

Spring bean 的理解:

  spring 的工厂就是生产bean。可以将所有的对象创建和依赖关系的维护,

  Spring bean 可分为5种:singleton , prototype  request session global-session

  request : 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境。

  session : 同一个HTTP Session共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境。

  global-session : 一般用于Portlet应用环境,该运用域仅适用于WebApplicationContext环境。

  singleton 是默认的作用域

  如果没有指定的作用域的配置, 就默认使用singleton 。 那么spring ioc的容器中只会存在一个共享的bean的实例,并且所有的bean的请求,只要id与bean匹配,就会返回bean的同一实例。

  singleton 是单例的类型,创建容器起就同时自动创建了一个bean的对象,不管是否 使用过,他都存在每次的获取到的都是同一对象, 注意: singleton作用域是spring中的缺省作用域。

  prototype 作用域

  表示bean定义对应多个对象实例, prototype作用域的bean会导致在每次对该bean请求时会创建一个新的bean。prototype 是原型类型,他在我们创建容器的时候并没有实例化, 而是当我们获取bean对象的时候才会去创建一个对想, 而且我们每次获取的对象都是不同一个对象。

package com.tutorialspoint;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }

   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}


package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      HelloWorld objA = (HelloWorld) context.getBean("helloWorld");
      objA.setMessage("I'm object A");
      objA.getMessage();
      HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
      objB.getMessage();
   }
}

bean.xml 文件

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean > 
      scope="prototype">
   </bean>

</beans>

输出的结果

Your Message : I'm object A
Your Message : null

bean 的生命周期表达式:

   bean的定义   —— bean初始化 ——bean的使用 ——bean的销毁。

bean的后置处理器:

  允许在调用bean的初始化方法前后对bean的特殊处理。  需要实现 BeanPostProcessor 类    在bean.xml中配置实现BeanPostProcessor 类的路径。

  

spring的aop的理解:

  在项目中用到Spring 的 aop 地方

  目标类是 service 接口, 切面就是实现service接口类  通过在xml中配置   (切面类中确定通知,需要实现不同接口,接口就是规范,从而就确定方法名称。

  spring的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 1 创建目标类 -->
    <bean />
    </aop:config>
</beans>

测试:

  @Test
    public void demo01(){
        String xmlPath = "com/itheima/c_spring_aop/beans.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);

        //获得目标类
        UserService userService = (UserService) applicationContext.getBean("userServiceId");
        userService.addUser();
        userService.updateUser();
        userService.deleteUser();
    }

AOP 的编程思想及术语?

  AOP是面向切面的编程,其编程思想是把散布在不同业务但功能相同的代码从业务逻辑中抽出来,进行封装成独立的模块,这些独立的模块被称为切面,切面的具体功能方法被称为关注 点,在业务执行的过程中,AOP会把分离出来的切面和关注点动态的切入到业务流程中,这样做的好处就是提高了代码的重用性和可维护性。

  Aspect  : 表示切面,切入业务流程的一个独立的模块。

  Join point :表示连接点,也就是业务流程在运行过程中需要插入切面的具体位置,

  Advice :表示通知,是切面的具体实现方法,可分为前置通知( Before ) ,后置通知( afterReturning )  异常通知 ( afterThrowing) , 最终通知 ( after) 和 环绕通知( Around) 五种。实现的具体方法属于哪种类通知,在配置文件和注解中指定的。

  pointcut : 表示切入点, 用于定义通知该切入点到哪些连接点上,不同的通知常需要切入到不同的连接点上,例如: 前面案例配置文件的 <aop:pointcut> 标签上。

  Target : 表示的目标类,被一个或者多个切面所通知的对象,例如:前面的案例的 AopEmailNotice 类。

  Proxy : 表示代理对象,将通知应用到目标对象之后被动态创建的对象,可以简单的理解为 代理对象为目标对象的业务逻辑功能加上被切入的切面所形成的对象 。

  weaving : 表示切入, 也称为织入,将切面应用到目标对象从而创建一个新的代理队形对象过程,这个过程可以发生在编译器,类装转载及运行期。