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&amp;characterEncoding=UTF-8&amp;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();
}

 

  

 

         

posted @ 2022-06-27 13:34  西风51668  阅读(1355)  评论(0)    收藏  举报