第三节 理解 SpringApplication

合集下载

Spring的ApplicationEvent的使用

Spring的ApplicationEvent的使用

Spring的ApplicationEvent的使用Spring的ApplicationEvent的使用Spring 3.0中提供了很多类似*Aware的类,其中ApplicationContextAware接口可以实现我们在初始化bean的时候给bean注入ApplicationConxt(Spring上下文对象)对象。

ApplicationContextAware接口提供了publishEvent方法,实现了Observe(观察者)设计模式的传播机制,实现了对bean的传播。

通过ApplicationContextAware我们可以把系统中所有ApplicationEvent传播给系统中所有的ApplicationListener。

因此,我们只需要构造好我们自己的ApplicationEvent和ApplicationListener,就可以在系统中实现相应的监听器。

下面以增加学生的示例来演示如何构造Spring的监听器,StudentAddEvent是监听的事件对象,StudentAddListener是事件的监听器(负责处理接收到的监听事件),StudentAddBean负责触发StudentAddEvent事件。

具体步骤如下:1. 定义StudentAddEvent监听事件新建StudentAddEvent类,实现抽象类org.springframework.context.ApplicationEvent StudentAddEvent类中需要实现自己的构造函数,具体代码如下:[java] view plaincopypackage com.trs.spring.event; import org.springframework.context.ApplicationEvent; /** * 增加学生的监听事件*/ public class StudentAddEvent extends ApplicationEvent { /** * */ private static final long serialVersionUID = 20L; /** * 学生姓名*/ private String m_sStudentName; /** * @param source */ public StudentAddEvent(Object source, String _sStudentName){ super(source); this.m_sStudentName = _sStudentName; } /** * 获取学生姓名* * @return */ public String getStudentName() { returnm_sStudentName; } }2. 定义StudentAddListener监听器新建StudentAddListener类,实现接口org.springframework.context.ApplicationListener中的onApplicationEvent方法,在该方法中只处理StudentAddEvent类型的ApplicationEvent事件,代码如下:[java] view plaincopypackage com.trs.spring.event; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; publicclass StudentAddListener implements ApplicationListener{ /* * (non-Javadoc) * * @see*org.springframework.context.ApplicationListener#onApplicatio nEvent(org * .springframework.context.ApplicationEvent) */ public void onApplicationEvent(ApplicationEvent_event) { // 1.判断是否是增加学生对象的事件if (!(_event instanceof StudentAddEvent)){ return; } // 2.是增加学生事件的对象,进行逻辑处理,比如记日志、积分等StudentAddEvent studentAddEvent = (StudentAddEvent)_event; System.out.println("增加了学生:::" + studentAddEvent.getStudentName()); } }3. 定义StudentAddBean触发StudentAddEvent事件新建StudentAddBean类,实现接口org.springframework.context.ApplicationContextAware中的setApplicationContext方法,在构造bean的时候注入Spring的上下文对象,以便通过Spring上下文对象的publishEvent方法来触发StudentAddEvent事件,具体代码如下:[java] view plaincopypackage com.trs.spring.event; importorg.springframework.beans.BeansException; importorg.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware;importorg.springframework.context.support.ClassPathXmlApplication Context; public class StudentAddBean implements ApplicationContextAware { /** * 定义Spring上下文对象*/ private ApplicationContextm_applicationContext = null; /* * (non-Javadoc) * * @see *org.springframework.context.ApplicationContextAware#setApp licationContext *(org.springframework.context.ApplicationContext) */ public void setApplicationContext(ApplicationContext_applicationContext) throws BeansException { this.m_applicationContext =_applicationContext; } /** * 增加一个学生* * @param _sStudentName */ public void addStudent(String _sStudentName) { // 1.构造一个增加学生的事件StudentAddEvent aStudentEvent = newStudentAddEvent( m_applicationContext,_sStudentName); // 2.触发增加学生事件m_applicationContext.publishEvent(aStudentEvent); } /** * @param args */ public static void main(String[] args) { String[] xmlConfig = new String[] { "applicationContext.xml" }; // 使用ApplicationContext来初始化系统ApplicationContext context = new ClassPathXmlApplicationContext( xmlCo nfig); StudentAddBean studentBean = (StudentAddBean)context .getBean("StudentAddBean"); studentBean.addStudent("我是第一个学生"); studentBean.addStudent("第二个学生已经添加"); } }4. applicationContext.xml配置文件<beanid="StudentAddBean"class="com.trs.spring.event.StudentAddBean"></bean&gt ;<bean id="StudentAddListener"class="com.trs.spring.event.StudentAddListener"></bean >。

SpringBootApplication注解原理及代码详解

SpringBootApplication注解原理及代码详解

SpringBootApplication注解原理及代码详解1、SpringBoot 启动main()@SpringBootApplicationpublic class TomcatdebugApplication {public static void main(String[] args) {SpringApplication.run(TomcatdebugApplication.class, args);}}1.1 @SpringBootApplication 注解,其实主要是@ComponentScan,@EnableAutoConfiguration,@SpringBootConfiguration三个注解@ComponentScan 注解:spring⾥有四⼤注解:@Service,@Repository,@Component,@Controller⽤来定义⼀个bean.@ComponentScan注解就是⽤来⾃动扫描被这些注解标识的类,最终⽣成ioc容器⾥的bean.可以通过设置@ComponentScan basePackages,includeFilters,excludeFilters属性来动态确定⾃动扫描范围,类型已经不扫描的类型. 默认情况下:它扫描所有类型,并且扫描范围是@ComponentScan注解所在配置类包及⼦包的类@SpringBootConfiguration 注解:@SpringBootConfiguration继承⾃@Configuration,⼆者功能也⼀致,标注当前类是配置类,并会将当前类内声明的⼀个或多个以@Bean注解标记的⽅法的实例纳⼊到spring容器中,并且实例名就是⽅法名。

demo 说明:(1)注⼊spring ioc bean@SpringBootConfigurationpublic class Config {@Beanpublic Map createMap(){Map map = new HashMap();map.put("username","gxz");map.put("age",27);return map;}}(2)调⽤:public static void main( String[] args ){//⽅式1 获取contextConfigurableApplicationContext context = SpringApplication.run(App.class, args);context.getBean(Runnable.class).run();context.getBean("createMap"); //注意这⾥直接获取到这个⽅法beanint age = (int) map.get("age");System.out.println("age=="+age);//⽅式2. 使⽤@Autowired注解,应⽤bean// @Autowired// Map createMap}@EnableAutoConfiguration 注解@EnableAutoConfiguration作⽤:从classpath中搜索所有的META-INF/spring.factories配置⽂件,然后将其中key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的value加载到spring容器中。

springboot注解@SpringBootApplication分析

springboot注解@SpringBootApplication分析

springboot注解@SpringBootApplication分析@SpringBootApplication注解⽤在Spring Boot的⼊⼝类上⾯,是Spring Boot提供的应⽤启动相关的注解。

直接上注解的源码:@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public @interface SpringBootApplication {@AliasFor(annotation = EnableAutoConfiguration.class, attribute = "exclude")Class<?>[] exclude() default {};@AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName")String[] excludeName() default {};@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")String[] scanBasePackages() default {};@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")Class<?>[] scanBasePackageClasses() default {};}@SpringBootApplication是⼀个复合注解查看源码,可以发现@SpringBootApplication是⼀个复合注解,包含了@SpringBootConfiguration,@EnableAutoConfiguration和@ComponentScan三个注解。

对Spring的理解

对Spring的理解

对Spring的理解1、Spring 是什么?Spring 是⼀个轻量级的 IoC 和 AOP 容器框架。

是为 Java 应⽤程序提供基础性服务的⼀套框架,⽬的是⽤于简化企业应⽤程序的开发,它使得开发者只需要关⼼业务需求。

常见的配置⽅式有三种:基于 XML 的配置、基于注解的配置、基于 Java 的配置。

主要由以下七个模块组成:(CC DAO MW)Spring Core:核⼼类库,提供 IOC 服务;Spring Context:提供框架式的 Bean 访问⽅式,以及企业级功能(JNDI、定时任务等);Spring AOP:AOP 服务;Spring DAO:对 JDBC 的抽象,简化了数据访问异常的处理;Spring ORM:对现有的 ORM 框架的⽀持;Spring Web:提供了基本的⾯向 Web 的综合特性,例如多⽅⽂件上传;Spring MVC:提供⾯向 Web 应⽤的 Model-View-Controller 实现。

2、Spring 的优点?(1)spring 属于低侵⼊式设计,代码的污染极低;(2)spring 的 DI 机制将对象之间的依赖关系交由框架处理,减低组件的耦合性;(3)Spring 提供了 AOP 技术,⽀持将⼀些通⽤任务,如安全、事务、⽇志、权限等进⾏集中式管理,从⽽提供更好的复⽤。

(4)spring 对于主流的应⽤框架提供了集成⽀持。

3、Spring 的 AOP 理解:实际案例:⽇志控制。

AOP,⼀般称为⾯向切⾯,作为⾯向对象的⼀种补充,⽤于将那些与业务⽆关,但却对多个对象产⽣影响的公共⾏为和逻辑,抽取并封装为⼀个可重⽤的模块,这个模块被命名为“切⾯”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提⾼了系统的可维护性。

可⽤于权限认证、⽇志、事务处理。

AOP 实现的关键在于代理模式,AOP 代理主要分为静态代理(拦截器)和动态代理。

(1)Spring AOP 使⽤的动态代理:Spring AOP 中的动态代理主要有两种⽅式,JDK 动态代理和 CGLIB 动态代理:@JDK 动态代理只提供接⼝的代理,不⽀持类的代理。

对Spring的理解

对Spring的理解

对Spring的理解1.是⼀个轻量级的框架,这个轻量级就体现在⾮侵⼊式上,即在代码实现过程中不需要继承Spring框架的相应类或实现相应接⼝。

2.Spring的核⼼就是IOC(控制反转) 和AOP,在Spring中,⽆需再在代码⾥进⾏以new的⽅式来使⽤了,所有的Bean对象都交由IOC容器进⾏管理(Bean实例对象的创建、属性值的设置、初始化、销毁整个⽣命周期都由IOC容器来管理),所以,第⼀个需要明⽩的就是所有的对象放在了⼀个统⼀的地⽅由Spring帮我们管理着。

并且,各个对象中所需要的其他依赖(就是⼀个对象中引⽤的其他对象,成员变量等)是通过依赖注⼊(DI)的⽅式进⾏传递,也就是说⽆需我们调⽤setter⽅法进⾏设置。

使⽤时直接从IOC容器中获取这些对象进⾏使⽤即可。

对象和对象之间的调⽤不会再以 new 这种硬编码的⽅式进⾏关联了,做到了解耦。

3.Spring中IOC容器有两种实现⽅式,⼀种是BeanFactory接⼝定义,⼀种是ApplicationContext接⼝定义(继承于BeanFactory实现)。

我们主要以ApplicationContext为主。

这⾥初始化IOC容器实际上就是创建ApplicationContent上下⽂对象的过程。

即ApplicationContent就表⽰的是IOC容器。

这⾥创建ApplicationContext时需要根据配置⽂件进⾏初始化IOC容器,配置⽂件⾥就是告诉了Spring需要将哪些指定的Bean放到IOC容器中管理起来。

配置的⽅式有多种,从类路径下加载⼀个或多个xml ⽂件、从⼀个或多个基于java的配置类中加载、从⽂件系统下的⼀个或多个xml⽂件中加载。

基本都类似,这⾥我们看下从类路径中加载。

ApplicationContext ctx=new ClassPathXmlApplicationContext("application.xml"),其中ClassPathXmlApplicationContext类为ApplicationContext接⼝的实现类,当然加载⽅式不同,它还有其他的实现类。

spring学习-ApplicationContext-spring上下文深入理解

spring学习-ApplicationContext-spring上下文深入理解

spring学习-ApplicationContext-spring上下⽂深⼊理解4⽉份开始复习⼀遍spring相关知识。

让⾃⼰巩固⼀下spring⼤法的深奥益处,所以就看了⼤佬的博客,转载留下来⽇后继续研读。

认为重点的标记为红⾊Spring有两个核⼼接⼝:BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的⼦接⼝。

他们都可代表Spring容器,Spring容器是⽣成Bean实例的⼯⼚,并且管理容器中的Bean。

Bean是Spring管理的基本单位,在基于Spring的Java EE应⽤中,所有的组件都被当成Bean处理,包括数据源、Hibernate的SessionFactory、事务管理器等。

在Spring中,Bean的是⼀个⾮常⼴义的概念,任何的Java对象、Java组件都被当成Bean处理。

⽽且应⽤中的所有组件,都处于Spring的管理下,都被Spring以Bean的⽅式管理,Spring负责创建Bean实例,并管理他们的⽣命周期。

Bean在Spring容器中运⾏,⽆须感受Spring容器的存在,⼀样可以接受Spring的依赖注⼊,包括Bean属性的注⼊,协作者的注⼊、依赖关系的注⼊等。

Spring容器负责创建Bean实例,所以需要知道每个Bean的实现类,Java程序⾯向接⼝编程,⽆须关⼼Bean实例的实现类;但是Spring容器必须能够精确知道每个Bean实例的实现类,因此Spring配置⽂件必须精确配置Bean实例的实现类。

⼀、Spring容器Spring容器最基本的接⼝就是BeanFactor。

BeanFactory负责配置、创建、管理Bean,他有⼀个⼦接⼝:ApplicationContext,因此也称之为Spring上下⽂。

Spring容器负责管理Bean与Bean之间的依赖关系。

BeanFactory接⼝包含以下⼏个基本⽅法:Ø Boolean containBean(String name):判断Spring容器是否包含id为name的Bean实例。

spring学习(十二)--spring中WebApplicationInitializer解析

spring学习(十二)--spring中WebApplicationInitializer解析

spring学习(⼗⼆)--spring中WebApplicationInitializer解析 上⽂中讲解了如何通过WebApplicationInitializer取代Web.xml进⾏spring容器的启动,WebApplicationInitializer是⼀个接⼝,通过实现WebApplicationInitializer,在其中可以添加servlet,listener等。

在Web容器启动的时候,spring-web会通过SPI机制,加载这个接⼝的实现类,从⽽起到web.xml相同的作⽤。

下⾯就看⼀下这个接⼝的详细内容:public interface WebApplicationInitializer {void onStartup(ServletContext servletContext) throws ServletException;}WebApplicationInitializer只有⼀个⽅法,⽐较简单,看不出什么头绪。

在WebApplicationInitializer同级别有个SpringServletContainerInitializer类,我们来看下这个类的代码:package org.springframework.web;@HandlesTypes(WebApplicationInitializer.class)public class SpringServletContainerInitializer implements ServletContainerInitializer {@Overridepublic void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)throws ServletException {List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>();if (webAppInitializerClasses != null) {for (Class<?> waiClass : webAppInitializerClasses) {// Be defensive: Some servlet containers provide us with invalid classes,// no matter what @HandlesTypes says...if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&WebApplicationInitializer.class.isAssignableFrom(waiClass)) {try {initializers.add((WebApplicationInitializer) waiClass.newInstance());}catch (Throwable ex) {throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);}}}}if (initializers.isEmpty()) {servletContext.log("No Spring WebApplicationInitializer types detected on classpath");return;}AnnotationAwareOrderComparator.sort(initializers);servletContext.log("Spring WebApplicationInitializers detected on classpath: " + initializers);for (WebApplicationInitializer initializer : initializers) { //这⾥指定了调⽤的类的⽅法,onStartup()initializer.onStartup(servletContext);}}}SpringServletContainerInitializer这个类⾥也有个onStartup⽅法,看⼀下它的逻辑。

application 怎么读

application 怎么读

application 怎么读
“application”是一个英语单词,发音为英式音标/ˌæplɪˈkeɪʃn/ 和美式音标/ˌæplɪˈkeɪʃn/。

这个单词的发音可以拆分为两个音节:“ap-”和“-plication”,并在“ap-”上放置重音。

在发音时,注意保持整个单词的音调平稳,并清晰地发出每个音节。

“application”的基本含义是“申请”或“请求”,它通常用于描述个人或组织向另一方提出的正式请求或申请。

这个单词在求职、入学、贷款等场合中非常常见,比如填写“application form”(申请表)或发送“application letter”(申请信)。

此外,“application”还可以表示“应用”或“使用”的意思,即如何利用某种知识、技能或工具来实现特定目的。

例如,在科技领域,“application”可以指代手机或电脑上的“应用程序”(app),这些程序可以帮助用户完成各种任务,如浏览网页、编辑文档、玩游戏等。

除此之外,“application”还可以表示“适用性”或“实用性”,即某物或某方法是否适合用于特定情境或目的。

这个含义通常用于评估某种理论、技术或产品的实际应用价值。

总之,“application”是一个具有多种含义的单词,可以用于各种语境中描述申请、应用、使用以及适用性和实用性等概念。

在发音时,注意将重音放在正确的音节上,并保持清晰的发音。

同时,在
使用时也需要注意具体语境和语法规则,以确保表达的准确性和清晰度。

Spring事件,ApplicationEvent在业务中的应用

Spring事件,ApplicationEvent在业务中的应用

Spring事件,ApplicationEvent在业务中的应⽤前⾔关于事件驱动模型,百度百科在有明确的解释。

在JDK的Util包⾥抽象了事件驱动,有兴趣的朋友可以⾃⾏去看下相关类的定义。

Spring事件模型ApplicationEvent是基于JDK⾥的事件模型,废话不多说,直接看Spring是如何定义事件模型,以及在具体业务场景中的应⽤。

事件事件就是事件,⿏标点击⼀下算⼀个事件,某个按钮被点击了⼀下算⼀个点击事件,那么我订单⽀付了可以认为⽀付也算⼀个件事!触发了某个事件...... 等等。

抽象类ApplicationEvent承载着我们要传播的事件或者消息,⽩话就是说可以把某个对象⽤ApplicationEvent这个对象来⾥的Source来引⽤。

监听者上⾯我们定义了事件,那么事件产⽣的⼀系列的效应或者是变动,那么都由这些监听者们去实现。

点击下⿏标(事件),那么我记录下⽇志,你弹出个提⽰框。

⽀付某个订单(事件),我记录下记录,他发送个⽀付通知...... 等等。

泛型接⼝ApplicationListener规定了泛型E的上边界为ApplicationEvent,意思很明确,就是给我们⾃定义事件⽤的。

Spring最⼤的优点我认为是留给⽤户发挥的空间很⼤,就像神秘的海洋⼀样,它⼀直有你探索不完的秘密,每⼀次你去了解它,它都能给你带来新的事物和理解。

实战⽂章中,我们⽤SpringPlugin插件的⽅式去实现了订单的不同操作!⽽在某个操作⾥⾯,我们可能⼜要发送操作事件的通知,⽐如:订单⽀付了后,要通知打印机打印⼩票、微信公众号提醒⽀付信息等等。

那么我们来实际的操作下。

定义事件源public class OrderPayedEvent extends ApplicationEvent {/*** 消息体,这⾥就设定为当前订单对象*/private final Order order;public OrderPayedEvent(Object source) {super(source);this.order = (Order) source;}public Order getOrder() {return order;}}实现ApplicationEvent,我这⾥Source实际传递就是Order对象,当然你也可以定义其他的多参数构造函数!定义监听者定义监听者的⽅式,Spring提供了两种,⼀种是接⼝⽅式,⼀种是注解⽅式。

SpringBoot-application:application.yml配置文件详解

SpringBoot-application:application.yml配置文件详解

SpringBoot-application:application.yml配置⽂件详解springboot采纳了建⽴⽣产就绪应⽤程序的观点。

Spring Boot优先于配置的惯例,旨在让您尽快启动和运⾏。

在⼀般情况下,我们不需要做太多的配置就能够让spring boot正常运⾏。

在⼀些特殊的情况下,我们需要做修改⼀些配置,或者需要有⾃⼰的配置属性。

1.1、⼀、⾃定义属性当我们创建⼀个springboot项⽬的时候,系统默认会为我们在src/main/Java/resources⽬录下创建⼀个application.properties。

个⼈习惯,我会将application.properties改为application.yml⽂件,两种⽂件格式都⽀持。

在application.yml⾃定义⼀组属性:my:name: forezpage: 12如果你需要读取配置⽂件的值只需要加@Value(“${属性名}”):@RestControllerpublic class MiyaController {@Value("${}")private String name;@Value("${my.age}")private int age;@RequestMapping(value = "/miya")public String miya(){return name+":"+age;}}启动⼯程,访问:localhost:8080/miya,浏览器显⽰:forezp:12⼆、将配置⽂件的属性赋给实体类当我们有很多配置属性的时候,这时我们会把这些属性作为字段来创建⼀个javabean,并将属性值赋予给他们,⽐如:my:name: forezpage: 12number: ${random.int}uuid : ${random.uuid}max: ${random.int(10)}value: ${random.value}greeting: hi,i'm ${}其中配置⽂件中⽤到了${random} ,它可以⽤来⽣成各种不同类型的随机值。

spring成神之路第三篇:Spring容器基本使用及原理(ApplicationCont。。。

spring成神之路第三篇:Spring容器基本使用及原理(ApplicationCont。。。

spring成神之路第三篇:Spring容器基本使⽤及原理(ApplicationCont。

1. jdk1.82. idea3. maven-3.6.14. spring-5.2.3.RELEASEIOC容器是具有依赖注⼊功能的容器,负责对象的实例化、对象的初始化,对象和对象之间依赖关系配置、对象的销毁、对外提供对象的查找等操作,对象的整个⽣命周期都是由容器来控制。

我们需要使⽤的对象都由ioc容器进⾏管理,不需要我们再去⼿动通过new的⽅式去创建对象,由ioc 容器直接帮我们组装好,当我们需要使⽤的时候直接从ioc容器中直接获取就可以了。

那么spring ioc容器是如何知道需要管理哪些对象呢?需要我们给ioc容器提供⼀个配置清单,这个配置⽀持xml格式和java注解的⽅式,在配置⽂件中列出需要让ioc容器管理的对象,以及可以指定让ioc容器如何构建这些对象,当spring容器启动的时候,就会去加载这个配置⽂件,然后将这些对象给组装好以供外部访问者使⽤。

这⾥所说的IOC容器也叫spring容器。

由spring容器管理的对象统称为Bean对象。

Bean就是普通的java对象,和我们⾃⼰new的对象其实是⼀样的,只是这些对象是由spring去创建和管理的,我们需要在配置⽂件中告诉spring容器需要创建哪些bean对象,所以需要先在配置⽂件中定义好需要创建的bean对象,这些配置统称为bean定义配置元数据信息,spring容器通过读取这些bean配置元数据信息来构建和组装我们需要的对象。

1. 引⼊spring相关的maven配置2. 创建bean配置⽂件,⽐如bean xml配置⽂件3. 在bean xml⽂件中定义好需要spring容器管理的bean对象4. 创建spring容器,并给容器指定需要装载的bean配置⽂件,当spring容器启动之后,会加载这些配置⽂件,然后创建好配置⽂件中定义好的bean对象,将这些对象放在容器中以供使⽤5. 通过容器提供的⽅法获取容器中的对象,然后使⽤spring内部提供了很多表⽰spring容器的接⼝和对象,我们来看看⽐较常见的⼏个容器接⼝和具体的实现类。

Spring事件ApplicationEvent原理详解

Spring事件ApplicationEvent原理详解

Spring事件ApplicationEvent原理详解这篇⽂章主要介绍了Spring 事件Application Event原理详解,⽂中通过⽰例代码介绍的⾮常详细,对⼤家的学习或者⼯作具有⼀定的参考学习价值,需要的朋友可以参考下Spring 的事件(Application Event)为 Bean 与 Bean 之间的消息通信提供了⽀持。

当⼀个 Bean 处理完⼀个任务之后,希望另⼀个 Bean 知道并能做相应的处理,这时我们就需要让另⼀个 Bean 监听当前 Bean 所发送的事件。

(观察者模式)Spring 的事件需要遵循以下流程:⾃定义事件,集成 ApplicationEvent。

定义事件监听器,实现 ApplicationListener。

使⽤容器发布事件。

以下代码基于 Spring Boot 实现⾃定义事件public class DemoEvent extends ApplicationEvent {private static final long serialVersionUID = 1L;private String msg;public DemoEvnet(Object source, String msg) {super(source);this.msg = msg;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}}事件监听者@Componentpublic class DemoListener implements ApplicationListener<DemoEvent> {public void onApplicationEvent(DemoEvent event) {String msg = event.getMsg();System.out.println("接收到了消息:" + msg);}}代码解释:实现 ApplicaionListener 接⼝,并制定监听的时间类型。

spring中AbstractApplicationContext讲解

spring中AbstractApplicationContext讲解

AbstractApplicationContextApplicationContext的抽象实现,这里采用了模版方法的设计模式,需要具体的子类去具体实现这些抽象方法。

这个类中,最重要的就是refresh()方法,虽然其中很多方法都需要子类去实现,但是,我们还是需要对其中调用的方法做一个详细的说明!1.protected void prepareRefresh() {this.startupDate = System.currentTimeMillis();synchronized (this.activeMonitor) {this.active = true;}if (logger.isInfoEnabled()) {("Refreshing " + this);}}●这个方法有个比较重要的地方,就是this,通过日志记录getClass(),我们发现,这个this并不是AbstractApplicationContext,而是ClassPathXmlApplicationContext(这个地方,在我以前的关于class的说明中有,一定要记住)!●再一个就是,当我()出来的结果让我有点意外,如下:Refreshingorg.springframework.context.support.ClassPathXmlApplicationContext@85 af80: display name [org.springframework.context.support.ClassPathXmlApplicationContext@8 5af80]; startup date [Tue Sep 28 11:38:55 CST 2010]; root of context hierarchy我们可以想象,不可能每个类都有startup date的东西,为什么会出现这样的情况呢?通过分析,我们发现,所有的java 类都是继承了object类,而这个object类中有个toString()方法,我们看看源代码:public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}从这里可以知道,在display name 之前的部分才应该是toString()应该显示的东西,到这里,我们就可以怀疑,是否是AbstractApplicationContext重写了这个toString()方法呢?往后看,果然发现是这样,代码如下:public String toString() {StringBuffer sb = newStringBuffer(ObjectUtils.identityToString(this));sb.append(": display name [").append(getDisplayName());sb.append("]; startup date [").append(newDate(getStartupDate()));sb.append("]; ");ApplicationContext parent = getParent();if (parent == null) {sb.append("root of context hierarchy");}else {sb.append("parent:").append(ObjectUtils.identityToString(parent));}return sb.toString();}注:()需要的参数是String类型的,如果带的参数不是String类型的,那么JAVA会自动给予转换,就相当于自动调用toString()方法!2.protected final void refreshBeanFactory() throws BeansException {// Shut down previous bean factory, if any.ConfigurableListableBeanFactory oldBeanFactory = null;synchronized (this.beanFactoryMonitor) {oldBeanFactory = this.beanFactory;}if (oldBeanFactory != null) {oldBeanFactory.destroySingletons();synchronized (this.beanFactoryMonitor) {this.beanFactory = null;}}// Initialize fresh bean factory.try {DefaultListableBeanFactory beanFactory =createBeanFactory();customizeBeanFactory(beanFactory);loadBeanDefinitions(beanFactory);synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing XML document for application context [" + getDisplayName() + "]", ex);}}3.protected void loadBeanDefinitions(DefaultListableBeanFactorybeanFactory) throws IOException {// Create a new XmlBeanDefinitionReader for the given BeanFactory.XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);// Configure the bean definition reader with this context's// resource loading environment.beanDefinitionReader.setResourceLoader(this);beanDefinitionReader.setEntityResolver(newResourceEntityResolver(this));// Allow a subclass to provide custom initialization of the reader,// then proceed with actually loading the bean definitions.initBeanDefinitionReader(beanDefinitionReader);loadBeanDefinitions(beanDefinitionReader);}下面讲解在加载数据中很重要的类Resource及其衍生类:Spring中的org.springframework.core.io.Resource接口代表着物理存在的任何资源,其继承于org.springframework.core.io.InputStreamSource;其子类有如下几种:ByteArrayResource, ClassPathResource, DescriptiveResource, FileSystemResource, InputStreamResource, PortletContextResource, ServletContextResource, UrlResource 。

Application详解与用法

Application详解与用法

Application详解与用法1:Application是什么?Application和Activity,Service一样,是android框架的一个系统组件,当android程序启动时系统会创建一个application对象,用来存储系统的一些信息。

通常我们是不需要指定一个Application的,这时系统会自动帮我们创建,如果需要创建自己的Application,也很简单创建一个类继承Application并在manifest的application标签中进行注册(只需要给Application标签增加个name属性把自己的Application的名字定入即可)。

android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,所以Application可以说是单例(singleton)模式的一个类.且application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。

因为它是全局的单例的,所以在不同的Activity,Service中获得的对象都是同一个对象。

所以通过Application来进行一些,数据传递,数据共享等,数据缓存等操作。

2:通过Application传递数据假如有一个Activity A, 跳转到Activity B ,并需要推荐一些数据,通常的作法是Intent.putExtra() 让Intent携带,或者有一个Bundle 把信息加入Bundle让Intent推荐Bundle对象,实现传递。

但这样作有一个问题在于,Intent和Bundle所能携带的数据类型都是一些基本的数据类型,如果想实现复杂的数据传递就比较麻烦了,通常需要实现Serializable或者Parcellable接口。

这其实是Android的一种IPC 数据传递的方法。

如果我们的两个Activity在同一个进程当中为什么还要这么麻烦呢,只要把需要传递的对象的引用传递过去就可以了。

SpringBoot(一)SpringBootApplication注解详解

SpringBoot(一)SpringBootApplication注解详解

SpringBoot(⼀)SpringBootApplication注解详解@SpringBootApplicationSpringBootApplication注解我们肯定不会陌⽣,在配置SpringBoot的启动类时就会⽤到这个注解,下⾯就说⼀下SpringBootApplication注解的详细作⽤@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })打开SpringBootApplication注解我们可以看到在注解下包含以上三个注解,那么简单说明下以上三个注解的具体作⽤1.@Configuration:⽤于定义⼀个配置类2.@EnableAutoConfiguration :Spring Boot会⾃动根据你jar包的依赖来⾃动配置项⽬。

3.@ComponentScan:告诉Spring 哪个packages 的⽤注解标识的类会被spring⾃动扫描并且装⼊bean容器。

在我们初学SpringBoot的时候我们可能都会遇到⼀个问题,就是定义了⼀个请求,但是SpringBoot并没有装配成功,导致请求失败代码如下(1) 启动类代码:@SpringBootApplication@ComponentScanpublic class HelloWorldMainApplication {public static void main(String[] args) {SpringApplication.run(HelloWorldMainApplication.class, args);}}(2)请求1代码@Controllerpublic class HelloController {@ResponseBody@RequestMapping("/hello")public String Hello(){return "Hello World";}}(2)请求2代码@Controllerpublic class TestController {@ResponseBody@RequestMapping("/test")public String Test(){return "Hello Test";}}(3)⽬录结构从上图的⽬录结构我们可以看到请求1HelloController所在的⽬录是跟HelloWorldMainApplication启动类属于同级⽬录,⽽请求2TestController所在⽬录是com包下也就是请求1和启动类的⽗级⽬录,下⾯启动项⽬并发送请求看下结果(4)控制台(5)请求1(6)请求2其实从控制台我们就可以看到hello请求是被Spring扫描到⽽test请求并没有被扫描到,所以test请求肯定会出现404请求失败这种结果,那么SpringBoot为什么只能扫描同级⽬录和⼦集⽬录呢?如果我们想扫描指定⽬录下的⽂件该怎么做,看下图public void registerBeanDefinitions(AnnotationMetadata metadata,BeanDefinitionRegistry registry) {register(registry, new PackageImport(metadata).getPackageName());}这段代码就是SpringBoot在启动类中默认扫描包路径的配置,所在路径(点击@SpringBootApplication注解---点击@EnableAutoConfiguration注解---点击@AutoConfigurationPackage---点击@Import(AutoConfigurationPackages.Registrar.class)),其实看到这个⽅法名我们应该不会感到陌⽣,因为Spring载⼊IOC容器的⽅法不就是BeanDefinition么,SpringBoot是基于Spring的所以这点就不难理解了从上图我们可以看到所得到的值是com.main也就可以说明为什么@SpringBootApplication默认扫描同级以及⼦级⽬录,⽽test请求在⽗级⽬录所以扫描不到请求⾃然会出现404的错误,那么如何扫描指定⽬录的包呢?看下⾯代码@ComponentScan(basePackages = {"com"})@SpringBootApplication(scanBasePackages = {"com"})这俩种⽅式都可以扫描指定⽬录下的包,多个包⽤逗号分隔即可。

SpringBoot启动流程(一)SpringApplication类的构造函数

SpringBoot启动流程(一)SpringApplication类的构造函数

SpringBoot启动流程(一)SpringApplication类的构造函数SpringApplication类是SpringBoot启动流程的核心类之一,它负责启动Spring应用程序。

在本文中,我们将详细讨论SpringApplication类的构造函数,并深入了解其在应用程序启动过程中的重要作用。

SpringApplication类的构造函数用于创建一个新的SpringApplication实例,它接收一个或多个参数。

具体来说,SpringApplication类的构造函数有两个重要的参数:一个是主要配置类,另一个是一组字符串参数。

另一个重要的参数是一组字符串参数。

这些字符串参数通常用于传递命令行参数,用于配置应用程序的行为。

在构造函数中,我们可以将这些字符串参数传递给SpringApplication,以便在应用程序启动时使用它们。

一旦创建了SpringApplication实例,我们可以调用其run方法来启动应用程序。

run方法是SpringBoot启动流程的关键方法,在应用程序启动过程中执行一系列的操作。

首先,run方法会创建一个SpringApplicationRunListeners列表,并使用SpringFactoriesLoader类加载运行监听器。

运行监听器是一种扩展机制,允许我们以插件形式添加自定义逻辑。

监听器可以在应用程序启动的各个阶段介入,并执行特定的任务。

例如,我们可以编写一个监听器,用于在应用程序启动时初始化数据库连接池。

接下来,run方法会创建一个SpringBootExceptionReporter实例,并在发生相关异常时使用它。

SpringBootExceptionReporter是一个接口,用于处理应用程序启动过程中的异常。

我们可以自定义一个实现,以便在异常发生时采取适当的措施。

然后,run方法会创建一个ConfigurableEnvironment实例,并将其与主要配置类关联起来。

applicationlistener原理

applicationlistener原理

applicationlistener原理ApplicationListener是Spring框架中一个比较重要的组件,它是一个接口,可以用来接收各种事件的通知。

它是一个抽象类,可以让它的子类实现不同的事件处理逻辑。

它的实现可以通过继承ApplicationListener抽象类并实现onApplicationEvent方法,来接收来自ApplicationContext的时间通知,也可以通过@EventListener注解,来实现自动接收来自ApplicationContext的时间通知。

ApplicationListener是Spring中发布、订阅模式的一种体现。

发布者通过ApplicationContext发布事件,而订阅者(ApplicationListener)通过实现onApplicationEvent方法来接收这些事件通知,从而达到解耦的目的,实现各个组件的事件通信。

ApplicationListener工作原理主要分为以下3个步骤:1. 事件发布ApplicationContext在初始化的过程中,会将自己注册为一个事件发布者,以便之后发布事件,每当ApplicationContext发布事件时,就会调用自身的publishEvent方法,将当前要发布的事件封装成ApplicationEvent,然后将其转发给内部的ApplicationEventMulticaster(事件广播器),然后由ApplicationEventMulticaster负责将事件发布给所有的ApplicationListener。

2. 事件接收订阅者(ApplicationListener)可以通过实现ApplicationListener抽象类,重写onApplicationEvent方法,来接收来自ApplicationContext的时间通知;也可以采用@EventListener注解的方式,将一个普通的方法标注为@EventListener,以此注解的方式可以接收ApplicationContext发布的指定类型的事件。

springboot源码分析之SpringApplication

springboot源码分析之SpringApplication

springboot源码分析之SpringApplicationspring boot提供了sample程序,学习spring boot之前先跑⼀个最简单的⽰例:/** Copyright 2012-2016 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** /licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package sample.simple;import sample.simple.ExitException;import sample.simple.service.HelloWorldService;import org.springframework.beans.factory.annotation.Autowired;import mandLineRunner;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.AnnotationConfigApplicationContext;@SpringBootApplicationpublic class SampleSimpleApplication implements CommandLineRunner {// Simple example shows how a command line spring application can execute an// injected bean service. Also demonstrates how you can use @Value to inject// command line args ('--name=whatever') or application properties@Autowiredprivate HelloWorldService helloWorldService;public void run(String... args) {System.out.println(this.helloWorldService.getHelloMessage());if (args.length > 0 && args[0].equals("exitcode")) {throw new ExitException();}}public static void main(String[] args) throws Exception {SpringApplication application = new SpringApplication(SampleSimpleApplication.class);application.setApplicationContextClass(AnnotationConfigApplicationContext.class);SpringApplication.run(SampleSimpleApplication.class, args);}}可以发现在主⽅法main⾥启动了⼀个SpringApplication,启动⽅法是run⽅法。

SpringApplicationListener的使用详解

SpringApplicationListener的使用详解

SpringApplicationListener的使⽤详解介绍Spring ApplicationListener 是Spring事件机制的⼀部分,与ApplicationEvent抽象类结合完成ApplicationContext的事件通知机制.ContextRefreshedEvent事件监听以Spring的内置事件ContextRefreshedEvent为例,当ApplicationContext被初始化或刷新时,会触发ContextRefreshedEvent事件.如下代码⽰例:@Componentpublic class LearnListener implements ApplicationListener<ContextRefreshedEvent> {@Overridepublic void onApplicationEvent(ContextRefreshedEvent event) {//获取所有的beanString[] definitionNames = event.getApplicationContext().getBeanDefinitionNames();for (String name : definitionNames) {//打印名称System.out.println("name = " + name);}}}⾃定义事件代码//继承ApplicationEvent 抽象类就可以⾃定义事件模型public class MyEvent extends ApplicationEvent {private Long id;private String message;public MyEvent(Object source) {super(source);}public MyEvent(Object source, Long id, String message) {super(source);this.id = id;this.message = message;}//get set ⽅法省略}//实现ApplicationListener接⼝@Componentpublic class MyListener implements ApplicationListener<MyEvent> {@Overridepublic void onApplicationEvent(MyEvent event) {System.out.println("监听到事件: "+event.getId()+"\t"+event.getMessage());}}测试@SpringBootTest@RunWith(SpringRunner.class)public class ListenerTest {@Autowiredprivate ApplicationContext applicationContext;@Testpublic void testListenner() {MyEvent myEvent = new MyEvent("myEvent", 9527L, "⼗⼆点了该吃饭了~");applicationContext.publishEvent(myEvent);// System.out.println("发送结束");}}结果到此这篇关于Spring ApplicationListener的使⽤详解的⽂章就介绍到这了,更多相关Spring ApplicationListener 内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

配置 Spring Boot Bean 源
Java 配置 Class 或 XML 上下文配置文件集合,用于 Spring Boot BeanDefinitionLoader读取,并且将配置源解析加载为Spring Bean 定义
数量:一个或多个以上
Java 配置 Class
用于 Spring 注解驱动中 Java 配置类,大多数情况是 Spring 模式注解所标注的类,如@Configuration。

XML 上下文配置文件
用于 Spring 传统配置驱动中的 XML 文件。

推断 Web 应用类型
根据当前应用 ClassPath 中是否存在相关实现类来推断 Web 应用的类型,包括:
Web Reactive :WebApplicationType.REACTIVE
Web Servlet:WebApplicationType.SERVLET
非 Web:WebApplicationType.NONE
参考方法:org.springframework.boot.SpringApplication#deduceWebApplicationType
private WebApplicationType deduceWebApplicationType() {
if (ClassUtils.isPresent(REACTIVE_WEB_ENVIRONMENT_CLASS, null)
&&!ClassUtils.isPresent(MVC_WEB_ENVIRONMENT_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
for (String className : WEB_ENVIRONMENT_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
return WebApplicationType.SERVLET;
}
推断引导类(Main Class)
根据 Main 线程执行堆栈判断实际的引导类
参考方法:org.springframework.boot.SpringApplication#deduceMainApplicationClass
private Class<?>deduceMainApplicationClass() {
try {
StackTraceElement[] stackTrace=new RuntimeException().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
if ("main".equals(stackTraceElement.getMethodName())) {
return Class.forName(stackTraceElement.getClassName());
}
}
}
catch (ClassNotFoundException ex) {
// Swallow and continue
}
return null;
}
加载应用上下文初始器(ApplicationContextInitializer)利用 Spring 工厂加载机制,实例化ApplicationContextInitializer实现类,并排序对象集合。

实现
private<T>Collection<T>getSpringFactoriesInstances(Class<T>type,
Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader=Thread.currentThread().getContextClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String>names=new LinkedHashSet<>(
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T>instances=createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
技术
实现类:org.springframework.core.io.support.SpringFactoriesLoader
配置资源:META-INF/spring.factories
排序:AnnotationAwareOrderComparator#sort
加载应用事件监听器(ApplicationListener)
利用 Spring 工厂加载机制,实例化ApplicationListener实现类,并排序对象集合
SpringApplication 运行阶段
加载SpringApplication运行监听器(SpringApplicationRunListeners)
利用 Spring 工厂加载机制,读取SpringApplicationRunListener对象集合,并且封装到组合类SpringApplicationRunListeners
运行SpringApplication运行监听器(SpringApplicationRunListeners)
SpringApplicationRunListener监听多个运行状态方法:
监听方法阶段说明Spring Boot 起始版本starting()Spring 应用刚启动 1.0
environmentPrepared(ConfigurableEnvironment)ConfigurableEnvironment准备妥当,允许将其调整 1.0
contextPrepared(ConfigurableApplicationContext)ConfigurableApplicationContext准备妥当,允许将其调整 1.0
contextLoaded(ConfigurableApplicationContext)ConfigurableApplicationContext已装载,但仍未启动 1.0
started(ConfigurableApplicationContext)ConfigurableApplicationContext已启动,此时 Spring Bean 已初始化完成 2.0
running(ConfigurableApplicationContext)Spring 应用正在运行 2.0
failed(ConfigurableApplicationContext,Throwable)Spring 应用运行失败 2.0
监听 Spring Boot 事件 / Spring 事件
Spring Boot 通过SpringApplicationRunListener 的实现类EventPublishingRunListener利用 Spring Framework 事件API ,广播 Spring Boot 事件。

Spring Framework 事件/监听器编程模型
Spring 应用事件
普通应用事件:ApplicationEvent
应用上下文事件:ApplicationContextEvent
Spring 应用监听器
接口编程模型:ApplicationListener
注解编程模型:@EventListener
Spring 应用事广播器
接口:ApplicationEventMulticaster
实现类:SimpleApplicationEventMulticaster
执行模式:同步或异步。

相关文档
最新文档