精华内容
下载资源
问答
  • 方法入参

    2020-02-08 12:07:04
    这本身也对方法的定义有更高的要求,这里我们只讲方法入参的一些规范技巧。 入参分两种类型:必需和非必需。必需比较好理解,方法执行必需这个入参,像常见的 String.valueOf(Object),这种情况就比较好判断;非...

        方法从创建之初就定义了它本身所代表的含义,它代表的是一个或一类行为,所以方法的设计和程序的稳健性是紧密相关的。这本身也对方法的定义有更高的要求,这里我们只讲方法入参的一些规范技巧。

        入参分两种类型:必需和非必需。必需比较好理解,方法执行必需这个入参,像常见的 String.valueOf(Object),这种情况就比较好判断;非必需指这个入参可有可无,即方法需要的对象可以通过入参的形式获取,也可以在方法中定义,对于这种情况需要仔细斟酌。

        一些总结可供参考:常量可直接在方法中使用,变量通过入参获取。这里的常量和变量都是是相对于方法而言。

       举一个例子供大家理解:

    AbstractApplicationContext 里面的 getBean 方法
    @Override
    public <T> T getBean(Class<T> requiredType) throws BeansException {
       assertBeanFactoryActive();
       return getBeanFactory().getBean(requiredType);
    }

    getBean 方法其定义是从 beanFactory 中通过 classType 获取bean实例。classType  相对于方法而言可变的, beanFactory 自始至终只有一个。所以这里 getBean 方法对 量 的管理便是:定义一个  requiredType 的入参,和方法内 getBeanFactory() 获取 beanFactory 对象。

    展开全文
  • 1、查看方法和返回值 2、查看类对象的属性 3、过滤不需要的请求 4、没有办法输出局部变量的值 五、arthas idea插件 一、原因 曾经,线上出了问题又定位不到问题原因,就开始抓耳挠腮,一遍一遍仔细看代码...

    目录

    一、原因

    二、watch主要功能

    三、使用

    1、下载

    2、测试类代码

    四、示例

    1、查看方法出参和返回值

    2、查看类对象的属性

    3、过滤不需要的请求

    4、没有办法输出局部变量的值

    5、查看方法耗时

    五、arthas idea插件


    一、原因

            曾经,线上出了问题又定位不到问题原因,就开始抓耳挠腮,一遍一遍仔细看代码,到底是哪里可能出错了呢?然后在可能出错的地方加上日志,然后重新部署,再看输出日志;发现不行,还需要输出这个方法中的这个参数,然后再重新部署;一遍一遍循环往复,甚是繁琐。心想就没有一个想debug那样可以在线时时查看的功能么?

            自从我接触了arthas,我被它强大的功能所折服。当我第一次看到同事使用arthas输出线上程序中任意方法的请求参数时心中一惊,还有这么神奇的工具呢?自此开启了我对arthas的崇拜之路。

            但是刚开始感觉还是会有点繁琐,不会过滤请求、不会看成员变量,有时候想看方法中某一参数的值,但是又不知道该怎么看,还是很苦恼。

            因此决定仔细学习一下arthas到底有哪些功能,都能做什么,这么好用的神器,不会用不是白白可惜了。

    二、watch主要功能

    1、查看方法入参、返回值

    2、过滤无用的输出

    3、查看类中的成员变量

    4、无法查看方法中的局部变量

    首先附上官方文档,更详细、更多的资料可以查看官方文档

    https://arthas.aliyun.com/doc/watch.html

    参数名称参数说明
    class-pattern类名表达式匹配
    method-pattern方法名表达式匹配
    express观察表达式
    condition-express条件表达式
    [b]方法调用之前观察
    [e]方法异常之后观察
    [s]方法返回之后观察
    [f]方法结束之后(正常返回和异常返回)观察
    [E]开启正则表达式匹配,默认为通配符匹配
    x指定输出结果的属性遍历深度,默认为 1
    n指定执行次数

            这部分可以先跳过,看完下面例子回过头来再看,这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写"{params,returnObj,target,throwExp}",只要是一个合法的 ognl 表达式,都能被正常支持。

    params:表示方法入参,可以通过params[0]获取指定位置的参数,可以用于过滤请求条件使用

    returnObj:表示方法返回参数;

    target:表示类对象,可以通过target查看成员变量的值;

    throwExp:表示异常;

    特别说明

    • watch 命令定义了4个观察事件点,即 -b 方法调用前,-e 方法异常后,-s 方法返回后,-f 方法结束后

    • 4个观察事件点 -b-e-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出

    • 这里要注意方法入参方法出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表方法入参外,其余事件都代表方法出参

    • 当使用 -b 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在

    三、使用

    1、windows下载

    下载地址

    https://alibaba.github.io/arthas/arthas-boot.jar

    2、linux下载

    wget https://arthas.aliyun.com/arthas-boot.jar

    直接用java -jar的方式启动,首先启动我们的demo项目,然后在启动arthas

    2、测试类代码

    DemoController类

    package com.demo.controller;
    
    import com.demo.model.UserModel;
    import com.demo.service.DemoService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class DemoController {
    
        @Autowired
        private DemoService demoService;
    
        @RequestMapping("/user")
        @GetMapping
        public String list(String name){
            UserModel userModel = new UserModel();
            userModel.setName(name);
            return demoService.getUser(name, userModel);
        }
    
    }

    DemoService类

    package com.demo.service;
    
    import com.demo.model.UserModel;
    import org.springframework.stereotype.Service;
    
    @Service
    public class DemoService {
    
        private static String PATH = "/home";
    
        private String user;
    
        public String getUser(String name, UserModel userModel) {
            user = "zhangsan";
            return userModel.getName();
        }
    }
    

    UserModel类

    package com.demo.model;
    
    import lombok.Data;
    
    @Data
    public class UserModel {
    
        public UserModel(){}
    
        public UserModel(String id, String name, Integer age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
    
        private String id;
    
        private String name;
    
        private Integer age;
    
    }

    四、示例

    1、查看方法入参和返回值

    watch com.demo.service.DemoService getUser '{params,returnObj}' -x 3

    2、查看类对象的属性

    watch com.demo.service.DemoService getUser 'target' -x 2

    查看类中静态变量,PATH为类中的静态成员变量

    getstatic com.demo.service.DemoService PATH  -x 2

    3、过滤不需要的请求

            实际使用中会有不相关的请求调用我们的目标方法,可以通过添加过滤条件,只输出我们自己请求的日志,params[0]=='demo'表示只有当第一个参数等于demo时才输出。

    watch com.demo.service.DemoService getUser "{params,returnObj}" "params[0]=='demo'" -x 4

            当我们请求参数为demo1时,控制台并没有输出日志,当参数为demo时,可以正常输出。

    采用参数UserModel对象中的属性过滤也是可以的,如下面示例:

    watch com.demo.service.DemoService getUser "{params,returnObj}" "params[1].name=='demo'" -x 4

    4、没有办法输出局部变量的值

            很多时候,我们想输出方法中某一个变量的值,但是到目前为止还没有找到好的方法,只能获取赋值给这个参数的方法的返回值来确定,这是一个比较遗憾的地方。

            watch 虽然很方便和灵活,但需要提前想清楚观察表达式的拼写,这对排查问题而言要求太高,因为很多时候我们并不清楚问题出自于何方,只能靠蛛丝马迹进行猜测。

            这个时候如果能记录下当时方法调用的所有入参和返回值、抛出的异常会对整个问题的思考与判断非常有帮助。

            同时还有更多命令和方法协同使用来定位问题,比如:

    1)trace获得一个方法的调用路径;

    2)tt: 记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测。

            我也还在进一步学习、使用中,以后有了更多的总结再来补充。

    5、查看方法耗时

            当遇到执行时间比较长的接口,我们想知道时间到底消耗在哪里,但是手动去输出每个方法又太繁琐,这时候arthas告诉你,让我来!一个trace命令轻松搞定。

            比如我们想查看DemoController#list()方法的内部耗时,只需要执行下面的命令,就可以看的一清二楚。

    trace com.demo.controller.DemoController list

    五、arthas idea插件

            有了arthas这种神器可以线上输出日志,但是watch语法还是不够简单,因此Idea arthas 插件就此横空出世,插件安装成功后,只需要将光标放置在具体的类、字段、方法上面 右键选择需要执行的命令,部分会有窗口弹出、根据界面操作获取命令;部分直接获取命令复制到了剪切板 ,自己启动arthas 后粘贴即可执行。

    复制出来的命令:

    watch com.demo.service.DemoService getUser '{params,returnObj,throwExp}' -v -n 5 -x 3 '1==1'

    展开全文
  • java中方法入参解析

    2020-03-11 14:21:28
    java中方法入参解析参数分为基本类型参数和对象类型参数当基本数据类型(Boolean,byte,char,String,int,Long,float,double)作为参数传递时,传递的是实参值的副本,即传的是值,无论在函数中怎么操作这个...

    参数分为基本类型参数和对象类型参数

    当基本数据类型(Boolean,byte,char,String,int,Long,float,double)作为参数传递时,传递的是实参值的副本,即传的是值,无论在函数中怎么操作这个副本,实参的值是不会被改变的。
    当对象作为参数传递时,实际上传递的是一份“引用的拷贝”。 (实际传递的是对象的引用)。对象的内部值可以被改变,但对象的引用不能被改变

    当入参被final关键词修饰时

    基本类型被final修饰,基本类型参数的值在方法体内不允许被改变;如果试图改变,则会引起编译器报错;
    对象类型的值被final修饰,引用是不可以变得,否则编译是不能够通过的;但是,对象内部的值是可以改变的;

    链接: Java方法参数(形参)被final修饰符修饰详解.

    链接: 关于Java对象作为参数传递是传值还是传引用的问题.
    图片: Alt

    展开全文
  • 很多时候,我们会需要对方法入参或者出参进行一些额外的处理,这时候使用AOP可以很好的满足我们的需求。因为AOP的侵入性较低,与业务逻辑的代码耦合度低,并且有较好的可重用性,开发效率较高。 下面摘抄一些关于...

    前言

    很多时候,我们会需要对方法的入参或者出参进行一些额外的处理,这时候使用AOP可以很好的满足我们的需求。因为AOP的侵入性较低,与业务逻辑的代码耦合度低,并且有较好的可重用性,开发效率较高。

    下面摘抄一些关于AOP的介绍

    AOP意为面向切面编程,AOP是通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

    前提

    在Spring Boot项目中使用aop,需要添加以下依赖

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

    AOP增强入参和出参

    如果我们要对入参和出参进行增强处理,那么需要使用的是Around环绕增强。

    下面简单介绍下Around环绕的作用

    Around环绕增强作用:可以在目标方法执行前织入增强动作,也可以在方法执行后织入增强动作,可以决定目标方法在什么时候执行,如何执行。可以改变目标的入参和返回值。

    看了Around环绕增强的作用,我们可以看到Around环绕增强很适合我们处理目标方法的入参和出参

    下面我就演示下Around环绕增强入参和出参的基本用法,大家可以参考进行自己的处理

    @Aspect //定义切面类
    @Component
    public class ControllerAspect {
    
        /**
         * 定义切点
         */
        @Pointcut("execution(* com.example.demo2.controller.*.*(..))")
        public void point(){
        }
    
        /**
         * 定义环绕增强
         */
        @Around("point()")
        public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
            //获取入参
            Object[] args = joinPoint.getArgs();
            //获取方法名
            System.out.println(joinPoint.getSignature().getName());
            //获取方法所在类的类名
            System.out.println(joinPoint.getSignature().getDeclaringType().getSimpleName());
            //对入参进行处理
            int i=0;
            if (ArrayUtils.isNotEmpty(args)){
                //入参为对象
                Params params=null;
                for (Object arg : args) {
                    //String类型或者Integer等包装类,需要对入参数组进行重新赋值
                    if (arg instanceof String){
                        args[i]="aop处理后的入参";
                    }
                    //对象类型的入参直接修改属性即可
                    if (arg instanceof Params){
                        params= (Params) arg;
                        params.setName("aop处理后的入参对象");
                    }
                    i++;
                }
            }
            //传入入参执行方法
            Object response = joinPoint.proceed(args);
            //修改返回值
            if (response instanceof String){
                response="修改后的返回值";
            }
            //将返回值返回,方法的返回值是around的返回值,而不是原来的返回值
            return response;
        }
    }
    
    

    下面概括下AOP修改方法入参和出参的大体过程

    修改入参
    1、通过ProceedingJoinPoint获取原来的入参

    2、对原入参进行增强处理

    3、将入参传入ProceedingJoinPoint的proceed,执行方法,这时候方法就相当于是用增强后的入参执行方法

    修改出参
    1、接收proceed方法的返回值,这就是方法初始的返回值

    2、对初始返回值进行增强处理

    3、返回增强后的返回值,被around环绕的方法,它的出参是around方法的返回值,而不一定是方法的原返回值,这就是我们能对返回值进行增强处理的本质

    测试类:

    @Controller
    @RestController
    public class TestController {
    
    
        @PostMapping(value = "testAop")
        public String testAop(String userName, Params params)throws Exception{
            System.out.println("入参为:  "+userName);
            System.out.println("入参对象为: "+params);
            return "正常返回值";
        }
    }
    

    调用后输出:

    testAop
    TestController
    入参为:  aop处理后的入参
    入参对象为: Params(name=aop处理后的入参对象)
    修改后的返回值
    

    通过结果,我们可以看到AOP已经对方法的入参和出参进行了处理

    展开全文
  • 有时候我们希望记录某些方法入参出参,但是有的时候切面可能把所有符合条件的切面的入参出参都记录了,没有很多的必要,有些方法记录入参出参没有过大的意义,所以我们可以利用注解 + AOP 实现针对注解方法入参...
  • Mybatis 方法入参处理

    千次阅读 2018-05-01 21:25:06
    在单个入参的情况下,mybatis不做任何处理,#{参数名} 即可,甚至连...多个入参:接口方法定义为: public Employee getEmpByIdAndName(Integer id,String name);取值:#{id},#{name} mybatis抛出异常:org.apac...
  • Java方法入参三个省略号...啥意思

    千次阅读 2019-06-03 21:23:54
    可以传入多个参数,也可以不传入参数 public void f1(Integer... arr) { System.out.println("进入f1方法..."); for (Integer a : arr) { System.out.println(a); } } Main main = n...
  • Mockito实战使用: 修改方法入参

    千次阅读 2019-06-21 18:20:15
    我们都知道在写UnitTest的时候,经常会使用Mockito去mock类中的某一个方法,让调用该方法的函数不调用这个实际方法,而是使用我们mock的方法返回我们事先准备好的返回值。通俗意义上解释就是实际方法的替代品,解决...
  • 应用一:方法入参校验由于系统多个方法入参均对外封装了统一的Dto,其中Dto中几个必传参数在每个方法中都会进行相同的校验逻辑。笔者考虑采用Spring AOP进行优化,拦截方法进行参数校验。测试case实现如下:Before/*...
  • Java泛型作为方法入参类型匹配规则

    千次阅读 2020-01-19 15:54:10
    A的get()方法返回值为泛型,运行时期具体实例类型在编译时期是不清楚的,因此 B C 编译状态 运行时method()方法传入的实例 接口 接口 通过 可能即是B的实现类,也是C的实现类 ...
  • Java如何获取到方法入参名称

    千次阅读 2019-04-19 15:30:55
      在使用javac编译时加入[-parameters]参数,然后通过反射就能获取到方法参数名称,但是如果不加这个参数获取到的会是arg0这样的参数名。 如果使用IDEA打开javac设置 代码如下: public class TestParameterNa...
  • } catch (Throwable throwable) { throw new Exception( "方法错误"); } } public String getValueBykey(String key, ProceedingJoinPoint pjp) { Expression expression = parserSpel .parseExpression(spELString...
  • 介绍一款Java的方法入参校验工具

    千次阅读 2019-01-06 17:14:17
    在日常开发中经常需要对方法入参做校验,特别是在远程调用的方法中。 我基于这个需求便开发了这款工具,可以节省在这方面所花费的精力,通过配置的注解,在编译期对语法树进行修改,就能为方法加入参数的校验逻辑...
  • mockito修改方法入参

    千次阅读 2017-06-24 10:47:13
    背景大部分方法入参和出参是区分的,格式如public Result method(Param param),这种场景比较容易,不再讨论。如果遇到方法的执行过程会修改入参,而且参数在方法内部创建,如以下代码所示:// 我们mock的目标方法...
  • 1.new Vue({ }) 的入参对象的属性: el、data、components、computed、methods、watch2.Vue.component(' ', { }) 的入参对象的属性: props、template3. Object.freeze( ) 4.Vue实例暴露了一些有用的实例属性与方法...
  • Java方法 入参为接口Interface

    千次阅读 2016-10-26 22:35:20
    Java方法 入参为接口Interface今天研究Google官方的MVP框架模式,看到了一个方法入参是两个Interface:这里写代码片自己写了个测试:public class Main { public static void main(String[] args) { //test 类 ...
  • SpringBoot 方法入参验证

    千次阅读 2018-08-20 17:13:19
    SpringBoot 方法入参验证 一、Validation Bean Validation Bean 是基于JSR-303标准开发出来的,使用注解方式实现,及其方便,但是这只是一个接口,没有具体实现 依赖包: < dependency > < ...
  • //(4)既使用HttpServletRequest同时使用基本类型的入参 @RequestMapping(value="method8") public String method8(HttpServletRequest request, @RequestParam("userName") String userName){ return ...
  • 主要给大家介绍了关于Spring Boot接收单个String入参的解决方法,文中通过示例代码介绍的非常详细,对大家学习或者使用spring boot具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 两个博文地址:springmvc 防止XSS攻击 && 特殊字符转义和方法入参检测工具类 springmvc 防止XSS攻击 && 特殊字符转义和方法入参检测工具类 XSS攻击,即Cross Site Script,跨脚本攻击,往web页面注入html代码或者...
  • arthas监控方法入参出参以及耗时

    千次阅读 2021-02-23 19:48:09
    } 抱怨归抱怨,为了尽快找了短信发送不成功的原因,我想到了老伙伴arthas(经常使用它定位线上问题),使用它可以监控方法入参和出参,于是我在服务器快速输入了以下命令: # 下载arthas(其实服务器早就有这个...
  • 我写了一个自定义注解,在一个controller方法上写上了注解,求问怎么获取该controller方法入参 有没有大神帮帮忙啊,在线等 我前段时间刚写过类似的代码,忘了放在那里了,要不然直接贴给你。你百度搜一下JAVA...
  • 类似的,当我们在编写类的方法时,也常常需要对方法入参进行合 法性检查,如果入参不符合要求,方法将通过抛出异常的方式拒绝后续处理。举一个例子:有一个根据文件名获取输入流的方法:InputStream getData(String ...
  • 字符串作为方法入参,方法内改变,方法外得不到想要的值   内部方法如下:   以上打印不了想要的值原来是犯了个低级错误! 不可变字符串不能修改值,需要使用可变字符串类型 修改如下: 方法内部修改...
  • 在Controller方法入参中写HttpServletRequest、HttpSession、Writer…等参数,它自动就有值了然后可以直接使用,并且我们可以很方便的使用形如@PathVariable、@RequestParam、@RequestBody…等轻松完成数据封装。...
  • 学些Java的抽象类和抽象方法,书中介绍一个例子:【问题描述】编写一个抽象...书中抽象方法getRadius()没有入参,我想试下有入参的实现,由于初学,经过多次调试才调通,总结下经验。【代码示例】抽象父类SpeedMet...
  • 实例概述我们前面的博文在讲解切点函数时说过args()、this()、target()、@args()、@within()、@target()和@annotation()这7个函数除了可以指定类名外,还可以指定参数名将目标对象连接点上的方法入参绑定到增强的...
  • SpringMVC Controller方法入参映射探秘

    千次阅读 2015-01-09 15:10:00
    SpringMVC Controller方法入参映射探秘 #1、不惑方式 public String addUser(@RequestParam(value="userName") String userName){ ... } #2、第二/三种方式 ```java public String addUser(@RequestParam ...
  • java中对象作为方法入参

    千次阅读 2017-08-23 13:57:39
    在java中,对象作为方法入参时,如果传进去该对象已经new好了,那么可以在方法中为属性赋值。跳出方法后,赋值的属性会生效。 但是,如果传进去的对象是null,在方法中才new ,为属性赋值等。这样,跳出方法后,...
  • 需求是这样的:对网关层指定接口(url)的调用情况做日志记录,日志需要根据 controller 层方法入参和返回值动态生成。 如果只是记录 url 的调用情况可以直接使用 HandlerInterceptor 实现,但需求中需要能够访问...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 162,372
精华内容 64,948
关键字:

方法入参