反射与动态代理
2020-09-01 11:01:21 0 举报
AI智能生成
Java框架基础-反射与动态代理
作者其他创作
大纲/内容
反射
概念
反射机制指的是程序再运行时能够获取自身的信息。
作用
在运行时判断任意一个对象所属的类
在运行时判断任意一个类锁具有的成员变量和方法
在运行时任意调用一个对象的方法
在运行时构造任意一个类的对象
Class类
Java.lang.Class
当一个类或接口被装入时,JVM便会产生一个与之关联的java.lang.Class对象
JVM为每种类型管理一个独一无二的Class的对象
反射与工厂模式实现Spring IOC
反射机制概念
官方概念
个人理解
可以直接创建对象,却使用反射机制的原因
静态编译:在编译时确定类型,绑定对象,即通过
动态编译:运行时确定类型,绑定对象。
反射机制的优缺点
优点
可以实现动态创建对象和编译,体现出很大的灵活性
缺点
对性能有影响
反射与工厂模式实现IOC
不用反射机制的工厂模式(代码)
interface fruit{
public abstract void eat();
}
class Apple implements fruit{
public void eat(){
System.out.println("Apple");
}
}
class Orange implements fruit{
public void eat(){
System.out.println("Orange");
}
}
//构造工厂类
//也就是说以后如果我们在添加其他的实例的时候只需要修改工厂类就行了
class Factory{
public static fruit getInstance(String fruitName){
fruit f=null;
if("Apple".equals(fruitName)){
f=new Apple();
}
if("Orange".equals(fruitName)){
f=new Orange();
}
return f;
}
}
class hello{
public static void main(String[] a){
fruit f=Factory.getInstance("Orange");
f.eat();
}
}
public abstract void eat();
}
class Apple implements fruit{
public void eat(){
System.out.println("Apple");
}
}
class Orange implements fruit{
public void eat(){
System.out.println("Orange");
}
}
//构造工厂类
//也就是说以后如果我们在添加其他的实例的时候只需要修改工厂类就行了
class Factory{
public static fruit getInstance(String fruitName){
fruit f=null;
if("Apple".equals(fruitName)){
f=new Apple();
}
if("Orange".equals(fruitName)){
f=new Orange();
}
return f;
}
}
class hello{
public static void main(String[] a){
fruit f=Factory.getInstance("Orange");
f.eat();
}
}
使用反射机制
interface fruit{
public abstract void eat();
}
class Apple implements fruit{
public void eat(){
System.out.println("Apple");
}
}
class Orange implements fruit{
public void eat(){
System.out.println("Orange");
}
}
class Factory{
public static fruit getInstance(String ClassName){
fruit f=null;
try{
f=(fruit)Class.forName(ClassName).newInstance();
}catch (Exception e) {
e.printStackTrace();
}
return f;
}
}
class hello{
public static void main(String[] a){
fruit f=Factory.getInstance("Reflect.Apple");
if(f!=null){
f.eat();
}
}
}
public abstract void eat();
}
class Apple implements fruit{
public void eat(){
System.out.println("Apple");
}
}
class Orange implements fruit{
public void eat(){
System.out.println("Orange");
}
}
class Factory{
public static fruit getInstance(String ClassName){
fruit f=null;
try{
f=(fruit)Class.forName(ClassName).newInstance();
}catch (Exception e) {
e.printStackTrace();
}
return f;
}
}
class hello{
public static void main(String[] a){
fruit f=Factory.getInstance("Reflect.Apple");
if(f!=null){
f.eat();
}
}
}
反射机制并结合属性文件的工厂模式(即IOC)
首先创建一个fruit.properties的资源文件:
apple=Reflect.Apple
orange=Reflect.Orange
然后编写主类代码:
interface fruit{
public abstract void eat();
}
class Apple implements fruit{
public void eat(){
System.out.println("Apple");
}
}
class Orange implements fruit{
public void eat(){
System.out.println("Orange");
}
}
//操作属性文件类
class init{
public static Properties getPro() throws FileNotFoundException, IOException{
Properties pro=new Properties();
File f=new File("fruit.properties");
if(f.exists()){
pro.load(new FileInputStream(f));
}else{
pro.setProperty("apple", "Reflect.Apple");
pro.setProperty("orange", "Reflect.Orange");
pro.store(new FileOutputStream(f), "FRUIT CLASS");
}
return pro;
}
}
class Factory{
public static fruit getInstance(String ClassName){
fruit f=null;
try{
f=(fruit)Class.forName(ClassName).newInstance();
}catch (Exception e) {
e.printStackTrace();
}
return f;
}
}
class hello{
public static void main(String[] a) throws FileNotFoundException, IOException{
Properties pro=init.getPro();
fruit f=Factory.getInstance(pro.getProperty("apple"));
if(f!=null){
f.eat();
}
}
}
apple=Reflect.Apple
orange=Reflect.Orange
然后编写主类代码:
interface fruit{
public abstract void eat();
}
class Apple implements fruit{
public void eat(){
System.out.println("Apple");
}
}
class Orange implements fruit{
public void eat(){
System.out.println("Orange");
}
}
//操作属性文件类
class init{
public static Properties getPro() throws FileNotFoundException, IOException{
Properties pro=new Properties();
File f=new File("fruit.properties");
if(f.exists()){
pro.load(new FileInputStream(f));
}else{
pro.setProperty("apple", "Reflect.Apple");
pro.setProperty("orange", "Reflect.Orange");
pro.store(new FileOutputStream(f), "FRUIT CLASS");
}
return pro;
}
}
class Factory{
public static fruit getInstance(String ClassName){
fruit f=null;
try{
f=(fruit)Class.forName(ClassName).newInstance();
}catch (Exception e) {
e.printStackTrace();
}
return f;
}
}
class hello{
public static void main(String[] a) throws FileNotFoundException, IOException{
Properties pro=init.getPro();
fruit f=Factory.getInstance(pro.getProperty("apple"));
if(f!=null){
f.eat();
}
}
}
IOC容器的技术剖析
IOC框架使用需要注意的点
1)软件系统中由于引入了第三方IOC容器,生成对象的步骤变得有些复杂,本来是
两者之间的事情,又凭空多出一道手续,所以,我们在刚开始使用IOC框架的时候,
会感觉系统变得不太直观。所以,引入了一个全新的框架,就会增加团队成员学习和
认识的培训成本,并且在以后的运行维护中,还得让新加入者具备同样的知识体系。
两者之间的事情,又凭空多出一道手续,所以,我们在刚开始使用IOC框架的时候,
会感觉系统变得不太直观。所以,引入了一个全新的框架,就会增加团队成员学习和
认识的培训成本,并且在以后的运行维护中,还得让新加入者具备同样的知识体系。
2)由于IOC容器生成对象是通过反射方式,在运行效率上有一定的损耗。如果你要追
求运行效率的话,就必须对此进行权衡。
求运行效率的话,就必须对此进行权衡。
3)具体到IOC框架产品(比如Spring)来讲,需要进行大量的配制工作,比较繁琐,
对于一些小的项目而言,客观上也可能加大一些工作成本。
对于一些小的项目而言,客观上也可能加大一些工作成本。
4)IOC框架产品本身的成熟度需要进行评估,如果引入一个不成熟的IOC框架产品,
那么会影响到整个项目,所以这也是一个隐性的风险。
那么会影响到整个项目,所以这也是一个隐性的风险。
动态代理
静态代理
概念
所谓静态代理,就是代理类是由程序员自己编写的,在编译期就确定好了的。
用途
控制真实对象的访问权限 通过代理对象控制对真实对象的使用权限。
避免创建大对象
通过使用一个代理小对象来代表一个真实的大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。
例子
动态代理
动态代理中的代理类并不要求在编译期就确定,而是可以在运行期动态生成,从而实现对目标对象的代理功能。
动态代理与反射的关系
反射是动态代理的一种实现方式。
动态代理的几种实现方法
子主题
1、JDK动态代理:java.lang.reflect 包中的Proxy类和InvocationHandler接口提供了生成动态代理类的能力。
2、Cglib动态代理:Cglib (Code Generation Library )是一个第三方代码生成类库,运行时在内存中动态生成一个子类对象从而实现对目标对象功能的扩展。
Java实现动态代理的大致步骤
1、定义一个委托类和公共接口。
2、自己定义一个类(调用处理器类,即实现 InvocationHandler 接口),这个类的目的是指定运行时将生成的代理类需要完成的具体任务(包括Preprocess和Postprocess),即代理类调用任何方法都会经过这个调用处理器类(在本文最后一节对此进行解释)。
3、生成代理对象(当然也会生成代理类),需要为他指定(1)委托对象(2)实现的一系列接口(3)调用处理器类的实例。因此可以看出一个代理对象对应一个委托对象,对应一个调用处理器实例。
Java 实现动态代理主要涉及哪几个类
java.lang.reflect.Proxy: 这是生成代理类的主类,通过 Proxy 类生成的代理类都继承了 Proxy 类,即 DynamicProxyClass extends Proxy。
java.lang.reflect.InvocationHandler: 这里称他为"调用处理器",他是一个接口,我们动态生成的代理类需要完成的具体内容需要自己定义一个类,而这个类必须实现 InvocationHandler 接口。
AOP
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。
JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。
如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。
CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
收藏
0 条评论
下一页