SpringBoot+Dubbo开发笔记(五)

一、SpringBoot+Dubbo整合MyBatis连接数据库

基于前面的项目,对其进行拓展补充

1.provider的pom文件引入mybatis,数据库驱动,数据源连接池依赖

        <!--数据库连接-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>

        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.1</version>
        </dependency>

        <!--druid 数据源-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.26</version>
        </dependency>

2.provider的SpringBoot配置文件(application.properties)配置Mybatis相关配置

# Mybatis配置

# 使用druid 数据源
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# spring.datasource.type=com.zaxxer.hikari.HikariDataSource
# 注意:一定要对应mapper映射xml文件的所在路径
mybatis.mapper-locations=classpath*:mapper/*.xml
# 注意:对应实体类的路径
mybatis.type-aliases-package=com.nt.demo.middle.entity

# mybatis.configuration.map-underscore-to-camel-case=true

# 打开sql语句打印
logging.level.com.nt.demo.provider.dao=debug

3.需要在provider的启动类上添加扫描mapper接口的注释

@SpringBootApplication
/**
 * 将项目中对应的mapper类的路径加进来就可以了
 */
@MapperScan(basePackages = "com.nt.demo.provider.dao")
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class,args);
    }
}

二、SpringBoot+Duboo中filter配置

1. 在consumer中新增filter类实现filter

package com.nt.demo.config.filters;

import com.nt.demo.config.wrapper.WrapperServletRequest;
import com.nt.demo.redis.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.jni.Local;
import org.springframework.core.annotation.Order;
import redis.clients.jedis.Jedis;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * Create by TaoTaoNing
 * 2019/7/3
 **/
@Slf4j
/**
 * order中数字越小,优先级越高
 */
@Order(0)
@WebFilter(urlPatterns = "/*", filterName = "loginFilter")
public class LoginFilter implements Filter {
    private static final String SESSION_TOKEN = "user_name";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info(this.getClass().getSimpleName() + " -- " + "is init ------");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info(servletRequest.getContentType());
        HttpServletResponse servletResponse1 = (HttpServletResponse) servletResponse;
        servletResponse1.setHeader("ningtao", "test_header");
        WrapperServletRequest wrapperServletRequest = null;
        // 关于请求包装流的使用
        if (servletRequest instanceof HttpServletRequest){

            HttpServletRequest servletRequest1 = (HttpServletRequest) servletRequest;
            wrapperServletRequest = new WrapperServletRequest(servletRequest1);

        }

        BufferedReader br = new BufferedReader(new InputStreamReader(wrapperServletRequest.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            System.out.println(line);
            sb.append(line);
        }
        System.out.println(sb.toString());

        filterChain.doFilter(wrapperServletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        log.info(this.getClass().getSimpleName() + " -- " + "is destroy ------");

    }
}

2.在consumer的启动类中加入组件扫描注解

@ServletComponentScan
@SpringBootApplication
public class WebConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebConsumerApplication.class,args);
    }
}

三、SpringBoot+Dubbo使用aop

1. 在consumer中引入aop依赖

        <!--aop依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2.新增aop类

package com.nt.demo.config.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.SourceLocation;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * Create by TaoTaoNing
 * 2019/7/30
 **/
@Slf4j
@Component
@Aspect
public class LogAspect {

    @Pointcut("execution(* com.nt.demo.controller..*.*(..))")
    public void executeMethod() {
    }

    /**
     * 前置通知,方法调用前调用
     *
     * @param joinPoint
     */
    @Before("executeMethod()")
    public void beforeDoController(JoinPoint joinPoint) {
        log.info("前置通知---beforeDoController");
        Object[] args = joinPoint.getArgs();

        log.info(Arrays.toString(args));

        String kind = joinPoint.getKind();
        log.info(kind);

        Signature signature = joinPoint.getSignature();
        log.info(signature.getName());

        SourceLocation sourceLocation = joinPoint.getSourceLocation();
        //   log.info(sourceLocation.getFileName());

        Object target = joinPoint.getTarget();

        log.info(target.toString());

        // 获取请求
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        log.info("请求URI = " + request.getRequestURI());
        log.info("请求ip = " + request.getRemoteHost());
        log.info("请求URL = " + request.getRequestURL());
        log.info("请求args = " + Arrays.toString(joinPoint.getArgs()));
        log.info("请求方法 = " + joinPoint.getSignature().getDeclaringTypeName() + "_" + joinPoint.getSignature().getName());

    }

    /**
     * 后置通知,方法调用后调用
     *
     * @param joinPoint
     */
    @After("executeMethod()")
    public void afterDoController(JoinPoint joinPoint) {
        log.info("后置通知---afterDoController");
        log.info("after = " + joinPoint.toLongString());
    }


    /**
     * 环绕通知:
     * 可以决定方法是否调用,执行时替换方法参数,执行完毕是否扩展返回值
     * 第一个参数必须是ProceedingJoinPoint类型
     *
     * @param proceedingJoinPoint
     */
    @Around("executeMethod()")
    public Object aroundDoController(ProceedingJoinPoint proceedingJoinPoint) {
        log.info("环绕通知------aroundDoController");
        Object[] args = proceedingJoinPoint.getArgs();
        Object proceed = null;
        try {
            // 执行目标方法
            proceed = proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        return proceed;
    }


    /**
     * 后置异常通知:
     * 定义一个名字,该名字用于匹配通知实现方法的一个参数名,当目标方法抛出异常返回后,将把目标方法抛出的异常传给通知方法;
     * throwing 限定了只有目标方法抛出的异常与通知方法相应参数异常类型时才能执行后置异常通知,否则不执行,
     * 对于throwing对应的通知方法参数为Throwable类型将匹配任何异常。
     *
     * @param joinPoint
     * @param throwable
     */
    @AfterThrowing(value = "executeMethod()", throwing = "throwable")
    public void exceptionAspect(JoinPoint joinPoint, Throwable throwable) {
        log.info("异常通知------exceptionAspect");

        log.info(joinPoint.getSignature().getName());

        if (throwable instanceof NullPointerException) {
            log.info("空指针异常!");
        }

    }


    /**
     * 后置返回通知
     * 这里需要注意的是:
     *      如果参数中的第一个参数为JoinPoint,则第二个参数为返回值的信息
     *      如果参数中的第一个参数不为JoinPoint,则第一个参数为returning中对应的参数
     * returning 限定了只有目标方法返回值与通知方法相应参数类型时才能执行后置返回通知,否则不执行,对于returning对应的通知方法参数为Object类型将匹配任何目标返回值
     * @param joinPoint
     * @param keys
     */
    @AfterReturning(value = "execution(* com.nt.demo.controller..*.*(..))",returning = "keys")
    public void doAfterReturningAdvice1(JoinPoint joinPoint,Object keys) {
        System.out.println("后置返回通知------doAfterReturningAdvice1");

        System.out.println("后置返回通知的返回值:" + keys);
    }
}

四、SpingBoot+Dubbo使用拦截器

1.在consumer新增管理类

package com.nt.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 配置类,主要配置:拦截器,过滤器,跨域配置等
 * Create by TaoTaoNing
 * 2019/7/3
 **/
@Configuration
public class WebConfig implements WebMvcConfigurer {

    /**
     * 添加拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        // 拦截器可以通过spring的依赖注入
        // registry.addInterceptor(拦截器)
    }

    /**
     * 此方法待研究
     * @param registry
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {

    }

    /**
     * 关于跨域的配置
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {

    }
}

2.新增拦截器

package com.nt.demo.config;

import com.nt.demo.config.interceptors.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

/**
 * 配置类,主要配置:拦截器,过滤器,跨域配置等
 * Create by TaoTaoNing
 * 2019/7/3
 **/
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    /**
     * 添加拦截器,拦截器通过此方法添加才会生效
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        // 拦截器可以通过spring的依赖注入
        // registry.addInterceptor(拦截器)
        registry.addInterceptor(loginInterceptor).addPathPatterns("/getUser","/register","/*");
    }

    /**
     * 此方法待研究
     * @param registry
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {

    }

    /**
     * 关于跨域的配置
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/demo/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "DELETE", "PUT", "OPTIONS")
                .allowedHeaders("x-requested-with","Content-Type")
                .maxAge(3600);
    }
    

    /**
     * 此方法用于配置静态资源的:eg:html,css,js:待研究
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

    }
}


附上github代码:
Github代码连接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值