springboot常用接口
参考地址:http://t.zoukankan.com/hlkawa-p-14099755.html
1、Aware接口
spring ioc容器中bean是感知不到容器的存在,Aware接口就是帮助bean感知到ioc容器的存在,即获取当前bean对应的spring的一些组件,如当前bean对应的ApplicationContext等。
1.1、ApplicationContextAware获取applicationContext
@Component
public class SpringContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; public SpringContextUtil() { } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { applicationContext = applicationContext; } public static ApplicationContext getApplicationContext() { return applicationContext; } public static <T> T getBean(String name) throws BeansException { return applicationContext.getBean(name); } public static <T> T getBean(Class<?> clz) throws BeansException { return applicationContext.getBean(clz); } }
2、EnviromentAware环境变量读取和属性对象获取
Enviroment:环境,Profile和PropertyResolver的组合。
Enviroment对象的作用是确定哪些配置文件当前处于活动状态,以及默认情况下哪些配置文件应处于活动状态。
properties在几乎所有应用程序中都发挥着重要作用,并有多种来源:属性文件,jvm系统属性,系统环境变量,JNDI
servlet上下文参数,ad-hoc属性对象,映射等,同时它继承PropertyResolver接口
所以与属性相关的Environment对象,其主要是为用于配置属性源和从属性源中解析属性。
@Component public class MyEnvironment implements EnvironmentAware { private Environment environment; @Override public void setEnvironment(Environment environment) { this.environment=environment; } }
Aware的其他子接口
ApplicationEventPublisherAware (org.springframework.context):事件发布
用法可参考:ApplicationEventPublisherAware事件发布详解
ServletContextAware (org.springframework.web.context): ServletContext
ServletConfigAware (org.springframework.web.context): ServletConfig
用法可参考:ServletConfig与ServletContext接口API详解和使用
MessageSourceAware (org.springframework.context): 国际化
用法可参考:Spring的国际化资源messageSource
ResourceLoaderAware (org.springframework.context):访问底层资源的加载器
用法参考:Spring使用ResourceLoader接口获取资源
NotificationPublisherAware (org.springframework.jmx.export.notification):JMX通知
Spring JMX之一:使用JMX管理Spring Bean: https://www.cnblogs.com/duanxz/p/3968308.html
Spring JMX之三:通知的处理及监听: https://www.cnblogs.com/duanxz/p/4036619.html
BeanFactoryAware (org.springframework.beans.factory): 申明BeanFactory
Spring BeanFactory体系: https://juejin.cn/post/6844903881890070541
EmbeddedValueResolverAware (org.springframework.context): 手动读取配置
使用方式可以参考:Spring中抽象类中使用EmbeddedValueResolverAware和@PostConstruct获取配置文件中的参数值
ImportAware (org.springframework.context.annotation):处理自定义注解
关于ImportAware的作用可以看: Spring的@Import注解与ImportAware接口
BootstrapContextAware (org.springframework.jca.context): 资源适配器BootstrapContext,如JAC,CCI
springcloud情操陶冶-bootstrapContext(二): https://blog.csdn.net/weixin_30725467/article/details/96008648
LoadTimeWeaverAware (org.springframework.context.weaving):加载Spring Bean时植入第三方模块,如AspectJ
说说在 Spring AOP 中如何实现类加载期织入(LTW): https://juejin.cn/post/6844903664469950478
BeanClassLoaderAware (org.springframework.beans.factory): 加载Spring Bean的类加载器
深入理解Java类加载器(ClassLoader): https://blog.csdn.net/javazejian/article/details/73413292
BeanNameAware (org.springframework.beans.factory): 申明Spring Bean的名字
ApplicationContextAware (org.springframework.context):申明ApplicationContext
2、ApplicationEvent,ApplicationListener自定义事件及监听
2.1、spring内置事件
| 内置事件 | 应用描述 |
| ContextRefreshedEvent | ApplicationContext 被初始化或刷新时,该事件被触发。这也可以在 ConfigurableApplicationContext接口中使用 refresh() 方法来发生。此处的初始化是指:所有的Bean被成功装载,后处理Bean被检测并激活,所有Singleton Bean 被预实例化,ApplicationContext容器已就绪可用 |
| ContextStartedEvent |
当使用 ConfigurableApplicationContext (ApplicationContext子接口)接口中的 start() 方法启动 ApplicationContext 时,该事件被发布。你可以调查你的数据库,或者你可以在接受到这个事件后重启任何停止的应用程序。 |
| ContextStoppedEvent |
当使用 ConfigurableApplicationContext 接口中的 stop() 停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作。 |
| ContextClosedEvent |
当使用 ConfigurableApplicationContext 接口中的 close() 方法关闭 ApplicationContext 时,该事件被发布。一个已关闭的上下文到达生命周期末端;它不能被刷新或重启。 |
| RequestHandledEvent |
这是一个 web-specific 事件,告诉所有 bean HTTP 请求已经被服务。只能应用于使用DispatcherServlet的Web应用。在使用Spring作为前端的MVC控制器时,当Spring处理用户请求结束后,系统会自动触发该事件。 |
2.2、如果容器中存在实现ApplicationListener的监听器,那么当ApplicationContext调用publishEvent方法时,那么这个监听器会被触发。
@Getter public class EmailEvent extends ApplicationEvent { private String address; private String text; /** * Create a new ApplicationEvent. * * @param source the object on which the event initially occurred (never {@code null}) */ public EmailEvent(Object source) { super(source); System.out.println("[zhangyulong test 观察者 publish-sub 模式!]"); } /** * Create a new ApplicationEvent. * * @param source the object on which the event initially occurred (never {@code null}) */ public EmailEvent(Object source,String address,String text) { super(source); this.address=address; this.text=text; } } /** * 自定义监听器 */ @Component public class EmailListener implements ApplicationListener { @Override public void onApplicationEvent(ApplicationEvent event) { if(event instanceof EmailEvent) System.out.println("=========EmailListener test 观察者 publish-sub 模式!"); EmailEvent email = (EmailEvent)event; Object source = email.getSource(); String address = email.getAddress(); String text = email.getText(); System.out.println("address is "+address+"===text is "+text); } } @Controller public class Controller{ @Autowired private ApplicationContext applicationContext; @GetMapping("mtGoodsListGetHandlerV1") public void mtGoodsListGetHandlerV1(){ EmailEvent emailEvent = new EmailEvent("hello","137***0812@163.com","邮件内容!"); applicationContext.publishEvent(emailEvent); } }
3、InitializingBean接口
InitializingBean为Bean提供了初始化方法的方式,它只包含afterPropertiesSet方法,凡是实现该接口的类,在初始化bean的时候,会执行该方法,效果等同于bean的init-method属性,或者使用@PostConstruct注解的使用
三种方式的执行顺序@PostConstruct-》执行initializingBean接口中定义的方法-》执行init-method属性指定的方法。
@Component public class TestInitializingBean implements InitializingBean{ @Override public void afterPropertiesSet() throws Exception { //bean 初始化后执行 } }
4、BeanPostProcessor(aop)
实现BeanPostProcessor接口的类即为Bean后置处理器,spring加载机制会在所有bean初始化的时候遍历调用每个bean后置处理器,BeanPostProcessor为每个bean实例化时提供个性化的修改,包装等。
其顺序为:Bean实例化->依赖注入->Bean后置处理器(postProcessBeforeInitialization)->@PostConstruct ->InitializingBean实现类 ->执行init-method属性指定的方法->Bean后置处理器(postProcessAfterInitialization)
public class MyBeanPostProcessor implements BeanPostProcessor { /** * 在bean实例化之前回调 */ public Object postProcessBeforeInitialization(Object bean, String beanName)throws BeansException { System.out.println("postProcessBeforeInitialization: " + beanName); return bean; }
<bean id="dataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"> <property name="driverClassName"value="${jdbc.driverClass}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}"/> <property name="password"value="${jdbc.password}" /> </bean> jdbc.driverClass=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost/mysqldb?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=round; jdbc.username=root jdbc.password=123456
/** * 在bean实例化之后回调 */ public Object postProcessAfterInitialization(Object bean, String beanName)throws BeansException { System.out.println("postProcessAfterInitialization: " + beanName); return bean; } }
5、BeanFactoryPostProcessor接口
bean工厂的bean属性处理容器,通俗讲就是管理我们bean工厂内所有的beandefinition(为实例化bean定义信息)数据,可以随意修改属性
@Component @Slf4j public class BrianBeanFactoryPostProcessor implements BeanFactoryPostProcessor { public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { BeanDefinition bd = beanFactory.getBeanDefinition("brianBean"); MutablePropertyValues pv = bd.getPropertyValues(); if (pv.contains("kawa")) { pv.addPropertyValue("kawa", "修改属性kawa的值"); } } }
}
5.1、spring中BeanFactoryPostProcessor实现类常用的有:
PropertyPlaceholderConfiguer,在xml文件中用类似EL表达式的${key}替换指定的properties中的值。
6、WebMvcConfigurer接口:是spring内部的一种配置方式,采用javabean的形式来替换传统xml配置实现个性化定制,可以自定义一些handler,Interceptor,ViewResolver,MessagerConverter。类似于springboot1.5的WebMvcConfigurerAdapter类,不过WebMvcConfigurerAdapter目前已弃用(被标记为@Deprecated)
6.1、addInterceptors:拦截器
6.2、addViewControllers:页面跳转
6.3、addResourceHandlers:静态资源
6.4、configureDefaultServletHandling:默认静态资源处理器
6.5、congureViewResolvers:视图解析器
6.6、configureContentNegotiation:配置内容裁决的一些参数
6.7、addCoresMappings:跨域
6.8、configureMessagerConverters:消息转换器
8、ApplicationRunner接口和CommandLineRunner接口
ApplicationRunner:spring容器启动完成后,就会紧接着执行改接口的实现类的run方法,在同一个项目中可以定义多个ApplicationRunner实现类,执行顺序通过注解@Order或者实现Orderd接口来实现,run方法的参数ApplicationArguments可以获取到当前项目执行的命令参数
@Component public class PublishEndpoint implements ApplicationRunner{ @Override public void run(ApplicationArguments applicationArguments) throws Exception { //do something } }
CommandLineRunner接口同理
@Component public class TestImplCommandLineRunner implements CommandLineRunner { @Override public void run(String... args) throws Exception { System.out.println("<<<<<<<<<<<<这个是测试CommandLineRunn接口>>>>>>>>>>>>>>"); } }
9、自定义拦截器的两种实现方式
9.1、定义一个类,实现
org.springframework.web.servlet.HandlerInterceptor
9.2、定义一个,继承已实现了HandlerInterceptor接口的类
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
9.3、添加Interceptor拦截器到WebMvcConfigurer配置器中
配置器实现方式:
继承org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter(方法已过时)
实现org.springframework.web.servlet.config.annotation.WebMvcConfigurer接口(推荐)
继承org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport类 (继承WebMvcConfigurationSupport会让springboot对mvc的自动配置失效,前后端分离,没有静态资源自动配置的需求,也可以继承WebMvcConfigurationSupport)
9.4、拦截器响应乱码处理方式
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { response.setContentType("application/json:charset=UTF-8"); response.setCharacterEncoding("UTF-8"); PrintWriter writer = response.getWriter(); writer.print(JsonUtils.writeValue(api)); writer.close(); }
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { response.setHeader("Content-type", "text/html;charset=UTF-8"); PrintWriter writer = response.getWriter(); writer.print(JsonUtils.writeValue(api)); writer.close(); }

浙公网安备 33010602011771号