Spring3.x企业应用开发_IOC

Ioc概念:

包括两个内容:控制&反转

对于软件来说,是某一接口具体实现类的选择控制权从调用类中移除,转交给第三方决定。DI(依赖注入:Dependency Injection)即让调用类对某一接口实现类的依赖由第三方(容器或协作类)注入,以移除调用类对某一接口实现类的依赖。


Ioc类型:从注入方法上看,主要可以划分为三种类型:构造函数注入、属性注入和接口注入。


反射在Ioc中的应用,小例子:

Car.class

package com.wiseweb.ioc;

public class Car {
	
	private String brand ;
	
	private String color ;
	
	private int maxSpeed ;
	
	public Car(){}
	
	public Car(String brand, String color, int maxSpeed) {
		this.brand = brand ;
		this.color = color ;
		this.maxSpeed = maxSpeed ;
	}
	
	public void introduce() {
		System.out.println("brand:" + brand + ";color:" +color + ";maxSpeed" + maxSpeed);
	}
	public String getBrand() {
		return brand;
	}
	public void setBrand(String brand) {
		this.brand = brand;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	public int getMaxSpeed() {
		return maxSpeed;
	}
	public void setMaxSpeed(int maxSpeed) {
		this.maxSpeed = maxSpeed;
	}
	
}
ReflectTest.class

package com.wiseweb.ioc;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class ReflectTest {
	public static Car initByDefaultConst() throws Throwable {
		ClassLoader loader = Thread.currentThread().getContextClassLoader() ;
		Class clazz = loader.loadClass("com.wiseweb.ioc.Car") ;
		
		Constructor cons = clazz.getDeclaredConstructor((Class[])null) ;
		Car car = (Car)cons.newInstance() ;
		
		Method setBrand = clazz.getMethod("setBrand", String.class) ;
		setBrand.invoke(car, "红旗") ;
		Method setColor = clazz.getMethod("setColor", String.class) ;
		setColor.invoke(car, "黑色") ;
		Method setMaxSpeed = clazz.getMethod("setMaxSpeed", int.class) ;
		setMaxSpeed.invoke(car, 200) ;
		return car ;
	}
	
	public static void main(String[] args) throws Throwable {
		Car car = initByDefaultConst() ;
		car.introduce() ;
	}
}

输出:brand:红旗;color:黑色;maxSpeed200


类装载器ClassLoader的工作机制:类装载器就是寻找类的字节码文件并构造出类在JVM内部表示的对象组件。在Java中,类装载器把一个类装入JVM中,要经过以下步骤:

1、装载:查找和导入class文件;

2、链接:执行校验、准备和解析步骤,其中解析步骤是可以选择的:

a、校验:检查载入class文件数据的正确定;

b、准备:给类的静态变量分配存储空间;

c、解析:将符号引用转成直接引用;

3、初始化:对类的静态变量、静态代码块执行初始化工作。

类装载工作由ClassLoader及其子类负责,ClassLoader是一个重要的Java运行时系统组件,它负责在运行时查找和装入Class字节码文件。JVM在运行时会产生三个ClassLoader:根装载器、ExtClassLoader(扩展类装载器)和AppClassLoder(系统类装载器)。其中,根装载器不是ClassLoader子类,它使用c++编写,因此我们在java中看不到它,根装载器负责装载JRE的核心类库,如JRE目标下的rt.jar、charsets.jar等。ExtClassLoader和AppClassLoader都是ClassLoader的子类。其中ExtClassLoader负责装载JRE扩展目录ext中的JAR类包;AppClassLoader负责装载Classpath路径下的类包。

这三个类装载器之间存在父子层级关系,即根装载器是ExtClassLoader的父装载器,ExtClassLoader是AppClassLoader的父装载器。默认情况下,使用AppClassLoader装载应用程序的类。

package com.wiseweb.ioc;

public class ClassLoaderTest {
	public static void main(String[] args) {
		ClassLoader loader = Thread.currentThread().getContextClassLoader() ;
		System.out.println("current loader:" + loader);
		System.out.println("parent loader:" + loader.getParent());
		System.out.println("grandparent loader:" + loader.getParent().getParent());
	}
}


输出:current loader:sun.misc.Launcher$AppClassLoader@70a0afab
  parent loader:sun.misc.Launcher$ExtClassLoader@456d3d51
  grandparent loader:null


JVM装载类时使用“全盘负责委托机制”,“全盘负责”是指当一个ClassLoader装载一个类时,除非显示地使用另一个ClassLoader,该类所依赖及引用的类也由这个ClassLoader载入;“委托机制”是指先委托父装载器寻找目标类,只有在找不到的情况下才从自己的类路径中查找并装载目标类。这一点是从安全角度考虑的,试想如果有人编写了一个恶意的基础类(如java.lang.String)并装载到JVM中将会引起多么可怕的后果。但是由于有了“全盘负责委托机制”,java.lang.String永远是由根装载器来装载的,这样就避免了上述时间的发生。


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。