在使用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类加载机制分为五个部分:加载,验证,准备,解析,初始化。
其中加载:
- 通过类的全限定名来获取定义此类的二进制字节流。
- 将这个类字节流代表的静态存储结构转为方法区的运行时数据结构。
- 在堆中生成一个代表此类的java.lang.Class对象,作为访问方法区这些数据结构的入口。
反射就是利用类的Class对象来生成类的实例,因为类的Class对象存储了该类的元数据信息。