Handwritten IOC container summary

newbaby2012 2022-02-13 08:17:45 阅读数:506

handwritten ioc container summary

A super simple IOC Containers , The code is shown : spring-code/src/main/java/com/IOC at main · CodePpoi/spring-code · GitHub

Refer to the Handwriting is the simplest IOC Containers , Thus understand spring The core principle of - Technology circle

At first, I wrote it myself ClassLoader, I found myself writing ClassLoader Cannot load annotations placed on classes , I guess it's defineClass() There is a problem , Because the bytecode is the same ( Through the tools ), Give up customization directly later ClassLoader, use UrlClassLoader

First define the annotation MyBean Used to label this class is a Bean, And comments AutoInject, The function is similar to Autowire        

@Retention(RetentionPolicy.RUNTIME)
@Target(value={ElementType.TYPE})
//@Documented
public @interface MyBean {
String value() default "TBean";
}
@Retention(RetentionPolicy.RUNTIME)
@Target(value={ElementType.FIELD})
//@Documented
public @interface AutoInject {
String value() default "";
}

establish BeanFactory,scanPackageAndLoadBeans Used to scan packets and injectBeans Used to annotate AutoInject Class assignment , typeBeanMap Used to store Class and Bean The corresponding relation of instance

package com.IOC;
import com.IOC.beans.*;
import java.lang.reflect.Field;
import java.util.*;
public class TBeanFactory {
private Map<Class, Object> typeBeanMap = new HashMap<>();
private String basePackage = "com.IOC.beans";
public <T> T getBean(Class clazz) {
return (T) typeBeanMap.get(clazz);
}
public static void main(String[] args) {
TBeanFactory beanFactory = new TBeanFactory();
beanFactory.scanPackageAndLoadBeans();
beanFactory.injectBeans(beanFactory.typeBeanMap);
UserController userController = beanFactory.getBean(UserController.class);
// call Bean The method in
User user = userController.getUserById(1L);
System.out.println(user);
}
// inject Used to mark AutoInject Set the value
private void injectBeans(Map<Class, Object> typeBeanMap) {
for(Object bean : typeBeanMap.values()) {
Class clasz = bean.getClass();
Field[] fields = clasz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(AutoInject.class)) {
field.setAccessible(true);
Class beanType = field.getType();
Object proxyBean = typeBeanMap.get(beanType);
try {
field.set(bean, proxyBean);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
private void scanPackageAndLoadBeans() {
// Find all the classes under the package
Set<String> classNames = ClassUtils.getClassName(basePackage, true);
for (String className : classNames) {
try {
// Find the class
Class clasz = Class.forName(className);
// Determine if there is MyBean annotation
if (clasz.isAnnotationPresent(MyBean.class)) {
typeBeanMap.put(clasz, clasz.newInstance());
}
} catch (Exception exception) {
}
}
}
}

Then there are two MyBean.Class, among UserController in AutoInject 了 userService

package com.IOC.beans;
@MyBean(value = "userController")
public class UserController {
@AutoInject
private UserServiceImpl userService;
public User getUserById(Long id) {
return userService.getUserById(id);
}
public UserController() {
System.out.println("beans.BeanA created");
}
public void print() {
System.out.println("called by someone");
}
}
@MyBean("userService")
public class UserServiceImpl {
public User getUserById(Long id) {
User user = new User();
if (id == 1) {
user.setId(id);
user.setName("zhangsan");
} else if (id == 2) {
user.setId(id);
user.setName("lisi");
}
return user;
}
}

copyright:author[newbaby2012],Please bring the original link to reprint, thank you. https://en.javamana.com/2022/02/202202130817435872.html