spring实用实现接口

一. spring framework

1. BeanPostProcessor(bean初始化前后置操作)

该接口能够在bean被实例化前后完成一些后置操作

例如在springboot环境中,每个bean在被实例化之前,都会执行该后置处理器,完成业务的特定操作

@Component
//@Lazy
public class BeanLife1 implements BeanPostProcessor, InitializingBean {


    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(bean);
        System.out.println(beanName);
        System.out.println("this is postProcessBeforeInitialization");
        return bean;
    }

    //判断如果是myselfService,则对该bean进行加强处理等业务操作
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(beanName.equals("myselfService")) {
            System.out.println("this is postProcessAfterInitialization");
        }
//        System.out.println("this is postProcessAfterInitialization");
        return bean;
    }
}

2. InitializingBean & DisposableBean (初始化 & 销毁接口)

实现该接口的方法,可以完成bean的初始化和销毁方法的重写

当然,可以使用@PostConstruct@PreDestroy注释代替

执行顺序为:

@PostConstruct -> InitializingBean -> PreDestroy -> DisposableBean

3. Lifecycle & LifecycleProcessor & SmartLifecycle 管理IOC的生命周期(启动和关闭回调)

通过实现以上接口,可以对IOC的启动,刷新,停止,重启进行回调。SmartLifecycle可以更加细粒度的管理IOC容器的自动刷新。从而实现对整个IOC容器的增强业务处理

4. ApplicationContextAware(获取spring当前的上下文对象)

实现该接口后,重写set方法,就可以拿到applicationContext上线文获取spring环境中所有的bean对象。该接口是实现类

ApplicationObjectSupport

提供的API更加强大,推荐使用该类获取上线文

@Component
public class BeanLife4 implements ApplicationContextAware {


    private ApplicationContext applicationContext;


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        applicationContext = applicationContext;
    }
}

5. factoryBean接口

spring提供了该接口,用于实现自己的bean工厂类

//实现三个方法,分别提供了bean的实例对象,bean的class类型,bean是否单例
public class MyselfBeanFactory implements FactoryBean<FactoryBean1> {
    @Override
    public FactoryBean1 getObject() throws Exception {

        return new FactoryBean1();
    }
    @Override
    public Class<?> getObjectType() {
        return FactoryBean1.class;
    }
    @Override
    public boolean isSingleton() {
        return true;
    }
}

//通过注入该工厂,达到注入指定bean的目的
   @Bean
    public MyselfBeanFactory myselfBeanFactory() {
        return new MyselfBeanFactory();
    }

二. spring web mvc

1. HandlerExceptionResolver全局异常处理接口

该接口实现方法后可以捕获所有来自MVC(requestMapping)的异常,并且返回一个modeAndView对象,可以指向其他的controller层。但是在实际的工作中,直接实现该接口并不是优雅的解决方案,springMVC 提供了一个注解@restControllerAdvice、@ExceptionHandler、@ResponseStatus

其中@restControllerAdvice注解能够拦截所有controller层的异常,并且交给当前类来处理

@exceptionHandler指定了异常被拦截后的处理方法,该注解可以执行具体的拦截异常类型参数

@responsedaStatus,可以指定当前request返回的response是什么类型,也就是执行什么就会返回什么

@RestControllerAdvice
@Slf4j
public class MyselfExceptionAnnotation {

    @ExceptionHandler(Exception.class)
//    @ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "我愿意")//默认也是返回
    public String handler(HttpServletRequest request, Exception ex) {

        log.error("捕获到异常,e={}", ex.getMessage());
//        ex.printStackTrace();
        return "error12123";
    }
}

2. WebMvcConfigurer MVC的拦截处理接口

该接口用于实现自定义拦截需求,项目中可以通过实现该接口或者继承WebMvcConfigurationSupport。并加入到spring容器中

该接口中有很多方法比较使用,例如:

①addInterceptors : 实现spring MVC的拦截器

②addArgumentResolvers():实现MVC的参数处理解析

③configurePathMatch(PathMatchConfigurer configurer):这个是和访问路径有关的

④configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer): 以实现静态文件可以像Servlet一样被访

⑤addFormatters(FormatterRegistry registry):增加转化器或者格式化器。这边不仅可以把时间转化成你需要时区或者样式。还可以自定义转化器和你数据库做交互,比如传进来userId,经过转化可以拿到user对象。

⑥addResourceHandlers(ResourceHandlerRegistry registry):静态资源处理器,业务场景就是自己的服务器作为文件服务器

⑦addCorsMappings(CorsRegistry registry):这个是设置跨域问题的

...... 还有其他的方法可以深入研究

exp1:例如拦截器:

先实现拦截器的接口:HandlerInterceptor或者继承HandlerInterceptorAdapter都可以,推荐直接实现

public class HandlerInterceptorConfig implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        request.setAttribute("user_id", "12345");
        request.setAttribute("phone", "110");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}

然后将该拦截器添加到spring MVC的拦截规则中

@Configuration
public class WebAppConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new HandlerInterceptorConfig()).addPathPatterns("/**");
    }
}

此时,拦截器即可生效

exp2: 参数解析

spring MVC的参数可以在webMvcConfigurer中被拦截,并且按照自定义规则解析

实现参数拦截解析接口

public class ParamResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        //判断拦截的参数中是否有该注解,如果此方法返回true, 则执行resolveArgument中的内容
        return parameter.hasParameterAnnotation(UserIds.class);
//        return false;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        //该方法将返回需要被解析的参数值,并进行绑定
        return webRequest.getAttribute("user_id", RequestAttributes.SCOPE_REQUEST);
    }
}

将参数解析添加到WebMvcConfigurer中

@Configuration
public class WebAppConfig implements WebMvcConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new ParamResolver());
    }
}

3. 消息转化器(HttpMessageConverter)

在springMVC中,前端传送参数&接口返回客户端参数,都需要经过springMVC默认的参数转化器进行转化,我们可以干掉springMVC默认的消息转化器,自定义一个来完成灵活使用。

3.1 首先,springMVC是如何定义默认的converter的呢?

跟踪代码发现:在MVC的统一配置处理拦截器里,在进行controller信息映射时,会讲默认的converter进行添加,此处调用了

getMessageConverters()

 该方法中,判断了当前的解析器集合是否为空,不为空,则调用了

addDefaultHttpMessageConverters()方法,添加默认解析器的方法,在该方法中加入了springMVC的解析器,也就是JackSon的解析器
	protected final List<HttpMessageConverter<?>> getMessageConverters() {
		if (this.messageConverters == null) {
			this.messageConverters = new ArrayList<>();
			configureMessageConverters(this.messageConverters);
			if (this.messageConverters.isEmpty()) {
				addDefaultHttpMessageConverters(this.messageConverters);
			}
			extendMessageConverters(this.messageConverters);
		}
		return this.messageConverters;
	}

3.2 要想实现自定义或者覆盖spring配置的解析器。可以在WebMvcConfigurer或者WebMvcConfigurationSupport中实现

extendMessageConverters()或者 configureMessageConverters()方法

此处的集合参数,就是WebMvcConfigurationSupports中默认添加好的解析器,如果不需要使用默认,可以将list执行clear方法,重新添加解析器即可,有关配置fastjson解析器可以参考博客:

https://www.cnblogs.com/hhhshct/p/9676604.html

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.clear();
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect);
        converter.setFastJsonConfig(config);
        converters.add(converter);
    }

4. 获取上下文请求对象 RequestContextHolder

可以根据RequestContextHolder获取当前请求的request和response

RequestAttributes request = RequestContextHolder.currentRequestAttributes()

5. MVC的异步响应模式(DeferredResult(异步响应一个)、servletRequest.startAsync、ResponseBodyEmitter(支持多次发送)、SseEmitter、StreamingResponseBody)

参考博客:https://blog.csdn.net/f641385712/article/details/88710676

  • DeferredResult,当servlet的请求返回值是这个类型时,response的返回将会一直等待响应,直到被添加了返回值才会结束响应。如下示例,flux1接口会一直等待响应,并且把result保存起来,当请求flux2时,将result中添加响应,此时flux1接口接收到响应值并完成。
    private static DeferredResult<String> results;
    @GetMapping("/flux1")
    public DeferredResult<String> flux1(HttpServletRequest request) {
        DeferredResult<String> result = new DeferredResult<>();
        this.results = result;
        return result;
    }
    @GetMapping("/flux2/{id}")
    public String flux2(@PathVariable String id) {
        this.results.setResult("FUCK" + id);
        return "OK";
    }
  • startAsync模式:该模式是servlet3.0后支持的一种异步响应的请求方式,大概意思是,如果有一些IO或者长时间阻塞的请求,如果按照传统的servlet请求,线程会一直被阻塞直到处理完成后释放。现在使用startAsync模式后,假如请求需要响应5s,请求后,请求线程会立即完成,将处理业务的5s阻塞交给另一个线程去处理,处理完成后完成响应。对请求来说,不是阻塞的,耗时会交给一个新线程处理,并且请求线程会等处理完成后完成响应,示例如下:
    @GetMapping("/flux3")
    public void flux3(HttpServletRequest request, HttpServletResponse response) {
        AsyncContext asyncContext = request.startAsync();
        asyncContext.addListener(new AsyncListener() {
            @Override
            public void onComplete(AsyncEvent asyncEvent) throws IOException {
                log.info("is complete");
            }

            @Override
            public void onTimeout(AsyncEvent asyncEvent) throws IOException {
                log.info("is timeout");
            }

            @Override
            public void onError(AsyncEvent asyncEvent) throws IOException {
                log.info("is error");
            }

            @Override
            public void onStartAsync(AsyncEvent asyncEvent) throws IOException {
                log.info("is start");
            }
        });
        asyncContext.setTimeout(2000);
        //实际的业务处理会交给这个线程来完成,
        asyncContext.start(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("ddddd");
                log.info("内部线程:"+Thread.currentThread().getName());
//                int i = 1/0;
                asyncContext.getResponse().setCharacterEncoding("utf-8").;
                asyncContext.getResponse().setContentType("text/html;charset=UTF-8");
                asyncContext.getResponse().getWriter().print("这是【异步】的请求返回");

            }catch (Exception e){
                log.error("异常",e);
            }
            //异步请求完成通知
            //此时整个请求才完成
            //其实可以利用此特性 进行多条消息的推送 把连接挂起。。
            asyncContext.complete();
        });
        log.info("servlet线程响应结束");
    }
  • ResponseBodyEmitter 可以返回多个值给请求,示例如下:当客户端发起骑牛/fulx4时,将emitter保存,然后返回。有其他的请求在emitter中发送消息,则客户端会一直接受消息,直到调用complate后,请求才会结束。
    @GetMapping("/flux4")
    public ResponseEntity<ResponseBodyEmitter> flux4() {
        ResponseBodyEmitter emitter = new ResponseBodyEmitter();
        EMITTERS = emitter;
        return ResponseEntity
                .ok()
                .contentType(MediaType.TEXT_HTML)
                .body(emitter); //2
    }

    @GetMapping("/flux5")
    public void flux5() throws IOException {
        EMITTERS.send("FUCK5");
    }

    @GetMapping("/flux6")
    public void flux() throws IOException {
        EMITTERS.send("FUCK6");
    }

    @GetMapping("/flux7")
    public void flux7() throws IOException {
        EMITTERS.send("FUCK7");
        EMITTERS.complete();
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Boot和Vue是两个独立的框架,分别用于后端和前端开发。Spring Boot是一个基于Spring框架的快速开发平台,可以用于构建Java应用程序的后端部分。它提供了很多开箱即用的功能和约定,使得开发者可以更专注于业务逻辑的实现。 Vue是一个用于构建用户界面的JavaScript框架,它能够通过组件化和响应式的方式构建复杂的前端应用。Vue提供了许多工具和库来简化前端开发,并且具有高效的渲染能力和优秀的性能。 在后台管理系统中,通常会使用Spring Boot作为后端框架来提供数据接口和业务逻辑的实现。通过Spring Boot的RESTful接口,可以实现前后端之间的交互和数据传输。同时,Spring Boot还可以提供安全认证、日志记录、数据库连接等功能,使得后台管理系统更加可靠和安全。 而Vue则可以用于构建后台管理系统的前端界面。Vue提供了丰富的组件库和工具,可以方便地构建用户界面。通过Vue的组件化和响应式特性,可以实现页面的动态更新和交互。同时,Vue还支持路由管理和状态管理等功能,可以更好地组织和管理前端代码。 综上所述,Spring Boot和Vue可以很好地配合使用来开发后台管理系统。Spring Boot提供了强大的后端能力,而Vue则提供了优秀的前端开发框架,两者的结合可以使得后台管理系统更具有实用性和可扩展性。同时,Spring Boot和Vue都具有良好的社区支持和文档资料,方便开发者学习和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值