学习 Spring,跟着二哥简单写个 IoC 容器。
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface MyAutowired {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface MyComponent {
}
public class SimpleIoC {
Map<Class<?>, Object> beans = new HashMap<>();
//扫描
public void scan(String packageName) {
List<Class<?>> classes = getClassesInPackage(packageName);
for (Class<?> clazz : classes) {
if (clazz.isAnnotationPresent(MyComponent.class)) {
registerBean(clazz);
}
}
di();
}
//获取包下的类,简化实现
private List<Class<?>> getClassesInPackage(String packageName) {
// 实际实现需要扫描classpath,这里简化处理.
return Arrays.asList(UserDao.class, UserService.class);
}
//注册bean
private void registerBean (Class<?> clazz) {
try {
Object instance = clazz.getDeclaredConstructor().newInstance();
beans.put(clazz, instance);
} catch (Exception e) {
throw new RuntimeException("创建bean失败");
}
}
//获取bean
@SuppressWarnings("unchecked")
public <T> T getBean(Class<T> clazz) {
return (T)beans.get(clazz);
}
//依赖注入
private void di() {
for (Object bean : beans.values()) {
Field[] fields = bean.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(MyAutowired.class)) {
field.setAccessible(true);
Object dependency = getBean(field.getType());
try {
field.set(bean, dependency);
} catch (Exception e) {
throw new RuntimeException("依赖注入失败");
}
}
}
}
}
}
//DAO层
@MyComponent
class UserDao {
public void save(String user) {
System.out.println("保存用户: " + user);
}
}
// Service层
@MyComponent
class UserService {
@MyAutowired
private UserDao userDao;
public void createUser(String name) {
userDao.save(name);
System.out.println("用户创建完成");
}
}
class Test {
public static void main(String[] args) {
SimpleIoC ioc = new SimpleIoC();
ioc.scan("package");
UserService bean = ioc.getBean(UserService.class);
bean.createUser("dong");
}
}
参考链接: