zoukankan      html  css  js  c++  java
  • SpringBoot初体验(续)

    1.如果你还不知道SpringBoot的厉害之处,或者你不知道SpringBoot的初级用法,请移步我的上一篇文章,传送门

    2.SpringBoot中的表单验证

    所谓验证,无非就是检验,对比,正如javax.validation.constraints包中的各种注解,从名字上我们可以看出来:

     

    我就用这个包中的Min做例子:

    我给我们的数据持久化层Dril类的age属性加上注解@Min

    a.Dril.java

    //数据持久化
    @Entity
    public class Dril {
        
        @Id
        @GeneratedValue
        private Integer id;
        
        private String name;
        
        @Min(value=18,message="未成年!")
        private Integer age;
    
        public Dril() {
    
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
        
        
        
    }

    b.DrilController.java

    @RequestMapping(value="addDril.do",method=RequestMethod.POST)
    public Dril getDrilName(@Valid Dril dril,BindingResult bindingResult){
            
        if (bindingResult.hasErrors()) {
            logger.info(bindingResult.getFieldError().getDefaultMessage());
            return null;
        }
        return drilService2.addDril(dril);

    c.运行结果

    当我们插入age小于18的数据的时候出现

    console输出:

    如果我们输入的对象年龄大于18的话出现

     

    其他方法自行测试。

    2.AOP统一处理请求日志

    a.简单介绍AOP

    面向对象将对象垂直划分,并且每个都有自己的方法,AOP将面向对象的庞大体系进行水平分割,并将影响到多个类的公共行为做成可重用的模块。正如AOP的核心思想,将通用逻辑从业务逻辑分离出来。

    b.AOP的运用场景

    权限控制,缓存控制,事务控制,审计日志,性能监控,分布式追踪,异常处理

    b.使用Aspectj注解

    @Aspect:用于声明当前类是一个切面

    @Pointcut:用于描述在哪些类、哪些方法上执行切面的代码

    Advice:描述想要在这些方法执行的什么时机进行拦截

    在介绍5种Advice之前,我先说说切面表达式

    c.切面表达式

    1.designators(指示器)
        描述通过什么样的方式去匹配哪些类、哪些方法。如匹配方法 execution(),匹配注解 @target() @args() @within() @annotation(),匹配包/类型 @within(),匹配对象 this() bean()target(),匹配参数 args()。
    2.wildcards(通配符)
        * .. +
        使用通配符进行描述,如* 匹配任意数量的字符 ,+ 匹配指定类及其子类, .. 一般用于匹配任意参数的子包或参数
    3.operators(运算符)
        && || !
        使用运算符进行多条件的判断,如&& 与操作符, || 或操作符 ,! 非操作符

    d.5种advice1.匹配包类

      // 匹配 ProductServiceAop 类里面的所有方法
      @Pointcut("within(com.myimooc.springaopguide.service.ProductServiceAop)") public void matchType(){
      } 
      // 匹配 com.myimooc.springaopguide.service 包及子包下所有类的方法
      @Pointcut("within(com.myimooc.springaopguide.service..*)") 
      public void matchPackage(){
      }

    2.匹配对象

        // 匹配AOP对象的目标对象为指定类型的方法,即DemoDao的aop代理对象的方法
        @Pointcut("this(com.myimooc.springaopguide.dao.DemoDao)")
        public void testDemo() {
        } 
        // 匹配实现IDao接口的目标对象(而不是aop代理后的对象)的方法,这里即DemoDao的方法
        @Pointcut("target(com.myimooc.springaopguide.dao.IDao)")
        public void targetDemo() {
        } 
        // 匹配所有以Service结尾的bean里面的方法
        @Pointcut("bean(*Service)")
        public void beanDemo() {
        }

    3.匹配参数

    // 匹配任何以find开头而且只有一个Long参数的方法 
    @Pointcut("execution(* *..find*(Long))") 
    public void argsDemo1(){}
    // 匹配任何只有一个Long参数的方法 
    @Pointcut("args(Long)") 
    public void argsDemo2(){} 
    // 匹配任何以find开头而且第一个参数为Long型的方法 
    @Pointcut("execution(* *..find*(Long,..))") public void argsDemo3(){} 
    // 匹配第一个参数为Long型的方法 
    @Pointcut("args(Long,..))") 
    public void argsDemo4(){}

    4.匹配注解

    // 匹配方法标注有AdminOnly的注解的方法 
    @Pointcut("@annotation(com.myimooc.springaopguide.security.AdminOnly)") public void annoDemo(){
    } 
    // 匹配标注有Beta的类底下的方法,要求的annotation的RetentionPolicy级别为CLASS @Pointcut("@within(com.google.common.annotations.Beta)")
     public void annoWithDemo(){
    } 
    // 匹配标注有Repository的类底下的方法,要求的RetentionPolicy级别为RUNTIME @Pointcut("@target(org.springframework.stereotype.Repository)")
     public void annoTargetDemo(){
    } 
    // 匹配传入的参数类标注有Repository注解的方法
     @Pointcut("@args(org.springframework.stereotype.Repository)")
     public void annoArgsDemo(){
    }

    5.匹配方法

    execution()格式

    execution( 
    modifier-pattern? // 修饰符匹配 
    ret-type-pattern // 返回值匹配 
    declaring-type-pattern? // 描述值包名 
    name-pattern(param-pattern) // 方法名匹配(参数匹配) 
    throws-pattern?// 抛出异常匹配 
    )

    实例:

        /**
         * 切点
         * 使用public修饰符匹配,任意返回值,在com.huhu.controller包下以Controller结尾的类名下的getDrils()方法
         */
        @Pointcut("execution(public * com.huhu.controller..*Controller.getDrils(..))")
        public void Log() {
            
        }

    e.AOP所需要的注解

    @Before,前置通知

    @After(finally)后置通知,方法执行完之后

    @AfterReturning,返回通知,成功执行之后

    @AfterThrowing,异常通知,抛出异常之后

    @Around,环绕通知

    f.请开始我们的表演

    代码接着上篇的代码,我们给在controller运行前输出访问的URL,METHOD,IP,类方法以及参数

    HttpAspect.java

    @Aspect
    @Component
    public class HttpAspect {
        Logger logger=LoggerFactory.getLogger(HttpAspect.class);
        
        /**
         * 切点
         * 使用public修饰符匹配,任意返回值,在com.huhu.controller包下以Controller结尾的类名下的getDrils()方法
         */
        @Pointcut("execution(public * com.huhu.controller..*Controller.getDrils(..))")
        public void Log() {
            
        }
        
        /**
         * 用于匹配方法执行的连接点
         * @param joinpoint(为org.aspectj.lang.JoinPoint的对象)
         */
        @Before("Log()")
        public void before(JoinPoint joinpoint) {
            logger.info("AOP的before()方法");
            
            ServletRequestAttributes attributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            //url
            logger.info("url={}",request.getRequestURL());
            //method
            logger.info("method={}",request.getMethod());
            //ip
            logger.info("ip={}",request.getRemoteAddr());
            //类方法
            logger.info("class_method= {}",joinpoint.getSignature().getDeclaringTypeName()+"."+joinpoint.getSignature().getName());
            //参数
            logger.info("args={}",joinpoint.getArgs());
        }
    
        @After("Log()")
        public void after() {
            logger.info("AOP的after()方法");
        }  
    }

    为了知道是运行controller前输出的,我们给controller加上

    @RequestMapping(value="getDrils",method=RequestMethod.GET)
        public List<Dril> getDrils(){
            logger.info("getDrils");
            List<Dril> drils =drilService.findAll();
            return drils;
        }

    运行结果:

    结果向我们展示了使用AOP的结果,所以AOP显然能做权限控制,缓存控制,事务控制,审计日志,性能监控,分布式追踪,异常处理这些事了。

    参考资料:

    《探秘Spring AOP》学习总结

    慕课网--Spring Boot进阶之Web进阶

  • 相关阅读:
    2013-1-17 打开/关闭默认共享的命令
    2013-1-1遍历文件夹,改名文件
    2012-07-02 无边框最大化窗体
    2012-04-12 工具箱中添加自定义控件的方法
    2012-4-2 通过MdiParent设置窗体最前
    2012-2-7列举及终止进程
    python with as 以上这段代码执行完毕后,就算在处理过程中出问题了,文件 f 总是会关闭。
    终于好了 ipython 里执行dos命令 显示结果却显示在kernel界面里 搞定了
    Win7开启远程桌面
    哪位有方法把 dd/mm/yyyy的字符串 格式化成yyyy-mm-dd
  • 原文地址:https://www.cnblogs.com/huhu1203/p/7676488.html
Copyright © 2011-2022 走看看