手写模拟Spring底层原理,实现扫描、创建单例/原型bean,依赖注入,aware回调,aop,后置处理器,初始化等操作
代码结构
模拟spring源码
BeanDefinition
public class BeanDefinition { private Class aClass; private String scope; private Boolean lazy; public Class getaClass() { return aClass; } public void setaClass(Class aClass) { this.aClass = aClass; } public String getScope() { return scope; } public void setScope(String scope) { this.scope = scope; } public Boolean getLazy() { return lazy; } public void setLazy(Boolean lazy) { this.lazy = lazy; } }
BeanNameAware
public interface BeanNameAware { void setBeanName(String beanName); }
BeanPostProcessor
public interface BeanPostProcessor { default Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; } /** * 初始化后,创建bean的过程中,每一个bean都会调用此方法,也可以单独判断,可以用来实现aop */ default Object postProcessAfterInitialization(Object bean, String beanName) { return bean; } }
InitializingBean
public interface InitializingBean { void afterPropertiesSet(); }
MyApplicationContext
public class MyApplicationContext { private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>(); //单例池 private Map<String, Object> singletonObjects = new HashMap<>(); private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>(); public MyApplicationContext(Class<MyAppConfig> myAppConfigClass) throws ClassNotFoundException, NoSuchMethodException { //扫描 构建Bean定义,放在beanDefinitionMap中 scan(myAppConfigClass); //扫描完,遍历beanDefinitionMap,找出所有的单例bean,创建单例bean并放在单例池中 //单例模式先创建bean再放在单例池中 Set<Map.Entry<String, BeanDefinition>> entries = beanDefinitionMap.entrySet(); for (Map.Entry<String, BeanDefinition> entry : entries) { String beanName = entry.getKey(); BeanDefinition beanDefinition = entry.getValue(); String scope = beanDefinition.getScope(); if ("singleton".equals(scope)) { Object singletonBean = createBean(beanName, beanDefinition); singletonObjects.put(beanName, singletonBean); } } } private void scan(Class<?> myAppConfigClass) throws ClassNotFoundException { if (myAppConfigClass.isAnnotationPresent(MyComponentScan.class)) { MyComponentScan annotation = myAppConfigClass.getAnnotation(MyComponentScan.class); //扫描路径 String path = annotation.value(); System.out.println("扫描路径:" + path); path = path.replace(".", "/"); ClassLoader classLoader = MyApplicationContext.class.getClassLoader(); URL resource = classLoader.getResource(path); File fileDirectory = new File(resource.getFile()); if (fileDirectory.isDirectory()) { File[] files = fileDirectory.listFiles(); //遍历class文件 for (File file : files) { String absolutePath = file.getAbsolutePath(); //System.out.println("absolutePath->" + absolutePath); //加载类 //转换路径格式 absolutePath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.lastIndexOf(".class")); absolutePath = absolutePath.replace("\\", "."); //System.out.println("absolutePath->" + absolutePath); //class文件加载为class对象 //Class<?> aClass = Class.forName(absolutePath); Class<?> aClass = classLoader.loadClass(absolutePath); //找到有Component注解的类 if (aClass.isAnnotationPresent(MyComponent.class)) { System.out.println(absolutePath + "有component注解"); //如果一个类有component注解,再判断是否实现了BeanPostProcessor接口 if (BeanPostProcessor.class.isAssignableFrom(aClass)) { try { BeanPostProcessor instance = (BeanPostProcessor) aClass.getConstructor().newInstance(); //保存BeanPostProcessor,等到创建bean的时候再使用 beanPostProcessorList.add(instance); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } //不用获取BeanPostProcessor的BeanDefinition } else { MyComponent myComponent = aClass.getAnnotation(MyComponent.class); //注解中配置的beanName String beanName = myComponent.value(); //如果未指定beanName if ("".equals(beanName)) { //根据类型生成名字 beanName = Introspector.decapitalize(aClass.getSimpleName()); } //如果有类有Component这个注解,那么需要创建一个BeanDefinition描述该bean BeanDefinition beanDefinition = new BeanDefinition(); beanDefinition.setaClass(aClass); //再判断是单例还是原型 if (aClass.isAnnotationPresent(MyScope.class)) { MyScope myScope = aClass.getAnnotation(MyScope.class); String scope = myScope.value(); beanDefinition.setScope(scope); } else { //没有注解,默认是单例,如果是单例 beanDefinition.setScope("singleton"); } beanDefinitionMap.put(beanName, beanDefinition); } } } } } } public Object getBean(String beanName) throws NoSuchMethodException { //如果没有则说明没有定义这个bean if (!beanDefinitionMap.containsKey(beanName)) { System.out.println("找不到该bean"); return null; } BeanDefinition beanDefinition = beanDefinitionMap.get(beanName); String scope = beanDefinition.getScope(); //如果是单例,直接从单例池中获取 if ("singleton".equals(scope)) { Object singletonBean = singletonObjects.get(beanName); //可能因为扫描顺序问题,还没有初始化成功 if (singletonBean == null) { singletonBean = createBean(beanName, beanDefinition); singletonObjects.put(beanName, singletonBean); } return singletonBean; } else { //原型模式每次都要重新创建 Object prototypeBean = createBean(beanName, beanDefinition); return prototypeBean; } } //创建bean public Object createBean(String beanName, BeanDefinition beanDefinition) throws NoSuchMethodException { Class aClass = beanDefinition.getaClass(); //调用构造方法创建对象 Object instance = null; try { instance = aClass.getConstructor().newInstance(); //创建bean的过程中进行依赖注入 //遍历类的属性 Field[] fields = aClass.getDeclaredFields(); for (Field field : fields) { //判断属性上是否有autowired注解 if (field.isAnnotationPresent(MyAutowired.class)) { field.setAccessible(true); //赋值 -> 先根据类型再根据名字去找,我们这里只使用名字去找 会有循环依赖问题 field.set(instance, getBean(field.getName())); } } //依赖注入完成后,beanNameAware if (instance instanceof BeanNameAware) { ((BeanNameAware) instance).setBeanName(beanName); } //初始化前 for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) { instance = beanPostProcessor.postProcessBeforeInitialization(instance, beanName); } //依赖注入完成之后进行初始化操作 //判断是否实现了InitializingBean接口 if (instance instanceof InitializingBean) { ((InitializingBean) instance).afterPropertiesSet(); } //初始化后 //new MyBeanPostProcessor().postProcessAfterInitialization(instance, beanName); for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) { instance = beanPostProcessor.postProcessAfterInitialization(instance, beanName); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return instance; } }
MyAutowired
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface MyAutowired { String value() default ""; }
MyComponent
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface MyComponent { String value() default ""; }
MyComponentScan
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface MyComponentScan { String value() default ""; }
MyScope
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface MyScope { String value() default ""; }
测试代码
MyAppConfig
@MyComponentScan("com.sy.test") public class MyAppConfig { }
MyBeanPostProcessor
@MyComponent public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) { //创建bean的过程中,每一个bean都会调用此方法,也可以单独判断 if ("orderService".equals(beanName)) { System.out.println("生成orderService的代理对象"); Object proxyInstance = Proxy.newProxyInstance(MyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //切面逻辑 System.out.println(beanName + "执行切面逻辑"); return method.invoke(bean, args); } }); return proxyInstance; } else { System.out.println(beanName + "执行bean的后置处理器"); return bean; } } }
MyValue
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface MyValue { String value() default ""; }
MyValueBeanPostProcessor
@MyComponent public class MyValueBeanPostProcessor implements BeanPostProcessor { /** * 测试通过自定义注解给属性赋值 */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { Field[] declaredFields = bean.getClass().getDeclaredFields(); for (Field field : declaredFields) { if (field.isAnnotationPresent(MyValue.class)) { field.setAccessible(true); MyValue annotation = field.getAnnotation(MyValue.class); String value = annotation.value(); try { field.set(bean,value); } catch (IllegalAccessException e) { e.printStackTrace(); } } } return bean; } }
OrderInterface
public interface OrderInterface { void test(); }
OrderService
@MyComponent @MyScope("prototype") public class OrderService implements OrderInterface, InitializingBean { @MyAutowired private UserService userService; @MyValue("xxxxxx") private String testStr; @Override public void test() { System.out.println("myOrderService.test.........."); System.out.println("myOrderService.myUserService->" + userService); System.out.println("myOrderService.testStr->" + testStr); } @Override public void afterPropertiesSet() { System.out.println("myOrderService.afterPropertiesSet..."); } }
UserService
@MyScope("singleton") @MyComponent("userService") public class UserService implements InitializingBean, BeanNameAware { private String beanName; public void test() { System.out.println("myUserService.test.............."); } @Override public void afterPropertiesSet() { System.out.println("myUserService.afterPropertiesSet..."); } @Override public void setBeanName(String beanName) { System.out.println("userService.setBeanName..."); this.beanName = beanName; } }
TestSpring
public class TestSpring { @Test public void testCreateBean() throws ClassNotFoundException, NoSuchMethodException { //首先扫描 -> 创建单例bean BeanDefinition BeanPostProcessor MyApplicationContext applicationContent = new MyApplicationContext(MyAppConfig.class); UserService userService = (UserService) applicationContent.getBean("userService"); userService.test(); System.out.println("userService->" + applicationContent.getBean("userService")); System.out.println("userService->" + applicationContent.getBean("userService")); OrderInterface orderService = (OrderInterface) applicationContent.getBean("orderService"); orderService.test(); System.out.println("orderService->" + applicationContent.getBean("orderService")); System.out.println("orderService->" + applicationContent.getBean("orderService")); } }
测试结果
源码下载
本博客文章均已测试验证,欢迎评论、交流、点赞。
部分文章来源于网络,如有侵权请联系删除。
转载请注明原文链接:https://www.cnblogs.com/sueyyyy/p/16774188.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了