在使用spring时,在application.xml里面都会配置:

<context:component-scan base-package="com.xxx">
spring会扫描指定包下的类文件进行初始化相应的类。这样做的原理是什么呢?就是反射:

反射的使用

反射是java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。以下为实现例子。
  • 创建接口类:
package com.zhang.usb;
public interface Usb {
    public void open();
    public void close();
}

 

  • 创建调用类:
package com.zhang.domain;
import com.zhang.usb.Usb;
public class NoteBook {
    public NoteBook(){
        System.out.println("笔记本开始工作");
    }
    public void useUSB(Usb usb){    //传入接口对象,在使用中传入接口实现类对线即可。
        usb.open();
        usb.close();
    }
}

 

  • 创建类实现接口:
package com.zhang.domain;
import com.zhang.usb.Usb;
public class Mouse implements Usb{
    @Override
    public void open() {
        // TODO Auto-generated method stub
        System.out.println("鼠标打开");
    }
    @Override
    public void close() {
        // TODO Auto-generated method stub
        System.out.println("鼠标关闭");    
    }
}

 

  • 配置文件配置properties:
usb1=com.zhang.domain.Mouse
usb2=com.zhang.domain.Key

 

  • 加载配置文件反射实现类:
package com.zhang.main;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import com.zhang.domain.NoteBook;
import com.zhang.usb.Usb;
public class ReflectMain {
    /**
     * @param args
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws IOException
     */
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {
        // TODO Auto-generated method stub
        NoteBook nb = new NoteBook();
        File configFile = new File("usb.properties"); //创建配置文件
        if(!configFile.exists()){
            configFile.createNewFile();
        }
        //加载配置文件
        FileInputStream fs = new FileInputStream(configFile);
        Properties pp = new Properties();
        pp.load(fs);
        //读取配置文件
        for(int i=1;i<=pp.size();i++){
            String className = pp.getProperty("usb"+i);
            //获得配置文件所配置的类
            Class clazz = Class.forName(className);
            //创建类
            Usb obj = (Usb)clazz.newInstance();
            nb.useUSB(obj);
        }    
    }
}

 

反射的原理

类加载过程

JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化。

其中加载:

  1. 通过类的全限定名来获取定义此类的二进制字节流。
  2. 将这个类字节流代表的静态存储结构转为方法区的运行时数据结构。
  3. 在堆中生成一个代表此类的java.lang.Class对象,作为访问方法区这些数据结构的入口。

反射就是利用类的Class对象来生成类的实例,因为类的Class对象存储了该类的元数据信息。