Skip to content

Commit

Permalink
Merge pull request hellokaton#5 from Lemonjing/master
Browse files Browse the repository at this point in the history
Master
  • Loading branch information
hellokaton committed Feb 20, 2016
2 parents 68a3f8f + df9be43 commit 3c8bbda
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 21 deletions.
File renamed without changes.
42 changes: 21 additions & 21 deletions ioc/3.myioc.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

Java语言允许通过程序化的方式间接对Class进行操作,Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数、属性和方法等。Java允许用户借由这个Class相关的元信息对象间接调用Class对象的功能,这就为使用程序化方式操作Class对象开辟了途径。

我们将从一个简单例子开始探访Java反射机制的征程,下面的Car类拥有两个构造函数、两个方法以及三个属性,如代码清单所示:
我们将从一个简单例子开始探访Java反射机制的征程,下面的Hero类拥有一个构造函数、五个方法以及两个属性,如代码清单所示:

```java
/**
Expand Down Expand Up @@ -54,7 +54,7 @@ public class Test {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class<?> clazz = loader.loadClass("com.biezhi.ioc.Hero");

//2. 获取类的默认构造器对象并通过它实例化Car
//2. 获取类的默认构造器对象并通过它实例化Hero
Constructor<?> cons = clazz.getDeclaredConstructor((Class[])null);
Hero hero = (Hero)cons.newInstance();

Expand All @@ -74,7 +74,7 @@ public class Test {

这说明我们完全可以通过编程方式调用Class的各项功能,这和直接通过构造函数和方法调用类功能的效果是一致的,只不过前者是间接调用,后者是直接调用罢了。

在Test中,使用了几个重要的反射类,分别是ClassLoader、Class、Constructor和Method,通过这些反射类就可以间接调用目标Class的各项功能了。在①处,我们获取当前线程的ClassLoader,然后通过指定的全限定类`"com.biezhi.ioc.Hero"`装载Hero类对应的反射实例。在②处,我们通过Car的反射类对象获取Hero的构造函数对象cons,通过构造函数对象的newInstrance()方法实例化Car对象,其效果等同于new Hero()。在③处,我们又通过Hero的反射类对象的getMethod(String methodName,Class paramClass)获取属性的Setter方法对象,第一个参数是目标Class的方法名;第二个参数是方法入参的对象类型。获取方法反射对象后,即可通过invoke(Object obj,Object param)方法调用目标类的方法,该方法的第一个参数是操作的目标类对象实例;第二个参数是目标方法的入参。
在Test中,使用了几个重要的反射类,分别是ClassLoader、Class、Constructor和Method,通过这些反射类就可以间接调用目标Class的各项功能了。在①处,我们获取当前线程的ClassLoader,然后通过指定的全限定类`"com.biezhi.ioc.Hero"`装载Hero类对应的反射实例。在②处,我们通过Hero的反射类对象获取Hero的构造函数对象cons,通过构造函数对象的newInstrance()方法实例化Hero对象,其效果等同于new Hero()。在③处,我们又通过Hero的反射类对象的getMethod(String methodName,Class paramClass)获取属性的Setter方法对象,第一个参数是目标Class的方法名;第二个参数是方法入参的对象类型。获取方法反射对象后,即可通过invoke(Object obj,Object param)方法调用目标类的方法,该方法的第一个参数是操作的目标类对象实例;第二个参数是目标方法的入参。

第三步是通过反射方法操控目标类的元信息,如果我们将这些信息以一个配置文件的方式提供,就可以使用Java语言的反射功能编写一段通用的代码对类似于Hero的类进行实例化及功能调用操作了。

Expand Down Expand Up @@ -145,7 +145,7 @@ public interface Container {
/**
* 初始化装配
*/
public void initWrited();
public void initWired();
}
```

Expand Down Expand Up @@ -242,7 +242,7 @@ public class SampleContainer implements Container {
}

@Override
public void initWrited() {
public void initWired() {
Iterator<Entry<String, Object>> it = beans.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it.next();
Expand All @@ -261,40 +261,40 @@ public class SampleContainer implements Container {
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
// 需要注入的字段
AutoWrited autoWrited = field.getAnnotation(AutoWrited.class);
if (null != autoWrited) {
AutoWired autoWired = field.getAnnotation(autoWired.class);
if (null != autoWired) {

// 要注入的字段
Object autoWritedField = null;
Object autoWiredField = null;

String name = autoWrited.name();
String name = autoWired.name();
if(!name.equals("")){
String className = beanKeys.get(name);
if(null != className && !className.equals("")){
autoWritedField = beans.get(className);
autoWiredField = beans.get(className);
}
if (null == autoWritedField) {
if (null == autoWiredField) {
throw new RuntimeException("Unable to load " + name);
}
} else {
if(autoWrited.value() == Class.class){
autoWritedField = recursiveAssembly(field.getType());
if(autoWired.value() == Class.class){
autoWiredField = recursiveAssembly(field.getType());
} else {
// 指定装配的类
autoWritedField = this.getBean(autoWrited.value());
if (null == autoWritedField) {
autoWritedField = recursiveAssembly(autoWrited.value());
autoWiredField = this.getBean(autoWired.value());
if (null == autoWiredField) {
autoWiredField = recursiveAssembly(autoWired.value());
}
}
}

if (null == autoWritedField) {
if (null == autoWiredField) {
throw new RuntimeException("Unable to load " + field.getType().getCanonicalName());
}

boolean accessible = field.isAccessible();
field.setAccessible(true);
field.set(object, autoWritedField);
field.set(object, autoWiredField);
field.setAccessible(accessible);
}
}
Expand Down Expand Up @@ -334,7 +334,7 @@ public class IocTest {
public static void baseTest(){
container.registerBean(Lol.class);
// 初始化注入
container.initWrited();
container.initWired();

Lol lol = container.getBean(Lol.class);
lol.work();
Expand All @@ -343,7 +343,7 @@ public class IocTest {
public static void iocClassTest(){
container.registerBean(Lol2.class);
// 初始化注入
container.initWrited();
container.initWired();

Lol2 lol = container.getBean(Lol2.class);
lol.work();
Expand All @@ -353,7 +353,7 @@ public class IocTest {
container.registerBean("face", new FaceService2());
container.registerBean(Lol3.class);
// 初始化注入
container.initWrited();
container.initWired();

Lol3 lol = container.getBean(Lol3.class);
lol.work();
Expand Down

0 comments on commit 3c8bbda

Please sign in to comment.