ioc 过多的概念我再这里就不解释了 需要了解概念 点下边链接
https://blog.csdn.net/qq_22654611/article/details/52606960
概念理解了 手写个ioc 就明白怎么回事了 其实ioc没有想象中的那么难 注解+反射 就可以搞定
这里我是仿照spring设计的 的俩个注解 Autowired 和Component
项目结构图
注解引入的类
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
俩个注解
/**
* 自动注入 注解
*
*/
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
}
/**
* 指定需要容器管理的类
*
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
}
先上俩个工具类吧 一个是扫描所有类的 一个是根据扫描的类注实力化对象的
import java.io.File;
import java.io.FileFilter;
public class ClassUtil {
/**
* 获取该路径下所遇的class文件和目录
*
* @param pkg
* @return
*/
public static File[] getClassFile(String filePath) {
return new File(filePath).listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.isFile() && file.getName().endsWith(".class") || file.isDirectory();
}
});
}
}
import java.io.File;
import com.annotation.Component;
import com.ioc.IocContext;
public class AnnotationUtil {
//获取指定包路径下实现 Component主键Bean的实例
public static void addClassByAnnotation(String filePath, String packageName) {
try {
File[] files = ClassUtil.getClassFile(filePath);
if (files != null) {
for (File f : files) {
String fileName = f.getName();
if (f.isFile()) {
Class<?> clazz = Class.forName(packageName + "." + fileName.substring(0, fileName.lastIndexOf(".")));
//判断该类是否实现了注解
if(clazz.isAnnotationPresent(Component.class)) {
IocContext.applicationContext.put(clazz, clazz.newInstance());
}
} else {
addClassByAnnotation(f.getPath(), packageName + "." + fileName);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
重点来了 ,ioc 最重要的部分 iocContent 先扫描所有包 扫描到有注解的 放个 把对象 map集合里
import java.net.URL;
import java.util.Enumeration;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.util.AnnotationUtil;
/**
* Ioc 容器实现类
*
*/
public class IocContext {
public static final Map<Class<?>, Object> applicationContext = new ConcurrentHashMap<Class<?>, Object>();
static{
// 指定需要扫描的包名
String packageName = "com";
try {
initBean(packageName);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void initBean(String packageName) throws Exception {
Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageName.replaceAll("\\.", "/"));
while (urls.hasMoreElements()) {
AnnotationUtil.addClassByAnnotation(urls.nextElement().getPath(), packageName);
}
//IOC实现, 自定注入
IocUtil.inject();
}
}
底下是业务层
import java.lang.reflect.Field;
import java.util.Map;
import java.util.Map.Entry;
import com.annotation.Autowired;
/**
* Ioc 注入实现
*
*/
public class IocUtil {
public static void inject() {
Map<Class<?>, Object> map = IocContext.applicationContext;
try {
for (Entry<Class<?>, Object> entry : map.entrySet()) {
Class<?> clazz = entry.getKey();
Object obj = entry.getValue();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Autowired.class)) {
Class<?> fieldClazz = field.getType();
field.setAccessible(true);
Object fieldObj = map.get(fieldClazz);
field.set(obj, fieldObj);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Component
public class TestController {
@Autowired
public UserService userService;
public void getUser() {
User user = userService.getUser();
System.out.println(user);
}
}
public class User {
private String userName;
private Integer age;
private Integer sex;
public User(String userName, Integer age, Integer sex) {
this.userName = userName;
this.age = age;
this.sex = sex;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User [userName=" + userName + ", age=" + age + ", sex=" + sex + "]";
}
}
@Component
public class UserService {
public User getUser() {
User user = new User("张三", 50, 22);
return user;
}
}
测试
import com.demo.TestController;
import com.ioc.IocContext;
public class Main {
public static void main(String[] args) throws Exception {
TestController testController = (TestController)IocContext.applicationContext.get(TestController.class);
testController.getUser();
}
}
以上就是最简单的ioc了
源码要的私聊,