Spring源码简易手写实现(学习过程记录)(三)
3.1依赖注入实现
创建一个OrderService类
package com.rainwood.liming.service;
import com.rainwood.spring.Component;
@Component("orderService")
public class OrderService {
}
在UserService中依赖OrderService
package com.rainwood.liming.service;
import com.rainwood.spring.Autowired;
import com.rainwood.spring.Component;
import com.rainwood.spring.Scope;
@Component("userService")
//@Scope("prototype")
public class UserService {
@Autowired
private OrderService orderService;
public void test() {
System.out.println(orderService);
}
}
添加@Autowired注解
package com.rainwood.spring;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface Autowired {
}
作用域是ElementType.METHOD, ElementType.FIELD。
在createBean方法里处理依赖注入
public Object createBean(BeanDefination beanDefination) {
Class clazz = beanDefination.getClazz();
try {
//首先看getDeclaredConstructor(Class<?>... parameterTypes)
//这个方法会返回制定参数类型的所有构造器,包括public的和非public的,当然也包括private的。
//getDeclaredConstructors()的返回结果就没有参数类型的过滤了。
Object instance = clazz.getDeclaredConstructor().newInstance();
//依赖注入
//getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
for (Field declaredField : clazz.getDeclaredFields()) {
if(declaredField.isAnnotationPresent(Autowired.class)) {
//spring在依赖注入时候会去是spring容器池里去根据类型和名字来找对应的bean
//这里我们简化用名字来找
Object bean = getBean(declaredField.getName());
declaredField.setAccessible(true);//功能是启用或禁用安全检查
declaredField.set(instance, bean);
}
}
return instance;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
3.2关于Java Field.set()
获取属性的属性值并修改属性值
public static void main(String[] args) throws NoSuchFieldException,
SecurityException,
IllegalArgumentException,
IllegalAccessException {
Person person = new Person();
person.setName("VipMao");
person.setAge(24);
person.setSex("男");
//通过Class.getDeclaredField(String name)获取类或接口的指定属性值。
Field f1 = person.getClass().getDeclaredField("name");
System.out.println("-----Class.getDeclaredField(String name)用法-------");
System.out.println(f1.get(person));
System.out.println("-----Class.getDeclaredFields()用法-------");
//通过Class.getDeclaredFields()获取类或接口的指定属性值。
Field[] f2 = person.getClass().getDeclaredFields();
for (Field field: f2) {
field.setAccessible(true);
System.out.println(field.get(person));
}
//修改属性值
System.out.println("----修改name属性------");
f1.set(person, "Maoge");
//修改后再遍历各属性的值
Field[] f3 = person.getClass().getDeclaredFields();
for (Field fields: f3) {
fields.setAccessible(true);
System.out.println(fields.get(person));
}
}
执行结果:
-----Class.getDeclaredField(String name)用法-------
VipMao
-----遍历属性值-------
VipMao
24
男
----修改name属性后再遍历属性值------
Maoge
24
男
浙公网安备 33010602011771号