当前位置: 首页 > news >正文

网络规划设计师试题西安抖音seo

网络规划设计师试题,西安抖音seo,温州建设工程网站,手机商城网站制作公司SpringBoot3核心原理 事件和监听器 生命周期监听 场景:监听应用的生命周期 可以通过下面步骤自定义SpringApplicationRunListener来监听事件。 ①、编写SpringApplicationRunListener实现类 ②、在META-INF/spring.factories中配置org.springframework.boot.Sprin…

SpringBoot3核心原理

事件和监听器

生命周期监听

场景:监听应用的生命周期

可以通过下面步骤自定义SpringApplicationRunListener来监听事件。
①、编写SpringApplicationRunListener实现类
②、在META-INF/spring.factories中配置org.springframework.boot.SpringApplicationRunListener=自己的Listener,还可以指定一个有参构造器,接收两个参数SpringApplication application, String[] args
③、springboot在spring-boot.jar中配置了默认的Listener,如下:
org.springframework.boot.SpringApplicationRunListener=
org.springframework.boot.context.event.EventPublishingRunListener
监听器.png

场景实现
创建监听器

MyApplicationListener

package com.louis.listener;import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;import java.time.Duration;/*** springboot应用生命周期监听* @author XRY* @date 2023年07月14日14:51*/
public class MyApplicationListener implements SpringApplicationRunListener {@Overridepublic void starting(ConfigurableBootstrapContext bootstrapContext) {System.out.println("===========starting==========正在启动=======");}@Overridepublic void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {System.out.println("===========environmentPrepared==========环境准备完成=======");}@Overridepublic void contextPrepared(ConfigurableApplicationContext context) {//相当与IOC容器System.out.println("===========contextPrepared==========ioc容器准备完成=======");}@Overridepublic void contextLoaded(ConfigurableApplicationContext context) {System.out.println("===========contextLoaded==========ioc容器加载完成=======");}@Overridepublic void started(ConfigurableApplicationContext context, Duration timeTaken) {System.out.println("===========started==========启动完成=======");}@Overridepublic void ready(ConfigurableApplicationContext context, Duration timeTaken) {System.out.println("===========ready==========准备就绪=======");}@Overridepublic void failed(ConfigurableApplicationContext context, Throwable exception) {System.out.println("===========failed==========应用启动失败=======");}
}

提示:

想要让配置的监听器生效,需要在根目录下创建一个META-INF文件夹并添加文件spring.factories(它是一个key,value写法:key为接口全类名, value为我们创建类的全类名)

org.springframework.boot.SpringApplicationRunListener=com.louis.listener.MyApplicationListener
springboot应用生命周期监听

Listener先要从BootStrapContext引导整个项目启动,主要分为下面的几个步骤:

  1. 引导:利用BootstrapContext引导整个项目启动

    starting:应用开始,调用SpringApplication的run方法,只要有了BootStrapContext就执行
    environmentPrepared:环境准备好(把启动参数等绑定到环境变量中),但是ioc容器还没有创建。(调一次)
    
  2. 启动:

    contextPrepared: ioc容器创建并准备好,但是sources(主配置类)没加载,并关闭上下文,组件还没有创建(调一次)
    contextLoaded: ioc容器加载。著配置类加载进去,但是ioc容器还没有刷新。(Bean都没创建)
    started: ioc容器刷新了(容器中加入了Bean),但是runner没调用。
    ready: ioc容器刷新了(容器中加入了Bean),所有runner调用完。

  3. 运行

    以前的步骤都正确执行,代表容器running
    生命周期全流程.png

事件触发时机

1、各种回调监听器介绍
监听器监听阶段作用使用场景
BootstrapRegistryInitializer感知特定阶段感知引导初始化META-INF/spring.factories
创建引导上下文bootstrapContext的时候触发可以在主程序调用:application.add.BootstrapRegistryInitializer()
进行密钥校对授权
ApplicationContextInitializer感知特定阶段感知ioc容器初始化META-INF/spring.factories
ApplicationListener感知全阶段基于事件机制,感知事件。@Bean或EventListener、SpringApplication.addListeners(…)或SpringApplicationBuilder.listeners(…)、META-INF/spring.factories
SpringApplicationRunListener感知全阶段生命周期+各种阶段自定义操作META-INF/spring.factories
ApplicationRunner感知特定阶段感知应用就绪Ready的@Bean
CommandLineRunner感知特定阶段感知应用就绪Ready的@Bean

总结:

如果项目启动前做事:BootstrapRegistryInitializer和ApplicationContextInitializer
如果想要在项目启动完成后做事:ApplicationRunner和CommandLineRunner
如果想要干涉生命周期:SpringApplicationRunListener
如果想要用事件机制:ApplicationListener

2、事件完整触发流程(9种事件)
  • ApplicationStartingEvent:应用启动但未做任何事情,
  • ApplicationEnvironmentPreparedEvent:Environment准备好,但context未创建
  • ApplicationContextInitializedEvent:ApplicationContext准备好,ApplicationContextInitializers调用,到那时任何bean未加载
  • ApplicationPreparedEvent:容器刷新之前,bean定义信息加载
  • ApplicationStartedEvent:容器刷新完成,runner未调用
  • AvailabilityChangeEvent:LivenessState.CORRECT应用存活,存活探针
  • ApplicationReadyEvent:任何runner被调用
  • AvailabilityChangeEvent:ReadinessState.ACCEPTING_TRAFFIC应用就绪,可以接收请求,就绪探针
  • ApplicationFailedEvent:启动出错

事件发送顺序

事件发送顺序.png
**两个探针的作用是感知应用是否存货和就绪。 **

3、SpringBoot事件驱动开发

应用启动过程生命周期事件感知(9大事件)、应用运行中事件感知(无数种)

  • 事件发布:ApplicationEventPublisherAware或注入:ApplicationEventMulticaser
  • 事件监听:组件 + @EventListener
示例

事件驱动开发.png

创建service

AccountService

@Service
public class AccountService {public void addAccountScore(String username){System.out.println(username + "加了1分");}
}

CouponService

@Service
public class CouponService {public void sendCoupon(String username){System.out.println(username + "随机得到了一张优惠券");}
}

SystemService

@Service
public class SystemService {public void recordLog(String username, String password){System.out.println(username + "  ,密码为" + password + "登录信息已被记录");}
}
不使用事件

LoginController

@RestController
public class LoginController {@AutowiredAccountService accountService;@AutowiredCouponService couponService;@AutowiredSystemService systemService;@GetMapping("login")public String login(@RequestParam String username,@RequestParam String password){//业务处理登录System.out.println("业务处理登录完成.........");//1、账户服务自动签到加积分accountService.addAccountScore(username);//2、优惠服务随机发放优惠券couponService.sendCoupon(username);//3、系统服务登记用户登录信息systemService.recordLog(username, password);return username + "登录成功";}
}

测试事件开发.png
测试事件开发01.png

使用事件机制

创建实体类UserEntity

@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserEntity {private String username;private String password;
}

创建事件LoginSuccessEvent,继承ApplicationEvent

package com.louis.event;import com.louis.entity.UserEntity;
import org.springframework.context.ApplicationEvent;import java.awt.desktop.AppEvent;/*** @author XRY   登录成功事件, 所有事件都推荐继承ApplicationEvent* @date 2023年07月14日19:19*///登录成功事件
public class LoginSuccessEvent extends ApplicationEvent {/*** @param source 代表谁登录成功了*/public LoginSuccessEvent(UserEntity source) {super(source);}
}

创建事件发送类 EventPublisher

package com.louis.event;import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;/*** @author XRY* @date 2023年07月14日19:18*/
@Service
public class EventPublisher implements ApplicationEventPublisherAware {/*** 底层发送事件的组件,SpringBoot会通过ApplicationEventPublisherAware接口自动注入给我们*/ApplicationEventPublisher applicationEventPublisher;/*** 所有事件都可以发* @param event*/public void sendEvent(ApplicationEvent event){//用底层API发送事件applicationEventPublisher.publishEvent(event);}/*** 会被自动调用,把真正发事件的底层组件注入进来* @param applicationEventPublisher*/@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.applicationEventPublisher = applicationEventPublisher;}
}

控制器LoginController

@RestController
public class LoginController {//事件@AutowiredEventPublisher eventPublisher;@GetMapping("login")public String login(@RequestParam String username,@RequestParam String password){//业务处理登录System.out.println("业务处理登录完成.........");//发送事件//1、创建事件信息LoginSuccessEvent event = new LoginSuccessEvent(new UserEntity(username, password));//2、发送事件eventPublisher.sendEvent(event);return username + "登录成功";}
}

事件机制01.png
事件机制02.png

自动配置原理

入门理解

应用关注的三大核心:场景、配置、组件

1、 自动配置流程

自动配置流程.png

①、导入starter
②、依赖导入autoconfigure
③、寻找类路径下META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.import文件
④、启动,加载所有自动配置类-xxxAutoConfiguration
i、给容器种配置功能组件
ii、组件参数绑定到属性类中。xxxProperties
iii、属性类和配置文件前缀项绑定
iV、@Conditional派生的条件注解进行判断是否组件生效
⑤、效果:
i、修改配置文件、修改底层参数
ii、所有场景自动配置好直接使用
iii、可以注入SpringBoot配置好的组件随时使用。

2、SPI机制

SPI 全称是 Service Provider Interface,是一种 JDK 内置的动态加载实现扩展点的机制,通过 SPI 技术我们可以动态获取接口的实现类,不用自己来创建。这个不是什么特别的技术,只是 一种设计理念。它实际上是基于接口的编程+策略模式+配置文件组合实现的动态加载机制。

image.png
系统设计的各个抽象,往往有很多不同的实现方案,在面向对象的设计里,一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。Java SPI就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。所以SPI的核心思想就是解耦。

3、功能开关
  • 自动配置:全部都配置好,什么都不用管,自动批量导入。

    项目启动,spi文件中指定的所有都加载

  • @Enablexxx:手动控制哪些功能的开启,手动导入。

    开启xxx功能,都是利用@Import把此功能要用的组件导入进去。

进阶理解

@SpringBootApplication是以下三个注解的复合注解:
①、@SpringBootConfiguration:就是@Configuration,容器中的组件,配置类。Spring ioc启动就会加载创建这个类对象。
②、@EnableAutoConfiguration:开启自动配置,由如下两注解复合:

  • @AutoConfigurationPackage

扫描主程序包。利用@Import(AutoConfigurationPackages.Registrar.class)加载自己想要给容器中导入的组件。把主程序所在包的所有组件导入进来。即只扫描主程序及主程序所在的包及其子包。

  • @Import(AutoConfigurationImportSelector.class)

加载所有自动配置类,加载starter导入组件List configurations = ImportCandidates.load(AutoConfiguration.class,getBeanClassLoader()).getCandidates();
扫描SPI文件:“META-INF/spring/org.springframework.boot.autoconfigure.Autoconfiguration.imports”
③、@ComponentScan
组件扫描,排除一些组件,排除前面已经扫描进来的配置类和自动配置类。

自定义starter

场景:抽取聊天机器人场景,它可以打招呼。
效果:任何项目导入此starter都具有打招呼功能,并且问候语中的人名需要可以在配置文件中修改。

实现步骤

①、创建自定义starter项目,引入spring-boot-starter基础依赖
②、编写模块功能,引入模块所有需要的依赖,编写xxxAutoConfiguration自动配置类
③、编写配置文件META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports指定启动需要加载的自动配置。
④、其他下项目引入即可使用。

通用业务代码

小技巧:可以导入如下依赖重启项目,再写配置文件会有提示。

<!--导入配置处理器,自定义的properties配置文件会有提示-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>
配置类
@ConfigurationProperties(prefix = "robot")
@Component
@Data
public class RobotProperties {private String name;private String email;private Integer age;
}

配置文件

robot.name=张三
robot.age=23
robot.email=louis@qq.com

通用功能

@Service
public class RobotService {@AutowiredRobotProperties robotProperties;public String sayHello(){return "你好:" + robotProperties.getName() + "   ;年龄:" + robotProperties.getAge();}
}

控制器

@RestController
public class RobotController {@AutowiredRobotService robotService;@GetMapping("/robot/hello")public String sayHello(){return robotService.sayHello();}
}

代码.png

基本抽取(新建模块)

新建模块时不需要选择任何场景。

复制公共功能

抽取.png

根据公共功能,添加场景

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>
<!--导入配置处理器,自定义的properties配置文件会有提示-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>

删除主类

删除主类.png

在需要引用项目下导入该starter

<!--自定义的starter-->
<dependency><groupId>com.louis</groupId><artifactId>boot3-robot-starter</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency>

在starter下编写配置类

原因:SpringBoot项目只能扫描主程序以及主程序所在的子包,当导入自定义的starter时,不属于这一层级。

@Configuration
@Import({RobotController.class, RobotService.class, RobotProperties.class})
public class RobotAutoConfiguration {}

在主程序导入配置类

boot3-07.png

@SpringBootApplication
@Import(RobotAutoConfiguration.class)
public class Boot307Application {public static void main(String[] args) {SpringApplication.run(Boot307Application.class, args);}}

引入starter不会读取starter本身的配置。

编写application.properties

robot.name=louie
robot.age=23
robot.email=louis@qq.com

测试

基本抽取.png
总结:

a、创建starter,将公共代码所需的所有依赖导入
b、将公共代码复制到starter
c、自己写一个RobotAutoConfiguration,该容器中导入需要组件(主程序扫描规则)
d、测试功能

使用Enable机制

原因:在导入starter的时候,使用者可能不知道需要导入哪些相关的文件。

在我们的starter编写注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({RobotAutoConfiguration.class})
public @interface EnableRobot {
}在主程序中使用@EnableRobot注解
@SpringBootApplication
@EnableRobot
public class Boot307Application {public static void main(String[] args) {SpringApplication.run(Boot307Application.class, args);}}

测试

基本抽取.png
总结:

别人引入starter需要使用@EnableRobot开启功能

完全自动

依赖SpringBoot的SPI机制"META-INF/spring/org.springframework.boot.autoconfigure.Autoconfiguration.imports"在其中放置RobotAutoConfiguration配置类的全类名。如:com.louis.starter.robot.config.RobotAutoConfiguration
import文件.png只需要导入starter,不用加任何注解。

测试

import配置后.png


文章转载自:
http://dinncopinkie.tpps.cn
http://dinncowonderful.tpps.cn
http://dinncowagnerism.tpps.cn
http://dinncoxylographic.tpps.cn
http://dinncohijack.tpps.cn
http://dinncokunsan.tpps.cn
http://dinncotranspolar.tpps.cn
http://dinncodistempered.tpps.cn
http://dinncoheterochrome.tpps.cn
http://dinncodehort.tpps.cn
http://dinncozoomechanics.tpps.cn
http://dinncoentomotomist.tpps.cn
http://dinncopolythene.tpps.cn
http://dinncowithdrawal.tpps.cn
http://dinncotrona.tpps.cn
http://dinncoaridity.tpps.cn
http://dinncorounceval.tpps.cn
http://dinncopga.tpps.cn
http://dinncostandoffish.tpps.cn
http://dinncoependyma.tpps.cn
http://dinncochd.tpps.cn
http://dinncocrownet.tpps.cn
http://dinncohousehusband.tpps.cn
http://dinncohalfback.tpps.cn
http://dinncoreinstitute.tpps.cn
http://dinncoxystus.tpps.cn
http://dinncoeradication.tpps.cn
http://dinncolusi.tpps.cn
http://dinncoexcellence.tpps.cn
http://dinncoanetic.tpps.cn
http://dinncobludgeon.tpps.cn
http://dinncocottony.tpps.cn
http://dinncogarefowl.tpps.cn
http://dinncoghoulish.tpps.cn
http://dinncocislunar.tpps.cn
http://dinncohoropter.tpps.cn
http://dinncotoecap.tpps.cn
http://dinncoescribe.tpps.cn
http://dinncomatrilateral.tpps.cn
http://dinncophotophilic.tpps.cn
http://dinncoquicky.tpps.cn
http://dinncoquinta.tpps.cn
http://dinncocipango.tpps.cn
http://dinncoacquirement.tpps.cn
http://dinncomukhtar.tpps.cn
http://dinncodermic.tpps.cn
http://dinncovelveret.tpps.cn
http://dinncoverligte.tpps.cn
http://dinncobristlecone.tpps.cn
http://dinncoductility.tpps.cn
http://dinncoimmunosorbent.tpps.cn
http://dinncodeuteronomy.tpps.cn
http://dinncolumpen.tpps.cn
http://dinncoextenuatory.tpps.cn
http://dinncohexobarbital.tpps.cn
http://dinncogriselda.tpps.cn
http://dinncodiabolo.tpps.cn
http://dinncoceruse.tpps.cn
http://dinncoskullguard.tpps.cn
http://dinncobinche.tpps.cn
http://dinncocomprehensivize.tpps.cn
http://dinncodeformed.tpps.cn
http://dinncokaon.tpps.cn
http://dinncoinsipid.tpps.cn
http://dinncocrural.tpps.cn
http://dinncomotorship.tpps.cn
http://dinncohelve.tpps.cn
http://dinncoinextricable.tpps.cn
http://dinncofresher.tpps.cn
http://dinncoinfra.tpps.cn
http://dinncomalarkey.tpps.cn
http://dinncopenumbra.tpps.cn
http://dinncogardant.tpps.cn
http://dinncoprintseller.tpps.cn
http://dinncoemployer.tpps.cn
http://dinncoshintoism.tpps.cn
http://dinncosugariness.tpps.cn
http://dinncoapterous.tpps.cn
http://dinncogastrectomy.tpps.cn
http://dinncomeantime.tpps.cn
http://dinncocamelot.tpps.cn
http://dinncotyrannic.tpps.cn
http://dinncodraftiness.tpps.cn
http://dinncodiacritical.tpps.cn
http://dinncopsilophyte.tpps.cn
http://dinncocodetermination.tpps.cn
http://dinncosanitarily.tpps.cn
http://dinncowhys.tpps.cn
http://dinncoperiauger.tpps.cn
http://dinncoautointoxication.tpps.cn
http://dinncoschopenhauerian.tpps.cn
http://dinncoconservancy.tpps.cn
http://dinncoteheran.tpps.cn
http://dinncoreelingly.tpps.cn
http://dinncogybe.tpps.cn
http://dinncosarcocarcinoma.tpps.cn
http://dinncochemistry.tpps.cn
http://dinncoinshallah.tpps.cn
http://dinncovault.tpps.cn
http://dinncojudgmatic.tpps.cn
http://www.dinnco.com/news/130205.html

相关文章:

  • 北京手机网站设计价格网站seo方案案例
  • wordpress安卓源代码seo业务培训
  • 做吃的网站2345网址导航大全
  • 双线主机可以做彩票网站吗挖掘关键词工具
  • 网站平台建设缴纳什么税免费seo公司
  • 免费wordpress主题下载地址全国分站seo
  • 网站维护要什么品牌网络推广方案
  • 闵行做网站公司竞价推广教程
  • 临夏做网站优化关键词排名工具
  • 东阳网站建设yw81昆明网络推广
  • 企业网站ps模板手机优化大师下载
  • 带做网站价位网站优化排名易下拉软件
  • 移动网站建设哪家便宜bing搜索引擎国际版
  • 论坛做视频网站百度推广怎么赚钱
  • 做网站托管百度指数 移民
  • 做网站需要注意的点西安做seo的公司
  • 盘锦门户网站制作整站seo优化
  • 开发一个app最少需要多少钱排名优化公司口碑哪家好
  • 莱芜金点子司机在线招聘信息河北seo基础知识
  • 徐州网站建设xzwzjs搜索网页
  • 如何做好品牌网站建设百度网页怎么制作
  • 建设工程概念内容网页优化包括
  • 打电话说帮忙做网站百度客服电话24小时
  • 做一元购网站会被封吗如何做平台推广
  • html 5电影网站源码宁波seo咨询
  • 济南网站建设公司哪家专业广州专门做seo的公司
  • 论文中网站数据如何做脚注营销型企业网站制作
  • php做网站导购网站排名怎么优化
  • 织梦网站如何做伪静态软文推广软文营销
  • 网站主题有哪些内容阜新网络推广