IoC
Java反射机制
Java语言允许通过程序化的方式间接对Class的对象实例操作,Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息,如构造函数、属性和方法等:
编写一个简单示例开始探访Java反射机制的征程,通过比较传统方法以及反射机制创建类实例的不同,来介绍Java反射机制的原理:
Car类:拥有两个构造函数,一个方法以及三个属性
传统调用方法,使用构造函数设置属性或者set方法设置属性
1. 构造函数方法:Car car = new Car(“红旗轿车”, “黑色”, “180”);
2. Set方法:Car car = new Car(); car.setBrand(“红旗轿车”);
Java反射机制,以一种更加通用的方式间接地操作目标类
Java反射机制 – ClassLoader
类装载器就是寻找类的字节码文件并构造出类在JVM内部表示的对象组件,主要工作由ClassLoader及其子类负责,ClassLoader是一个重要的Java运行时系统组件,它负责在运行时查找和装入Class字节码文件: 工作机制: 装载:查找和导入Class文件 链接:执行校验,准备和解析步骤 初始化:对类的静态变量、静态代码块执行初始化工作
Class反射对象描述类语义结构,可以从Class对象中获取构造函数,成员变量,方法等类元素的反射对象,并以编程的方式通过这些反射对象对目标类对象进行操作。
这些反射对象类在java.reflect包中定义,下面是最主要的三个反射类:
Constructor
Method
Field
//首先需要编译整个工程,使类加载器可以找到所有的类
public class PrivateCarReflect {
public static void main(String[] args) throws Throwable{
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class clazz = loader.loadClass("com.minGW.reflect.PrivateCar");
PrivateCar pcar = (PrivateCar)clazz.newInstance();
Field colorFld = clazz.getDeclaredField("color");
//1.取消Java语言访问检查以访问private变量
colorFld.setAccessible(true);
colorFld.set(pcar,"红色");
Method driveMtd = clazz.getDeclaredMethod("drive",(Class[])null);
//Method driveMtd = clazz.getDeclaredMethod("drive"); JDK5.0下使用
//2.取消Java语言访问检查以访问protected方法
driveMtd.setAccessible(true);
driveMtd.invoke(pcar,(Object[])null);
}
}
Java的反射体系保证了可以通过程序化的方式访问目标类中的所有元素,Spring通过配置文件描述bean与bean之间的依赖关系,Spring IoC就是通过Java反射机制实现的
资源访问工具类
JDK所提供的访问资源的类并不能很好的满足各种底层资源的访问需求,因此,Spring设计了一个Resource接口,它为应用提供了更强大的访问底层资源的能力:
具体实现类:
ByteArrayResource
ClassPathResource
FileSystemResource
InputStreamResource
ServletContextResource
UrlResource
BeanFactory 和 ApplicationContext 的介绍
BeanFactory是Spring框架最核心的接口,它提供了高级IoC的配置机制。ApplicationContext建立在BeanFactory基础之上,提供了更多面向应用的功能,它提供了国际化支持和框架事件体系,更易于创建实际应用一般成BeanFactory为IoC容器,而称ApplicationContext为应用上下文
- BeanFactory 是Spring的基础设施,是面向Spring本身的
- ApplicationContext 则是面向使用Spring框架的开发者,(一般使用ApplicationContext)
在初始化BeanFactory时,必须为其提供一种日志框架,使用的是log4j,即在类路径下提供log4j的配置文件,这样启动Spring容器时才不会报错。
在获取ApplicationContext实例之后,就可以像BeanFactory一样通过getBean来返回Bean实例。
区别:
ApplicationContext:初始化上下文时,就实例化素有singleton实例,初始化时间稍微长一点,但这样有两点好处:
1. 对Bean提前的实例化操作会及时发现一些潜在的配置问题
2. 2.bean以缓存形式保存,运行时期使用到该实例时,可以直接获取,提高了运行效率
BeanFactory: 初始化容器时,并没有实例化Bean,直到第一次访问某个Bean时,才实例化目标Bean