一。springboot简介
Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。
二。springboot容器
spring容器提供了bean的创建和管理 spring沿用spring容器 提供了简化的操作方式 全程使用注解 以下通过实例讲解bean的管理 构建项目使用maven
1》helloworld
使用maven建立普通的maven jar项目
》》pom.xml内容(可以通过sts生成)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.et</groupId>
<artifactId>sb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>sb</name>
<description></description>
<!--集成springboot的父项目 统一进行版本管理-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.version>
</properties>
<!--springbbot添加web支持 spring所有的库 基本使用spring-boot-starter开头
所有库参考 https://docs.spring.io/spring-boot/docs/1.5.7.RELEASE/reference/htmlsingle/#using-boot-starter
-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--springboot测试库-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!--springboot项目发布 使用spring-boot-maven-plugin插件-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
创建包 cn.et.learn01创建类SbApplication 用于启动springboot
@ComponentScan("cn.et.learn01") 自动扫描和装配 (@Controller Component等) @ComponentScan指定扫描特定的包 默认是扫描当前main的子包
@EnableAutoConfiguration 启用自动配置 后续讲解
public class SbApplication {
public static void main(String[] args) {
SpringApplication.run(SbApplication.class, args);
}
}
添加springmvc的控制类 cn.et.learn01.controller.TestController 默认springboot只会扫描启动类相同包或者子包中带有注解的bean
package cn.et.learn01.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import cn.et.learn01.resource.MyConfig;
import cn.et.learn01.resource.MyConfigSource;
@RestController
public class TestController {
@GetMapping("/query/{id}")
public String query(@PathVariable String id) {
return "hello"+id;
}
}
运行主类 SbApplication 通过日志查看发现默认启动了tomcat端口 8080
访问 http://localhost:8080/query/123 发现打印 hello123
springboot默认读取src/main/resources下的application.properties或者application.yml文件 该文件时springboot的配置文件
比如配置端口 server.port=80 可以修改tomcat端口 其他配置参考springboot官方文档
(https://docs.spring.io/spring-boot/docs/1.5.7.RELEASE/reference/htmlsingle/#common-application-properties)
2》springboot自动扫描和装配
springboot自动扫描沿用spring的方式 @ComponentScan扫描某个包及其子包下所有带有 spring常用注解的类 并自动创建bean
也可以使用 @SpringBootApplication自动扫描当前主类当前包和子包下所有的注解类SpringBootApplication 也是由hello程序这些注解组成 查看源码
@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 {其他代码不贴出}
bean和bean之间自动装配只用 @AutoWired或者@Resouce 比如修改TestController类 添加容器ApplicationContext 就可以通过容器获取其他bean信息
@Autowired
ApplicationContext ac;
3》springboot资源文件读取
资源文件读取
@Value直接获取所有导入的资源文件 默认资源文件 application.properties
@PropertySource 指定加载的properties文件 这些加载的文件和 application.properties的键值对
都可以使用 @Value获取 已经加载的后面的不能覆盖
@ConfigurationProperties 指定就某些前缀的资源 自动装配到属性中 不需要使用 @Value注解
实例测试
src/main/resources添加资源文件 a.properties
my1.name=ls
my1.sex=girl
my.jj=large
application.properties中添加
my.name=zs
my.sex=boy
添加类 MyConfigSource.java
package cn.et.learn01.resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource("classpath:a.properties") //将a.properties中的键值对 写入spring容器环境中
public class MyConfigSource {
@Value("${my1.name}") //通过Value注解 使用表达式获取
private String name;
@Value("${my1.sex}")
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
使用 @ConfigurationProperties 可以不使用@Value
创建类MyConfig
package cn.et.learn01.resource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource("classpath:a.properties")
@ConfigurationProperties(prefix="my") //此时my前缀开头的 my.name和my.sex在application.properties中 my.jj在 a.properties都能正常读取
public class MyConfig {
private String name;
private String sex;
private String jj;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getJj() {
return jj;
}
public void setJj(String jj) {
this.jj = jj;
}
}
修改TestController注入两个bean
package cn.et.learn01.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import cn.et.learn01.resource.MyConfig;
import cn.et.learn01.resource.MyConfigSource;
@RestController
public class TestController {
@Autowired
MyConfig config;
@Autowired
MyConfigSource configSource;
@GetMapping("/query/{id}")
public String query(@PathVariable String id) {
return "hello"+config.getName()+"=>"+configSource.getName()+"=>"+config.getJj();
}
}
正常输出配置文件中的数据 说明成功读取配置文件
3》@Configuration动态注入bean
使用 @Compont等注解注入的bean不能进行一些复杂 动态的参数处理 使用 @Configuration可以做到
在spring中bean的定义一般为
spring.xml
<beans>
<bean id="user" class="cn.e.User"/>
<bean id="role" class="cn.e.Role"/>
</beans>
使用注解来配置(这里假设存在User和Role这两个类 )
package cn.et.learn02.resource;
import cn.e.User
import cn.e.Role
/**
@ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)
@ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)
@ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean)
@ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)
@ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)
@ConditionalOnNotWebApplication(不是web应用)
* @author jiaozi
*
*/
//如果在类路径上存在MyConfig 才创建bean
@ConditionalOnClass(User.class)
@Configuration
public class MyConfiguration {
//没有myUser 这个bean就创建
@ConditionalOnMissingBean(name="myUser")
@Bean
public User myUser() {
User my=new User();
return my;
}
@Bean
public Role myRole() {
Role my=new Role();
return my;
}
}
如果在一个
@Configuration引用其他的包下 @Configuration标注的类 可以使用
@Import注解导入 导入的类可以没有@Configuration注解
三。springboot自动配置
通过研究@EnableAutoConfiguration源码 发现spring-boot-autoconfigure-1.5.7.RELEASE.jar/META-INF下存在一个spring.factories 其中定义了所有的自动启动的配置类 org.springframework.boot.autoconfigure.EnableAutoConfiguration=@Configuration注解的类实际上就是springboot默认不扫描jar包中的@Configuration注解的类 而是通过 EnableAutoConfiguration读取 该配置文件下配置的类
# 初始化器 创建ApplicationContext对象 调用refresh方法创建并实例之前 可以进行一些bean的定义修改等此时只有bean的定义 还没有实例化
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
# 启动事件监听
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer
# 存在配置类被导入后触发的监听
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
# 配置导入过滤器
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnClassCondition
# 启动时自动装载到容器的bean类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,\
org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,\
org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,\
org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration
# 出现异常后的报告输出格式类
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.DataSourceBeanCreationFailureAnalyzer,\
org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer
# 可用的模板引擎提供类
org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.mustache.MustacheTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafTemplateAvailabilityProvider,\
org.springframework.boot.autoconfigure.web.JspTemplateAvailabilityProvider
接下来依次通过实例演示 初始化器 监听器 自动配置 异常报告
创建一个maven项目sbbean 同上添加依赖src/main/resources添加META-INF 添加spring.factories文件
1》springboot自动配置
实现一个功能 当在主类上添加EnableSocket 启动开启一个ServletSocket对象 端口8899
》》建立注解EnableSocket
package com.et.learn03.resource;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyMarkerConfiguration.class) //很重要 当任意类使用了该注解就会导入这个配置 这个配置就可以随便创建一个bean作为标志
public @interface EnableSocket {
}
》》标志配置类MyMarkerConfiguration
package com.et.learn03.resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//使用了注解EnableSocket才会创建该配置类的Bean
@Configuration
public class MyMarkerConfiguration {
@Bean
public Marker myMarkerBean() { //实例化一个myMarkerBean的标志bean
return new Marker();
}
class Marker {
}
}
添加一个当添加@EnableAutoConfiguration注解就会配置的类MyAutoConfiguretion
package com.et.learn03.resource;
import java.io.IOException;
import java.net.ServerSocket;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration()
//只有存在MyMarkerConfiguration.Marker的bean在容器中才会实例化这个类下的所有bean
//也就是只有加了EnableSocket 注解才能有这个类的实例
@ConditionalOnBean(MyMarkerConfiguration.Marker.class)
public class MyAutoConfiguretion {//没有myConfig 这个bean就创建
@ConditionalOnMissingBean(name="myServer")
@Bean
public ServerSocket myServer() throws IOException {
final ServerSocket ss = new ServerSocket(8899);
System.out.println("启动ServerSocket");
String str=null;//str.toString();
return ss;
}
}
将该类配置到 spring.factories中
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.et.learn03.resource.MyAutoConfiguretion
配置好后将maven项目 执行 install安装到本地镜像库 安装之前最好添加一个主类 去掉测试类 有可能安装失败
当前项目pom配置为
<groupId>cn.et</groupId>
<artifactId>sbbean</artifactId>
<version>0.0.1-SNAPSHOT</version>
在添加一个测试项目 test 添加sbbean的依赖 (测试项目的包路径(cn.et.learn03)和sbbean项目(com.et.learn03)的包路径不能一样否则会被扫描 )
<dependency>
<groupId>cn.et</groupId>
<artifactId>sbbean</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
添加一个主类测试
package cn.et.learn03;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.ComponentScan;
import com.et.learn03.resource.EnableSocket;
/**
* @EnableAutoConfiguration原理解析
* 自动读取jar包中的 /MeTA-INF/spring.factories类
* 具体实现参考 sbbean项目
* @author jiaozi
*
*/
@EnableAutoConfiguration
@ComponentScan("cn.et.learn03")
@EnableSocket
public class SbApplication {
public static void main(String[] args) {
SpringApplication sa=new SpringApplication();
sa.run(SbApplication.class, args);
}
}
发现启动 打印了启动ServerSocket telnet localhost 8899成功 说明开启了端口
主类中去掉启动ServerSocket 发现端口没有监听 成功
2》springboot初始化器
springboot初始化器 用于在bean被实例化之前(ConfigurableApplicationContext的refresh方法时)修改bean一些信息 配置profile等
初始化器 必须实现ApplicationContextInitializer接口实现 initialize方法
sbean项目中添加 该接口的实现类MyInitBean
package com.et.learn03.init;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
public class MyInitBean implements ApplicationContextInitializer<ConfigurableApplicationContext> {
//在创建bean指定 还可以定义bean 类似于 <bean id="myUser" class="MyUser"> 这里假设MyUser类已经
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
DefaultListableBeanFactory factory=(DefaultListableBeanFactory)applicationContext.getBeanFactory();
BeanDefinition bd=BeanDefinitionBuilder.genericBeanDefinition(MyUser.class).getBeanDefinition();
factory.registerBeanDefinition("myUser", bd);
}
}
将该类配置到 spring.factories中
#创建ApplicationContext对象 调用refresh方法创建并实例之前 可以进行一些bean的定义修改等
#此时只有bean的定义 还没有实例化
org.springframework.context.ApplicationContextInitializer=\
com.et.learn03.init.MyInitBean
任意maven项目 controller类测试 注入MyUser 看是否能装配
package cn.et.learn03.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.et.learn03.init.MyUser;
@RestController
public class TestController {
@Autowired
private MyUser myUser;
@GetMapping("/accept/{id}")
public String query(@PathVariable String id) {
return "ok111234";
}
}
能够成功启动 成功
3》springboot监听器
spring事件机制是使用 订阅和发布模式
ApplicationContext类中
addApplicationListener 用于添加订阅者 订阅某一些事件
publishEvent 用于发布一些事件
一般在spring容器的启动过程中会经历四个事件 当在这四个过程中springboot自动发布该事件 如果应用定了该事件 自动触发回调
四个事件为SpringApplicationEvent的子类 分别是:
ApplicationStartingEvent 调用run方法启动时触发, bean处理之前 但是此时已经注册了listeners and initializers.
ApplicationEnvironmentPreparedEvent 正在设置环境时触发, 此时 applicationcontext还没有创建
ApplicationPreparedEvent 此时bean定义信息已经加载 还没有进行调用refresh处理bean的生命周期
ApplicationReadyEvent 所有准备工作完成 可以对外提供服务了
此外还提供了另外一个异常的事件处理
ApplicationFailedEvent 启动时出现异常 自动发送该事件
如果需要监听 必须实现ApplicationListener 这里为了测试直接监听
SpringApplicationEvent 应该回调会调用四次 也可以单独监听某个事件
创建类MyListener
package com.et.learn03.listener;
import org.springframework.boot.context.event.SpringApplicationEvent;
import org.springframework.context.ApplicationListener;
/**
* @author jiaozi
*
*/
public class MyListener implements ApplicationListener<SpringApplicationEvent> {
@Override
public void onApplicationEvent(SpringApplicationEvent event) {
System.out.println("事件被触发"+event.getClass().getTypeName());
}
}
将该类配置到 spring.factories中
#启动事件监听
org.springframework.context.ApplicationListener=\
com.et.learn03.listener.MyListener
添加任意maven项目引用 该jar依赖后 尝试启动 发现控制台输出四次
4》springboot异常报告
在springboot启动时 出现异常可以使用异常报告拦截 并输出指定报告信息
创建异常报告类 拦截空指针异常
package com.et.learn03.fail;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.boot.diagnostics.FailureAnalysis;
import org.springframework.boot.diagnostics.analyzer.AbstractInjectionFailureAnalyzer;
public class MyExceptionFAilureAnalyzer extends AbstractInjectionFailureAnalyzer<NullPointerException> implements BeanFactoryAware {
@Override
public void setBeanFactory(BeanFactory arg0) throws BeansException {
// TODO Auto-generated method stub
}
@Override
protected FailureAnalysis analyze(Throwable arg0, NullPointerException arg1, String arg2) {
FailureAnalysis fa=new FailureAnalysis("出现空指针异常"+arg1.getMessage(), "你好", arg0);
return fa;
}
}
将该类配置到 spring.factories中
# 失败分析器 当启动时出现某些异常 可以通过程序截获并分析
org.springframework.boot.diagnostics.FailureAnalyzer=\
com.et.learn03.fail.MyExceptionFAilureAnalyzer
添加任意项目 在其中添加
String str=null;
str.toString();
发现启动时错误信息为 自定义的失败信息