关于反射:Java的精华反射机制

1.Java反射机制的概念Java反射机制次要就是在程序运行的时候,动静的加载一些类和这些类的详细信息,而后操作这些类或对象的属性和办法。它的实质就是JVM通过类加载器失去一个class对象后,对其进行反编译,这样就能失去对象中的各种信息。 2.反射机制的优缺点长处: 运行期类型的判断,动静加载类,进步代码灵便度。毛病: 性能瓶颈:反射相当于一系列解释操作,告诉 JVM 要做的事件,性能比间接的 java 代码要慢很多。平安问题:让咱们能够动静操作扭转类的属性同时也减少了类的安全隐患。3.Java反射机制的原理下图就是类的失常加载过程,以及它们的反射原理和class对象: 4.反射具体应用创立Class类的实例有四种办法: //提供的简略的Person类public class Person{ private String name; private int id; private static int UID; private String show(String nation){ System.out.println("我的国籍是:" + nation); return nation; }} //形式一:调用运行时类的属性:.class Class clazz1 = Person.class; //形式二:通过运行时类的对象,调用getClass() Person p1 = new Person(); Class clazz2 = p1.getClass();//通过对象取得class //形式三:调用Class的静态方法:forName(String classPath) Class clazz3 = Class.forName("com.demo.java.Person"); System.out.println(clazz1 == clazz2);//true System.out.println(clazz1 == clazz3);//true //形式四:应用类的加载器:ClassLoader (理解) ClassLoader classLoader = ReflectionTest.class.getClassLoader(); Class clazz4 = classLoader.loadClass("com.demo.java.Person");通过反射创立对应的运行时类的对象 ...

June 22, 2022 · 1 min · jiezi

关于反射:PHP高级特性反射Reflection以及Factory工厂设计模式的结合使用代码实例

PHP高级个性-反射以及工厂设计模式的联合应用 [联合 Laravel-Admin 代码实例解说]利用反射来实现工厂模式的生产而无需创立特定的工厂类本文地址http://janrs.com/?p=833转载无需通过作者自己受权转载请注明起源 反射[Relfection]JANRS.COM - PHP Reflection 反射 什么是ReflectionReflection,即反射。反射提供给面向对象编程能够自省的能力这么了解有点太过于概念化,艰深地讲,就是能依据事件的后果反查出起因。在编程中,能够依据一个被实例化的对象,反查出这个对象属于的类以及该类领有所有属性以及办法,甚至能够读取文档正文。这个反查的过程就叫做反射PHP 提供了残缺的反射 API ,提供了内省类、接口、函数、办法和扩大的能力。此外,反射 API 提供了办法来取出函数、类和办法中的文档正文。具体见PHP官网 PHP反射简介 Reflection能干什么在下面讲到的,能够应用反射来获取一个类的所有属性以及办法还有正文文档,甚至能够获取类属性和办法的拜访权限[protected/private],这些个性使得PHP的应用灵活性失去十分大的进步。例如:- Laravel 框架的所谓优雅所在,即容器、依赖注入、IOC 管制反转就是依附这些个性实现的- Hyperf 框架的注解路由也是依据反射取得正文来实现的- 生成文档 因为反射能够获取类属性和办法的拜访权限,能够扫描整个我的项目的所有文件再应用反射来生成文档- 测试驱动开发 利用反射获取该类的所有办法的个性,进行测试驱动开发- 开发插件 利用反射获取类的内部结构的个性,实现 Hook 性能,例如框架插件的实现Reflection的优缺点长处 反射提供了对类的反解析,从而相比本来面向对象的编程形式取得了极高的灵活性,以及正当的应用可能让代码看起来更加优雅以及简洁。本来在面向对象的编程形式中,应用一个类的实例须要先 new 出一个对象再应用办法,然而应用了反射机制,只须要提供一个该类的办法而后应用反射机制即可应用该对象或者办法。Laravel 框架正是应用了大量的反射才取得了优雅的美誉,Swoole 的 Hyperf 框架的注解路由的实现也是应用了反射毛病 同时,因为反射是类实例化的反过程,毁坏了面向对象的封装性,间接将类的整个内部结构裸露,这就导致了反射一旦滥用,代码将难于治理,整个我的项目将十分凌乱,甚至导致业务执行错乱。尤其在大我的项目几十人的团队中,试想一下,本来的面向对象,只通知什么能够用,什么不能够用,CTO写好了底层代码,其他人继承后而后应用就行,内部结构啥的其他人都不晓得。一旦用上了反射,如果有一个程序员不小心将本来是 protected 或者是 private 的属性或者办法设置成了能够拜访,其余程序员在不知情的状况调用了本该暗藏的数据或者办法,那将导致不可预测的劫难【见上面示例代码】其次,因为反射的灵活性极高,这导致了无奈在 IDE 中通过间接间接点击代码溯源,对于老手真的是很蛋疼,Laravel 和Hyperf 都是如此在上面的代码中,反射的机制间接将 private 办法设置成内部可拜访#Example:<?phpclass Foo { private function myPrivateMethod() { return 7; }}$method = new ReflectionMethod('Foo', 'myPrivateMethod');//该反射性能间接将本来是private权限的办法设置成可拜访$method->setAccessible(true);echo $method->invoke(new Foo);// echos "7"?>工厂设计模式三种工厂设计模式 [简略工厂模式] [工厂模式] [形象工厂模式]简略工厂模式 又称为动态工厂办法模式。简略的说,就是创建对象的形式是通过一个静态方法来实现的。在简略工厂模式中,依据传递的参数来返回不同的类的实例在PHP中在简略工厂模式中,有一个形象的产品类【即abstract class Calculate】,这个抽象类能够是接口/抽象类/一般类。这个形象的产品类能够派生出多个具体的产品类【即class CalculateAdd以及class CalculateSub】。最初再由一个具体的工厂类【即class CalculateFactory】来获取所须要的产品类的实例 ...

November 18, 2021 · 4 min · jiezi

关于反射:深入理解Java中的反射机制和使用原理详细解析invoke方法的执行和使用

@toc 反射的概念反射: Refelection,反射是Java的特色之一,容许运行中的Java程序获取本身信息,并能够操作类或者对象的外部属性 通过反射,能够在运行时取得程序或者程序中的每一个类型的成员活成成员的信息程序中的对象个别都是在编译时就确定下来,Java反射机制能够动静地创建对象并且调用相干属性,这些对象的类型在编译时是未知的也就是说 ,能够通过反射机制间接创建对象,即便这个对象类型在编译时是未知的Java反射提供下列性能: 在运行时判断任意一个对象所属的类在运行时结构任意一个类的对象在运行时判断任意一个类所具备的成员变量和办法,能够通过反射调用private办法在运行时调用任意一个对象的办法 反射的原理反射的外围: JVM在运行时才动静加载类或者调用办法以及拜访属性,不须要当时(比方编译时)晓得运行对象是什么类的加载: Java反射机制是围绕Class类开展的首先要理解类的加载机制: JVM应用ClassLoader将字节码文件,即 class文件加载到办法区内存中 Class clazz = ClassLoader.getSystemClassLoader().loadClass("com.mypackage.MyClass");ClassLoader类依据类的齐全限定名加载类并返回一个Class对象 ReflectionData: 为了进步反射的性能,必须要提供缓存class类外部应用一个useCaches动态变量来标记是否应用缓存这个值能够通过内部的sun.reflect.noCaches配置是否禁用缓存class类外部提供了一个ReflectionData外部类用来寄存反射数据的缓存,并申明了一个reflectionData域因为稍后进行按需提早加载并缓存,所以这个域并没有指向一个实例化的ReflectionData对象 // 标记是否应用缓存,能够通过内部的sun.reflect.noCaches配置是否禁用缓存private static boolean useCaches = true;static class ReflectionData<T> {volatile Field[] declaredFields;volatile Field[] publicFields;volatile Method[] declaredMethods;volatile Method[] publicMethods;volatile Constructor<T>[] declaredConstructors;volatile Constructors<T>[] publicConstructors;volatile Field[] declaredPublicFields;volatile Method[] declaredPublicMethods;final int redefinedCount;ReflectionData(int redefinedCount) { this.redefinedCount = redefinedCount;}}// 这个是SoftReference,在内存资源缓和的时候可能会被回收// volatile保障多线程环境下读写的正确性 private volatile transient SoftReference<RefelectionData<T>> reflectionData;// 这个次要用于和ReflectionData中的redefinedCount进行比拟// 如果两个值不相等,阐明ReflectionData缓存的数据曾经过期了private volatile transient classRedefinedCount = 0;反射的主要用途反射最重要的用处就是开发各种通用框架 很多框架都是配置化的,通过XML文件配置Bean为了保障框架的通用性,须要依据配置文件加载不同的对象或者类,调用不同的办法要使用反射,运行时动静加载须要加载的对象示例: 在使用Struts 2框架的开发中会在struts.xml中配置Action: <action name="login" class="org.ScZyhSoft.test.action.SimpleLoginAction" method="execute"> <result>/shop/shop-index.jsp</result> <result name="error">login.jsp</result> </action>配置文件与Action建设映射关系当View层发出请求时,申请会被StrutsPrepareAndExecuteFilter拦挡StrutsPrepareAndExecuteFilter会动静地创立Action实例 ...

June 20, 2021 · 10 min · jiezi

关于反射:golang反射

一、根本介绍反射能够在运行时动静获取变量的各种信息,比方变量的类型(type),类别(kind)如果是构造体变量,还能够获取到构造体自身的信息(包含构造体的字段、办法)通过反射,能够批改变量的值,能够调用关联的办法应用反射,须要import("reflect")二、反射重要的函数和概念reflect.TypeOf(变量名),获取变量的类型,返回reflect.Type类型reflect.ValueOf(变量名),获取变量的值,返回reflect.Value类型reflect.Value 是一个构造体类型,通过reflect.Value,能够获取到对于该变量的很多信息。变量、interface{}和reflect.Value是能够互相转换的,这在理论开发中,常常用到var student Studentvar number int//专门做反射func test(b interface{}) { // 1.如何将interface{} 转成reflect.Value rval = reflect.ValueOf(b) // 2.如何将reflect.ValueOf转为interface{} iVal := rVal.Interface{} // 3.如何将interface{}转成原来的变量类型,应用类型断言即可 v := iVal.(Student)}三、常量常量应用const润饰常量在定义的时候,必须初始化常量不能批改常量只能润饰bool、数值类型(int、float系列)、string类型语法:const identifier [type] = value四、反射注意事项和细节阐明reflect.Value.Kind,获取变量的类别,返回的是一个常量Type是类型,Kind是类别,Type和Kind可能雷同也可能不同比方:var number int 的Type和Kind都是int,比方:var stu Student stu的Type是包名.Student,Kind是struct通过反射能够让变量在interface{}和Reflect.Value之间互相转换,变量<---->interface{}<---->reflect.Value应用反射的形式获取变量的值(并返回相应的类型),要求数据类型匹配,比方x是int,那么就应该应用reflect.Value(x).Int(),而不能应用其余通过反射来批改变量,留神当应用Setxxx办法来设置须要通过对应的指针类型来实现,共事须要应用到reflect.Value.Elem()办法

February 22, 2021 · 1 min · jiezi

关于反射:反射和动态代理

作者:辞慾 链接:https://zhuanlan.zhihu.com/p/... 起源:知乎 著作权归作者所有。商业转载请分割作者取得受权,非商业转载请注明出处。 简介什么是反射反射(Reflection)是 Java 程序开发语言的特色之一,它容许运行中的 Java 程序获取本身的信息,并且能够操作类或对象的外部属性。 通过反射机制,能够在运行时拜访 Java 对象的属性,办法,构造方法等。 反射的利用场景反射的次要利用场景有: 开发通用框架 - 反射最重要的用处就是开发各种通用框架。很多框架(比方 Spring)都是配置化的(比方通过 XML 文件配置 JavaBean、Filter 等),为了保障框架的通用性,它们可能须要依据配置文件加载不同的对象或类,调用不同的办法,这个时候就必须用到反射——运行时动静加载须要加载的对象。动静代理 - 在切面编程(AOP)中,须要拦挡特定的办法,通常,会抉择动静代理形式。这时,就须要反射技术来实现了。注解 - 注解自身仅仅是起到标记作用,它须要利用反射机制,依据注解标记去调用注解解释器,执行行为。如果没有反射机制,注解并不比正文更有用。可扩展性性能 - 应用程序能够通过应用齐全限定名称创立可扩展性对象实例来应用内部的用户定义类。反射的毛病性能开销 - 因为反射波及动静解析的类型,因而无奈执行某些 Java 虚拟机优化。因而,反射操作的性能要比非反射操作的性能要差,应该在性能敏感的应用程序中频繁调用的代码段中防止。毁坏封装性 - 反射调用办法时能够疏忽权限查看,因而可能会毁坏封装性而导致平安问题。外部曝光 - 因为反射容许代码执行在非反射代码中非法的操作,例如拜访公有字段和办法,所以反射的应用可能会导致意想不到的副作用,这可能会导致代码性能反常并可能毁坏可移植性。反射代码突破了形象,因而可能会随着平台的降级而扭转行为。反射机制类加载过程 类加载的残缺过程如下: 在编译时,Java 编译器编译好 .java 文件之后,在磁盘中产生 .class 文件。.class 文件是二进制文件,内容是只有 JVM 可能辨认的机器码。JVM 中的类加载器读取字节码文件,取出二进制数据,加载到内存中,解析.class 文件内的信息。类加载器会依据类的全限定名来获取此类的二进制字节流;而后,将字节流所代表的动态存储构造转化为办法区的运行时数据结构;接着,在内存中生成代表这个类的 java.lang.Class 对象。加载完结后,JVM 开始进行连贯阶段(蕴含验证、筹备、初始化)。通过这一系列操作,类的变量会被初始化。Class 对象要想应用反射,首先须要取得待操作的类所对应的 Class 对象。Java 中,无论生成某个类的多少个对象,这些对象都会对应于同一个 Class 对象。这个 Class 对象是由 JVM 生成的,通过它可能获悉整个类的构造。所以,java.lang.Class 能够视为所有反射 API 的入口点。 反射的实质就是:在运行时,把 Java 类中的各种成分映射成一个个的 Java 对象。 ...

August 17, 2020 · 6 min · jiezi

关于反射:反射和动态代理

作者:辞慾 链接:https://zhuanlan.zhihu.com/p/... 起源:知乎 著作权归作者所有。商业转载请分割作者取得受权,非商业转载请注明出处。 简介什么是反射反射(Reflection)是 Java 程序开发语言的特色之一,它容许运行中的 Java 程序获取本身的信息,并且能够操作类或对象的外部属性。 通过反射机制,能够在运行时拜访 Java 对象的属性,办法,构造方法等。 反射的利用场景反射的次要利用场景有: 开发通用框架 - 反射最重要的用处就是开发各种通用框架。很多框架(比方 Spring)都是配置化的(比方通过 XML 文件配置 JavaBean、Filter 等),为了保障框架的通用性,它们可能须要依据配置文件加载不同的对象或类,调用不同的办法,这个时候就必须用到反射——运行时动静加载须要加载的对象。动静代理 - 在切面编程(AOP)中,须要拦挡特定的办法,通常,会抉择动静代理形式。这时,就须要反射技术来实现了。注解 - 注解自身仅仅是起到标记作用,它须要利用反射机制,依据注解标记去调用注解解释器,执行行为。如果没有反射机制,注解并不比正文更有用。可扩展性性能 - 应用程序能够通过应用齐全限定名称创立可扩展性对象实例来应用内部的用户定义类。反射的毛病性能开销 - 因为反射波及动静解析的类型,因而无奈执行某些 Java 虚拟机优化。因而,反射操作的性能要比非反射操作的性能要差,应该在性能敏感的应用程序中频繁调用的代码段中防止。毁坏封装性 - 反射调用办法时能够疏忽权限查看,因而可能会毁坏封装性而导致平安问题。外部曝光 - 因为反射容许代码执行在非反射代码中非法的操作,例如拜访公有字段和办法,所以反射的应用可能会导致意想不到的副作用,这可能会导致代码性能反常并可能毁坏可移植性。反射代码突破了形象,因而可能会随着平台的降级而扭转行为。反射机制类加载过程 类加载的残缺过程如下: 在编译时,Java 编译器编译好 .java 文件之后,在磁盘中产生 .class 文件。.class 文件是二进制文件,内容是只有 JVM 可能辨认的机器码。JVM 中的类加载器读取字节码文件,取出二进制数据,加载到内存中,解析.class 文件内的信息。类加载器会依据类的全限定名来获取此类的二进制字节流;而后,将字节流所代表的动态存储构造转化为办法区的运行时数据结构;接着,在内存中生成代表这个类的 java.lang.Class 对象。加载完结后,JVM 开始进行连贯阶段(蕴含验证、筹备、初始化)。通过这一系列操作,类的变量会被初始化。Class 对象要想应用反射,首先须要取得待操作的类所对应的 Class 对象。Java 中,无论生成某个类的多少个对象,这些对象都会对应于同一个 Class 对象。这个 Class 对象是由 JVM 生成的,通过它可能获悉整个类的构造。所以,java.lang.Class 能够视为所有反射 API 的入口点。 反射的实质就是:在运行时,把 Java 类中的各种成分映射成一个个的 Java 对象。 ...

August 17, 2020 · 6 min · jiezi

Go-译文之如何使用反射

作者:Jon Bodner | 地址:Learning to Use Go Reflection 什么是反射多数情况下,Go 中的变量、类型和函数的使用都是非常简单的。 当你需要一个类型,定义如下: type Foo struct { A int B string}当你需要一个变量,定义如下: var x Foo当你需要一个函数,定义如下: func DoSomething(f Foo) { fmt.Println(f.A, f.B)}但有时候,你想使用的变量依赖于运行时信息,它们在编程时并不存在。比如数据来源于文件,或来源于网络,你想把它映射到一个变量,而它们可能是不同的类型。在这类场景下,你就需要用到反射。反射让你可以在运行时检查类型,创建、更新、检查变量以及组织结构。 Go 中的反射主要围绕着三个概念:类型(Types)、类别(Kinds)和值(Values)。反射的实现源码位于 Go 标准库 reflection 包中。 检查类型首先,让我们来看看类型(Types)。你可以通过 reflect.TypeOf(var) 形式的函数调用获取变量的类型,它会返回一个类型为 reflect.Type 的变量,reflect.Type 中的操作方法涉及了定义该类型变量的各类信息。 我们要看的第一个方法是 Name(),它返回的是类型的名称。有些类型,比如 slice 或 指针,没有类型名称,那么将会返回空字符串。 下一个介绍方法是 Kind(),我的观点,这是第一个真正有用的方法。Kind,即类别,比如切片 slice、映射 map、指针 pointer、结构体 struct、接口 interface、字符串 string、数组 array、函数 function、整型 int、或其他的基本类型。type 和 kind 是区别不是那么容易理清楚,但是可以这么想: 当你定义一个名称为 Foo 的结构体,那么它的 kind 是 struct,而它的 type 是 Foo。 ...

August 18, 2019 · 5 min · jiezi

SpringBoot-动态代理反射注解四-动态代理对象注入到Spring容器

上一篇:SpringBoot 动态代理|反射|注解|AOP 优化代码(三)-注解 本篇我们将实现通过代理生成的对象注入到spring容器中。首先需要实现BeanDefinitionRegistryPostProcessor, ApplicationContextAware两个接口,作用分别为:ApplicationContextAware:可以获得ApplicationContext对象,然后获取Spring容器中的对象BeanDefinitionRegistryPostProcessor:可以将我们自定义的bean注入到spring容器 @Slf4j@Componentpublic class HandlerBeanDefinitionRegistry implements BeanDefinitionRegistryPostProcessor, ApplicationContextAware { private ApplicationContext applicationContext; @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException { /** * 获取AutoImpl注解的接口,这些接口就需要通过动态代理提供默认实现 */ Set<Class<?>> classes = getAutoImplClasses(); for (Class<?> clazz : classes) { /** * 获取继承自HandlerRouter的接口的泛型的类型typeName,传入到DynamicProxyBeanFactory * 以便传入到DynamicProxyBeanFactory扫描typeName的实现类,然后按照feign和url两种实现 * 方式分类 */ Type[] types = clazz.getGenericInterfaces(); ParameterizedType type = (ParameterizedType) types[0]; String typeName = type.getActualTypeArguments()[0].getTypeName(); /** * 通过FactoryBean注入到spring容器,HandlerInterfaceFactoryBean实现以下功能: * 1.调用动态代理DynamicProxyBeanFactory提供HandlerRouter子接口的默认实现 * 2.将第一步的默认实现,注入到spring容器 */ HandlerRouterAutoImpl handlerRouterAutoImpl = clazz.getAnnotation(HandlerRouterAutoImpl.class); BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz); GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition(); definition.getPropertyValues().add("interfaceClass", clazz); definition.getPropertyValues().add("typeName", typeName); definition.getPropertyValues().add("context", applicationContext); definition.setBeanClass(HandlerInterfaceFactoryBean.class); definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE); beanDefinitionRegistry.registerBeanDefinition(handlerRouterAutoImpl.name(), definition); } } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { log.info("------------------------>postProcessBeanFactory"); } /** * 通过反射扫描出所有使用HandlerRouterAutoImpl的类 * @return */ private Set<Class<?>> getAutoImplClasses() { Reflections reflections = new Reflections( "io.ubt.iot.devicemanager.impl.handler.*", new TypeAnnotationsScanner(), new SubTypesScanner() ); return reflections.getTypesAnnotatedWith(HandlerRouterAutoImpl.class); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; log.info("------------------->setApplicationContext"); } /** * 通过class获取所有该类型的bean * * @param clazz * @return */ private Map<String, T> getBeans(Class<T> clazz) { return applicationContext.getBeansOfType(clazz); } private String getYmlProperty(String propery) { return applicationContext.getEnvironment().getProperty(propery); }}HandlerInterfaceFactoryBean 通过动态代理创建默认实现类 ...

July 11, 2019 · 2 min · jiezi

SpringBoot-动态代理反射注解AOP-优化代码三注解

上一篇SpringBoot 动态代理|反射|注解|AOP 优化代码(二)-反射 我们实现了通过反射完善找到目标类,然后通过动态代理提供默认实现,本篇我们将使用自定义注解来继续优化。 创建注解1.创建枚举 ClientType,用来标明Handler的实现方式 public enum ClientType { FEIGN,URL}2.创建注解ApiClient,用来标明Handler的实现方式 @Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface ApiClient { ClientType type();}3.创建HandlerRouterAutoImpl注解,来标记该HandlerRouter是否通过代理提供默认实现 @Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface HandlerRouterAutoImpl { /** * 在spring容器中对应的名称 * @return */ String name();}4.DeviceHandlerRouter添加注解,以动态代理提供默认实现 @HandlerRouterAutoImpl(name = "deviceHandlerRouter")public interface DeviceHandlerRouter extends HandlerRouter<DeviceHandler> {}5.DeviceHandlerFeignImpl、DeviceHandlerUrlImpl 添加注解标明具体的实现方式 @ApiClient(type = ClientType.FEIGN)@Component@Slf4jpublic class DeviceHandlerFeignImpl implements DeviceHandler { @Autowired private DeviceFeignClient deviceFeignClient; @Override public void remoteAddBatch(RemoteAddDeviceParam remoteAddDeviceParam, Integer envValue) { RestResult restResult = deviceFeignClient.create(remoteAddDeviceParam); ... } @Override public void remoteDeleteBatch(Integer envValue, List<String> snsList) { RestResult restResult = deviceFeignClient.deleteBySnList(snsList); ... } }@ApiClient(type = ClientType.URL)@Component@Slf4jpublic class DeviceHandlerUrlImpl implements DeviceHandler { @Override public void remoteAddBatch(RemoteAddDeviceParam remoteAddDeviceParam, Integer envValue) { String url = getAddUrlByEnvValue(envValue); String response = OkHttpUtils.httpPostSyn(url, JSON.toJSONString(snsList), false); RestResult restResult = JSON.parseObject(response, RestResult.class); ... } @Override public void remoteDeleteBatch(Integer envValue, List<String> snsList) { String url = getDelUrlByEnvValue(envValue); String response = OkHttpUtils.httpPostSyn(url, JSON.toJSONString(snsList), false); RestResult restResult = JSON.parseObject(response, RestResult.class); ... }}6.通过注解扫描目标类 ...

July 11, 2019 · 2 min · jiezi

SpringBoot-动态代理反射注解AOP-优化代码二反射

SpringBoot 动态代理|反射|注解|AOP 优化代码(一)-动态代理提供接口默认实现 我们抛出问题,并且提出解决问题的第一步的方法。下面我们继续深入,动态代理和反射继续解决我们的问题。 改动代码结构新增一个HandlerRougter接口,其目的就是替代上一篇的DeviceHandlerRouter public interface HandlerRouter<T> { T getHandler(Integer env,Object... args);}其中T是具体的业务接口。下面实现DeviceHandler的HandlerRouter: public interface DeviceHandlerRouter extends HandlerRouter<DeviceHandler> {}那么上层代码的调用方式将会类似下面的代码: DeviceHandlerRouter deviceHandlerRouter = ...deviceHandlerRouter.getHandler(...). remoteAddBatch(...)反射+动态代理前面说过,每增加一种接口调用,就需要重新实现xxxHandlerRouter,那么下面我们通过动态代理和反射提供DeviceHandler的默认实现。 1.通过反射获取HandlerRouter<T>的子接口和泛型对应的类 首先加入下面的依赖 <dependency> <groupId>org.reflections</groupId> <artifactId>reflections</artifactId> <version>0.9.10</version> </dependency>/** * 通过反射扫描出所有HandlerRouter的子类 * @return */private Set<Class<?>> getHandlerRouterClasses() { Reflections reflections = new Reflections( "package.name.*", new TypeAnnotationsScanner(),//注解扫描,本节用不到 new SubTypesScanner() ); return reflections.getSubTypesOf(HandlerRouter.class);}Set<Class<?>> classes = getHandlerRouterClasses();//获取HandlerRouter的子接口的泛型Class 例如:DeviceHandlerRouter接口的DeviceHandlerfor (Class<?> clazz : classes) { //clazz 对应DeviceHandlerRouter.class Type[] types = clazz.getGenericInterfaces(); ParameterizedType type = (ParameterizedType) types[0]; //typeName对应DeviceHandlerRouter extends HandlerRouter<DeviceHandler> 中的DeviceHandler.class String typeName = type.getActualTypeArguments()[0].getTypeName();}2.SpringBoot ApplicationContext 获取注入的bean ...

July 11, 2019 · 2 min · jiezi

乐字节Java反射之四反射相关操作

大家好,乐字节小乐继续为Java初学者讲述Java基础知识。上次说到乐字节Java反射之三:方法、数组、类加载器,这次是Java反射之四:反射相关操作 1、操作属性//1、获取Class对象 Class<?> clz=Class.forName("com.shsxt.ref.simple.User"); //2、获取对象 User u=(User)clz.newInstance(); //3、设置属性 Field field=clz.getDeclaredField("uname"); field.setAccessible(true);//打开权限 field.set(u, "0523"); //4、获取此属性 System.out.println(field.get(u));2、调用方法调用方法,都是直接对象.方法([实参]);反射之后,动态调用方法需要使用 invoke即可。 1)、方法调用 //1、获取Class对象 Class<?> clz=Class.forName("com.shsxt.ref.simple.User"); //2、获取对象 User u=(User)clz.newInstance(); //3、获取方法 Method m =clz.getMethod("coding", String.class,String.class); //4、成员方法的调用 m.invoke(u, "反射","多个参数"); //若是静态方法,传递null即可 因为静态方法属性类,不属于对象 m=clz.getMethod("testStatic",int.class); m.invoke(null, 100);//与对象无关2)、操作setter与getter访问器 /** * @param obj 操作的对象 * @param att 操作的属性 * @param value 设置的值 * */ public static void setter(Object obj, String att,Object value) { try { //setUname setUpwd -->第一个字母大写 att=att.substring(0,1).toUpperCase()+att.substring(1); Method method = obj.getClass().getMethod("set" + att, value.getClass()); method.invoke(obj, value); } catch (Exception e) { e.printStackTrace(); } } public static Object getter(Object obj, String att) { try { //getUname getUpwd -->第一个字母大写 att=att.substring(0,1).toUpperCase()+att.substring(1); Method method = obj.getClass().getMethod("get" + att); return method.invoke(obj); } catch (Exception e) { e.printStackTrace(); } return null;}main方法//1、获取Class对象 Class<?> clz=Class.forName("com.shsxt.ref.simple.User"); //2、获取对象 User u=(User)clz.newInstance(); //3、设置值 setter(u,"uname","shsxt"); //获取值 String str=(String) getter(u,"uname"); System.out.println(str);3、利用反射编写简单工厂设计模式利用反射+配置文件可以实现简单工厂模式。 ...

July 10, 2019 · 2 min · jiezi

乐字节Java反射之二实例化对象接口与父类修饰符和属性

大家好,小乐继续接着上集:乐字节Java反射之一:反射概念与获取反射源头Class 这次是之二:实例化对象、接口与父类、修饰符和属性 一:实例化对象之前我们讲解过创建对象的方式,有new 、克隆、反序列化,再加一种,根据Class对象,使用newInstance() 或者构造器实例化对象。调用以下api即可 //获取源头 Class<?> clz = Class.forName("com.shsxt.ref.simple.User"); //第一种:通过newInstance()创建对象 User user=(User)clz.newInstance(); user.setUname("sxt"); user.setUpwd("good");//第二种:通过getDeclaredConstructors()创建对象,取得全部构造函数(注意顺序) Constructor<?>[] cons=clz.getDeclaredConstructors(); for(Constructor<?>c:cons){ System.out.println(c); }//注意观察上面的输出结果,再实例化,否则参数容易出错 User u1=(User)cons[0].newInstance("shsxt","good"); User u2=(User)cons[1].newInstance("sxt"); User u3=(User)cons[2].newInstance(); System.out.println(u1.getUname()+u1.getUpwd());注意:newInstance()是调用空构造,如果空构造不存在,会出现异常。由此可知,使用其他构造器创建对象比较麻烦,使用空构造非常简单。确保空构造存在 。 二、 接口与父类通过api获取接口与父类 //获取源头 Class<?> clz =Class.forName("com.shsxt.ref.simple.User"); //获取所有接口 Class<?>[] inters=clz.getInterfaces(); for(Class<?> in:inters){ System.out.println(in.getName()); } //获取父类 Class<?> cls=clz.getSuperclass(); System.out.println("继承的父类为:"+cls.getName());三、 修饰符获取修饰符,使用Modifier即可 Class<?>clz=Class.forName("com.shsxt.ref.simple.User"); //获得修饰符 int n=clz.getModifiers(); //使用Modifier转换为相应的字符串 System.out.println(Modifier.toString(n));四、 属性获取所有属性(包括父类或接口) ,使用Field 即可操作 Class<?> clz = Class.forName("com.shsxt.ref.simple.User"); //获取属性System.out.println("===============本类属性=========="); // 取得本类的全部属性 Field[] field = clz.getDeclaredFields(); for (int i = 0; i < field.length; i++) { // 1、权限修饰符 int mo = field[i].getModifiers(); String vis = Modifier.toString(mo); // 2、属性类型 Class<?> type = field[i].getType(); //3、名字 String name = field[i].getName(); System.out.println(vis + " " + type.getName() + " "+ name + ";"); }System.out.println("=========公开的属性包括接口或者父类属性======"); field = clz.getFields(); for (int i = 0; i < field.length; i++) { System.out.println(field [i]); }乐字节原创,转载请注明出处 ...

July 8, 2019 · 1 min · jiezi

乐字节Java反射之一反射概念与获取反射源头class

一、Java反射机制概念“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”,如Python, Ruby是动态语言;显然C++,Java,C#不是动态语言,但是JAVA有着一个非常突出 的动态相关机制:Reflection。 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方 法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以 及动态调用对象的方法的功能称为java语言的反射机制。如 /** * 入门级示例:通过对象获取 包名.类名 * @author Administrator */public class Simple { public static void main(String[] args) { Simple s=new Simple(); System.out.println(s.getClass().getName()); }}Java反射机制,可以实现以下功能: ①在运行时判断任意一个对象所属的类; ②在运行时构造任意一个类的对象; ③在运行时判断任意一个类所具有的成员变量和方法; ④在运行时调用任意一个对象的方法; ⑤生成动态代理。 相关的api为 二、 获取源头Class(重点)打开权限: add.setAccessible(true); 所有类的对象其实都是Class的实例。这个Class实例可以理解为类的模子,就是包含了类的结构信息,类似于图纸。我们日常生活中,需要创造一个产品,如想山寨一个iphone手机,怎么办? 有三种方式可以实现: ⑴买个iphone手机,拆的七零八落的,开始山寨; ⑵到iphone工厂参观,拿到iphone磨具,开始山寨; ⑶跑到美国盗取iphone的图纸,开始山寨,最后一种最暴力,最爽。 序列化:实现serializable接口, 反序列化 克隆:实现cloneable接口,重写clone()方法,修改权限为public New 反射 同理,获取类的class对象,也有三种方式: ①Class.forName(”包名.类名”)//一般尽量采用该形式 ②类.class ③对象.getClass() 示例如下: public class Source { public static void main(String[] args) { //第一种方式:对象.class Source s=new Source(); Class<?>c1=s.getClass(); //第二种方式:类.class Class<?>c2=Source.class; //第三种方式(推荐方式):Class.forName() Class<?>c3=null; try { c3=Class.forName("com.shsxt.ref.simple.Source"); } catch (ClassNotFoundException e) { e.printStackTrace(); } System.out.println(c1.getName()); System.out.println(c2.getName()); System.out.println(c3.getName()); }}有了class对象,我们就有了一切,这就是反射的源头,接下来就是“庖丁解牛”。 ...

July 6, 2019 · 1 min · jiezi

java-反射机制

Java反射动态获取这个类的所有信息 反射机制的作用反编译:.class-->.java通过反射机制访问java对象的属性,方法,构造方法等;反射机制的应用场景Jdbc 加载驱动Spring IOC框架反射机制获取类有三种方法第一种 Class.forName("类全路径");第二种 //java中每个类型都有class 属性. 类名.class; 第三种 //java语言中任何一个java对象都有getClass 方法 Test t = new Test(); Classc3 = t.getClass(); //c3是运行时类 (t的运行时类是Test)反射创建对象的方式Class<?> forName = Class.forName("类全路径");// 创建此Class 对象所表示的类的一个新实例 调用了User的无参数构造方法.Object newInstance = forName.newInstance();实例化有参构造函数Class<?> forName = Class.forName("类全路径");Constructor<?> constructor = forName.getConstructor(String.class, String.class);User newInstance = (User) constructor.newInstance("123", "123");APIgetDeclaredMethods [] 获取该类的所有方法getReturnType() 获取该类的返回值getParameterTypes() 获取传入参数getDeclaredFields() 获取该类的所有字段setAccessible 允许访问私有成员禁止使用反射机制初始化:将构造函数为私有化

June 4, 2019 · 1 min · jiezi

Java学习笔记系列-反射

反射的本质Java在运行时能够获得或判断某个对象的类型信息RTTI有一条前提就是某个对象的类型信息在编译时必须已知。RTTI的实质就是编译器在遍历检查代码时偷偷将类型信息记录下来并存储,以在运行时能够获得当编写完某个.java文件,并编译之后,就会产生一个Class对象,由编译器偷偷的把这个class对象保存在编译后的.class文件中,当这个.class文件被加载到内存之后,随之会在内存中创建这个Class对象了。所以,获得class对象的前提是能获得类编译后的.class文件。且class对象的功能强大,方法众多:Class.getInterfaces()、Class.getSuperclass()、Class.getName()、Class.isInterface()等等,能用来获得很多信息RTTI与反射在最底层的思想上是很类似的,本质的区别在于:对RRTI,编译器在编译时打开和检查.class文件,而对反射来说,.class文件在编译时是不可获取的,在运行时未知对象已经来了再去打开和检查.class文件反射机制使得java能够创建一个在编译时完全未知的对象。反射在Java中用来支持其他特性的,例如对象的序列化和JavaBeanClass对象Class对象是进行反射操作的入口,所以首先必须获得Class对象。除了通过实例获取外,Class对象主要由以下几种方法获得:通过类加载器加载class文件Class<?> clazz = Thread.currentThread().getContextClassLoader(). loadClass(“com.takumiCX.reflect.ClassTest”);通过静态方法Class.forName()获取,需要传入类的全限定名字符串作参数(在获得class对象的同时会引起类的初始化)Class<?> clazz = Class.forName(“com.takumiCX.reflect.ClassTest”);通过类.class获得类的Class对象Class<ClassTest> clazz = ClassTest.class;

January 28, 2019 · 1 min · jiezi