java反射主要类Constructor、Field、Method、Array、Modifier、Proxy、WeakCache:
Constructor继承Executable抽象类;
(Executable继承AccessibleObject类,并实现Member、GenericDeclaration接口;)
(其中Member就代表一个field、method或constructor;)
(Constructor主要方法有getDeclaringClass、getGenericParameterTypes、getParameterTypes、getName、toGenericString、newInstance等;)
(其中Constructor的newInstance和Class的newInstance等价;)
Field继承AccessibleObject类,并实现Member接口,代表实例字段或类字段;
(Field主要方法有set、get、setAccessible、setLong、setInt、setShort、setChar、setBoolean、setByte、getDouble、getFloat、getLong等;)
Method继承Executable抽象类,代表实例方法或类方法;
(Method主要方法有invoke、setAccessible等;)
Array是一个静态工具类,用于动态创建和访问数组,主要方法有newInstance、set、get等;
(其他native方法如newArray、multiNewArray、setDouble、setLong、setInt、set、getDouble、getLong、getChar、get、getLength等;)
Modifier是一个静态工具类,用于判断修饰符类型;
(主要方法有isPublic、isPrivate、isProtected、isStatic、isFinal、isSynchronized、isVolatile、isTransient、isNative、isInterface、isAbstract、parameterModifiers、fieldModifiers、methodModifiers、constructorModifiers、interfaceModifiers、classModifiers等)
Proxy是所有动态代理的超类;(即JDK动态代理,依赖反射实现)
(每个代理实例有一个invocation handler;是通过InvocationHandler接口及其invoke方法实现的;)
(代理接口和代理类关系如下:proxy interfaces are public =》Proxy classes are public, final, and not abstract;
若有non-public的proxy interfaces =》Proxy classes are non-public, final, and not abstract;)
(提供了多个静态方法如getProxyClass、newProxyInstance、isProxyClass、getInvocationHandler等;)
(利用java.lang.reflect.WeakCache维护代理类的缓存;其中key为内部类KeyFactory,value为内部类ProxyClassFactory;)
(注意:JDK动态代理只能代理实现了接口的类;而Cglib是一种子类代理,Spring-core包含了Cglib功能;)
(参见 https://blog.youkuaiyun.com/rokii/article/details/4046098)
WeakCache用于维护缓存映射,(key, sub-key) -> value,并提供了泛型;
(维护了ReferenceQueue类的字段refQueue;实现了静态内部类CacheKey、CacheValue、LookupValue、Factory;)
java静态代理和动态代理:
静态代理是指代理类和目标类实现相同的接口,并在代理类中维护一个目标类对象;
(优点:不修改目标对象的前提下,对目标对象进行功能的扩展和拦截,如实现前拦截、后拦截等业务功能;)
(缺点:因为需要实现与目标对象一样的接口,不易扩展和维护;)
(注意:静态代理不需要反射,可简单自己实现;且没有在运行期创建对象,即没有‘动态性’可言;)
动态代理是指动态的在内存中构建代理对象;
(前提:指定要代理的目标对象实现的接口类型;然后生成指定接口的对象;此时,需要jdk的反射包,特别是java.lang.reflect.Proxy来实现;)
(更具体的,利用Proxy的newProxyInstance方法可以构造一个目标对象的代理对象;只需要传递该对象的ClassLoader、所需实现的接口数组、以及一个InvocationHandler实例,然后就能用Constructor的newInstance来创建对象了;注意接口数组长度不能超过65535;和静态代理一样,动态代理也能拦截和扩展,只需要在InvocationHandler实例覆盖invoke方法,然后调用Method的invoke即可;)
(优点:动态创建、代理对象无要实现任何接口、十分方便;)
(缺点:目标对象仍然一定要实现接口;)
https://www.cnblogs.com/jiyukai/p/6958744.html
https://baijiahao.baidu.com/s?id=1617087707044210783&wfr=spider&for=pc
https://segmentfault.com/a/1190000011291179 !!!
https://www.ibm.com/developerworks/cn/java/j-lo-proxy1/ !!!
https://www.jianshu.com/p/5478f170d9ee
https://www.cnblogs.com/best/p/5679656.html
设计模式中的代理模式,也是指静态代理和动态代理;
问题:如果目标对象不使用接口(或者使用抽象类),那么静态代理和动态代理两个都用不了?是的,但可以用Cglib(它不依赖接口)
Cglib代理:
cglib(Code Generation Library)是一个第三方代码生成类库,运行时在内存中动态生成一个子类对象从而实现对目标对象功能的扩展;
(在运行期扩展Java类与实现Java接口,被许多AOP框架使用,如Spring AOP和dynaop,为它们提供方法拦截;)
(cglib底层是使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类;不鼓励直接使用ASM)
(cglib主要类有net.sf.cglib.proxy.Enhancer、MethodInterceptor、MethodProxy等;)
(cglib使用的技术不是反射,而是直接生成类字节码,比反射更快!但我觉得,也用到了反射,比如intercept方法用了Method.invoke)
(cglib需要继承目标对象,并重写方法,所以目标对象不能为final类;)
(参见 https://github.com/cglib/cglib)
字节码处理框架ASM:
https://www.jianshu.com/p/26e99d39b3fb
https://blog.youkuaiyun.com/qq_27376871/article/details/51613066
https://asm.ow2.io/
AOP的原理是动态代理,那Ioc和DI的原理是啥?
《Pro Spring 2.5》前6章;
《SPRING实战(第3版)》前4章;
《SPRING实战(第1版)》前3章;
《SPRING攻略-第2版》前3章;
《Spring技术内幕-第2版》前3章;
Ioc即控制反转,好处是降低耦合、便于维护和调试;
Ioc可以认为是一种全新的设计模式,但是理论和时间成熟相对较晚,并没有包含在GoF中;
DI是依赖注入,它是实现Ioc最常见的方式;
(它把耦合从代码中移出去,放到统一的XML文件中,通过一个容器在需要的时候把这个依赖关系形成;即避免了直接new对象;)
(通过IoC容器来管理对象的生命周期、依赖关系;实现配置和代码分离;)
(可以把IoC模式看作工厂模式的升华,把IoC容器看作一个大工厂;这个大工厂要生成的对象在XML文件中定义;)
(IoC最基本的Java技术就是“反射”编程,即根据给出的类名动态生成对象;)
Ioc除了依赖注入,还有依赖查找;(控制反转是目标,依赖注入和依赖查找是手段;)
http://jinnianshilongnian.iteye.com/blog/1413846
https://www.cnblogs.com/xdp-gacl/p/4249939.html
Type、ParameterizedType、WildcardType、TypeVariable、GenericArrayType:
Type是公共的顶层接口,表示java中所有类型,包括原始类型、参数化类型、数组类型、类型变量等,它只有一个方法是getTypeName;
ParameterizedType继承Type,代表参数化类型,主要方法有getActualTypeArguments、getRawType、getOwnerType;
WildcardType继承Type,代表通配符类型(即? extends Number或? super Integer等),主要方法有getUpperBounds、getLowerBounds;
TypeVariable继承Type和AnnotatedElement,是所有类型变量的顶级接口,主要方法有getBounds、getGenericDeclaration、getName、getAnnotatedBounds;
GenericArrayType继承Type,代表数组类型(其中元素可以是参数化类型或类型变量),方法有getGenericComponentType;
(注:Type类型在Class类中出现多次,如getGenericSuperclass、getGenericInterfaces方法;)
java.lang.invoke和java.lang.reflect有什么区别?
https://blog.youkuaiyun.com/u014285884/article/details/78740281 (《深入理解Java7核心技术与最佳实践》第2章)
https://www.infoq.cn/article/jdk-dynamically-typed-language (周志明)
java.lang.invoke提供了方法句柄(method handle),类似于反射API中的Method类,但是它功能更强大、使用更灵活、性能也更好;方法句柄和反射API可以协同使用;方法句柄由java.lang.invoke.MethodHandle类表示;方法句柄也类似某些语言的函数指针(与反射不同,方法句柄不区分构造方法、方法和域,而是统一采用MethodHandle;)
(除MethodHandle,重要的类还有MethodType、MethodHandles、SwitchPoint等;)