IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 手写简易Spring框架 -> 正文阅读

[Java知识库]手写简易Spring框架

我们前面分析很多的Spring源码,现在我们来手写一个简易的Spring源码

创建一个maven工程。

public class Test {
 ? ?public static void main(String[] args) {
 ? ? ? ?AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
 ? ? ? ?UserService userService = context.getBean("UserService", UserService.class);
 ? ? ? ?userService.test();
 ?  }
}

在我们的通常Spring项目中,一定有这几步,我们想要手写就得先模拟出这几个方法和类。

Autowrite注解的依赖注入实现: 遍历出类中的所有属性,循环他们进行判断是否加了Autowrite注解,通过getBean得到对象,再把得到的对象赋值给instance。(记得开启Accessible)

创建一个扫描注解?创建bean注解??一个scope判断是否是单例注解??在启动类上配置扫描注解,给扫描路径???创一个Annotationcontext类??有get?bean方法。通过得到注解扫描的类,通过App扫描得到注解所需要扫描的地址,通过截取?替换路径,解析成为com.user.service字符串,把他放入到classloader.loadclass中得到class对象?判断对象上是否有component注解,得到当前bean对应的名字????(创建beandefinition描述类??里面有?scope??class属性?)设置bd的class属性为当前类属性????判断当前类是否有原型bean注解??没有就设置它的描述scope为单例??有就设置它为注解上的值?????最后将它们放入beandefinitionmap中????????当我们在getbean的时候??传入beanName?我们在bdMap中去找???找到了则进行判断是否为单例bean??是则直接返回这里返回的bean对象都是一样的,称之为单例bean?????不是则通过bd中的class类通过反射进行创建,这里每创建的bean都是不一样的???不存在就抛出异常?????当然spring在启动的时候就把bean对象创建好了??我们通过循环bad.enteyset??得到bean名字和bd??判断是否是单例的,是就直接放入单例池。

package com.spring;
?
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
?
public class LuoChaoApplicationContext {
?
?
 ?  //对应AppConfig.class
 ?  private Class configClass;
?
 ?  //单例池 存放单例bean  确保我们得到得对象都是单例的。
 ?  private ConcurrentHashMap<String,Object> singletonObjects = new ConcurrentHashMap<>();
?
 ?  //存放BeanDefintion对象的HashMap
 ?  private ConcurrentHashMap<String,BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
?
 ?  //存放BeanPostProcessor集合
 ?  private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();
?
 ?  public LuoChaoApplicationContext(Class configClass) {
 ? ? ?  this.configClass = configClass;
?
 ? ? ?  //解析配置类
 ? ? ?  // Compontent注解---》扫描路径---》扫描---》BeanDefinition---》beanDefinitionMap
 ? ? ?  sacn(configClass);
?
 ? ? ?  //在我们启动的时候就要把所有的单例bean创建好
 ? ? ?  /*
 ? ? ?  entrySet()的返回值也是返回一个Set集合,此集合的类型为Map.Entry。
 ? ? ? ? Map.Entry是Map声明的一个内部接口,此接口为泛型,定义为Entry<K,V>。
 ? ? ? ? 它表示Map中的一个实体(一个key-value对)。接口中有getKey(),getValue方法。
 ? ? ? ? */
 ? ? ?  for (Map.Entry<String,BeanDefinition> entry : beanDefinitionMap.entrySet()) {
 ? ? ? ? ?  //得到bean的名字
 ? ? ? ? ?  String beanName = entry.getKey();
 ? ? ? ? ?  BeanDefinition beanDefinition = entry.getValue();
 ? ? ? ? ?  //判断是否是单例bean
 ? ? ? ? ?  if (beanDefinition.getScope().equals("singleton")){
 ? ? ? ? ? ? ?  Object bean = createBean(beanName,beanDefinition);
 ? ? ? ? ? ? ?  //是单例的把它放到单例池里面去
 ? ? ? ? ? ? ?  singletonObjects.put(beanName,bean);
 ? ? ? ? ?  }
 ? ? ?  }
?
?
 ?  }
?
 ?  //对应getBean方法
 ?  public Object getBean(String beanName){
 ? ? ?  //判断传进来的这个名字有没有对应的bean描述
 ? ? ?  if (beanDefinitionMap.containsKey(beanName)){
 ? ? ? ? ?  BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
 ? ? ? ? ?  //判断名字对象的对象是否是单例的
 ? ? ? ? ?  if (beanDefinition.getScope().equals("singleton")){
 ? ? ? ? ? ? ?  //从单例池中拿到这个对象
 ? ? ? ? ? ? ?  Object o = singletonObjects.get(beanName);
 ? ? ? ? ? ? ?  return o;
 ? ? ? ? ?  }else {
 ? ? ? ? ? ? ?  //原型bean  创建bean对象。
 ? ? ? ? ? ? ?  Object bean = createBean(beanName,beanDefinition);
 ? ? ? ? ? ? ?  return bean;
 ? ? ? ? ?  }
?
 ? ? ?  }else {
 ? ? ? ? ?  //不存在
 ? ? ? ? ?  throw new NullPointerException();
 ? ? ?  }
?
 ?  }
?
?
 ?  // 通过beanDefinition描述创建一个对象
 ?  public Object createBean(String beanName ,BeanDefinition beanDefinition){
 ? ? ?  //得到bean的class对象
 ? ? ?  Class clazz = beanDefinition.getClazz();
 ? ? ?  //通过反射调用无参构造进行bean的创建
 ? ? ?  try {
 ? ? ? ? ?  Object instance = clazz.getDeclaredConstructor().newInstance();
?
 ? ? ? ? ?  //依赖注入 (不考虑循环依赖问题)
 ? ? ? ? ?  // 得到类中的属性
 ? ? ? ? ?  Field[] declaredFields = clazz.getDeclaredFields();
?
 ? ? ? ? ?  for (Field declaredField : clazz.getDeclaredFields()) {
 ? ? ? ? ? ? ?  //判断是否加了自动注入注解。
 ? ? ? ? ? ? ?  if (declaredField.isAnnotationPresent(Autowired.class)){
 ? ? ? ? ? ? ? ? ?  //此处我们先只判断byName 我们调用getBean得到对象
 ? ? ? ? ? ? ? ? ?  Object bean = getBean(declaredField.getName());
 ? ? ? ? ? ? ? ? ?  //判断required是否为false
 ? ? ? ? ? ? ? ? ?  Autowired annotation = declaredField.getAnnotation(Autowired.class);
 ? ? ? ? ? ? ? ? ?  boolean required = annotation.required();
 ? ? ? ? ? ? ? ? ?  //判断bean为空并且required值为false 无法注入值
 ? ? ? ? ? ? ? ? ?  if (bean==null && required){
 ? ? ? ? ? ? ? ? ? ? ?  //抛出异常
 ? ? ? ? ? ? ? ? ? ? ?  throw new RuntimeException();
 ? ? ? ? ? ? ? ? ?  }
 ? ? ? ? ? ? ? ? ?  //实际上setAccessible是启用和禁用访问安全检查的开关
 ? ? ? ? ? ? ? ? ?  declaredField.setAccessible(true);
 ? ? ? ? ? ? ? ? ?  // 将bean对象赋值给instance属性。
 ? ? ? ? ? ? ? ? ?  declaredField.set(instance,bean);
 ? ? ? ? ? ? ?  }
 ? ? ? ? ?  }
?
 ? ? ? ? ?  //判断是否实现了BeanNameAware接口  也叫做回调
 ? ? ? ? ? ? ?  if (instance instanceof BeanNameAware){
 ? ? ? ? ? ? ? ? ?  ((BeanNameAware) instance).setBeanName(beanName);
 ? ? ? ? ? ? ?  }
?
 ? ? ? ? ? ? ?  //遍历出所有存放的beanPostProcessor
 ? ? ? ? ? ? ?  for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
 ? ? ? ? ? ? ? ? ?  //将对象和名字传入 进行初始化前的操作
 ? ? ? ? ? ? ? ? ?  instance = beanPostProcessor.postProcessBeforeInitialization(instance,beanName);
 ? ? ? ? ? ? ?  }
?
 ? ? ? ? ? ? ?  //判断是否实现了InitializingBean接口 ? 初始化
 ? ? ? ? ? ? ?  if (instance instanceof InitializingBean){
 ? ? ? ? ? ? ? ? ?  try {
 ? ? ? ? ? ? ? ? ? ? ?  ((InitializingBean) instance).afterPropertiesSet();
 ? ? ? ? ? ? ? ? ?  } catch (Exception e) {
 ? ? ? ? ? ? ? ? ? ? ?  e.printStackTrace();
 ? ? ? ? ? ? ? ? ?  }
 ? ? ? ? ? ? ?  }
?
 ? ? ? ? ? ? ?  //遍历出所有存放的beanPostProcessor
 ? ? ? ? ? ? ?  for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
 ? ? ? ? ? ? ? ? ?  //将对象和名字传入 进行初始化后的操作
 ? ? ? ? ? ? ? ? ?  instance = beanPostProcessor.postProcessAfterInitialization(instance,beanName);
 ? ? ? ? ? ? ?  }
?
 ? ? ? ? ? ? ?  //BeanPostProcessor
?
 ? ? ? ? ?  //直接返回创建的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;
 ?  }
?
?
?
 ?  private void sacn(Class configClass) {
 ? ? ?  //拿到配置类进行解析
 ? ? ?  //解析ComponentScan注解拿到扫描路径进行扫描
 ? ? ?  ComponentScan componentScanAnnotation = (ComponentScan) configClass.getDeclaredAnnotation(ComponentScan.class);
 ? ? ?  //拿到注解扫描得路径
 ? ? ?  String path = componentScanAnnotation.value();
?
 ? ? ?  //进行扫描类上面是否加载了ComponentScan注解
 ? ? ?  /**
 ? ? ? ? * Bootstrap---》jre/lib
 ? ? ? ? * ext----》jre/ext/lib
 ? ? ? ? * App----》classpath
 ? ? ? ?  */
 ? ? ?  ClassLoader classLoader = LuoChaoApplicationContext.class.getClassLoader();//得到得就是app
 ? ? ?  URL resource = classLoader.getResource("com/luochao/service");
 ? ? ?  //得到service目录
 ? ? ?  File file = new File(resource.getFile());
 ? ? ?  //判断是不是一个目录
 ? ? ?  if (file.isDirectory()){
 ? ? ? ? ?  File[] files = file.listFiles();
 ? ? ? ? ?  for (File file1 : files) {
 ? ? ? ? ? ? ?  //E:\code\springBychaoluo\target\classes\com\luochao\service\UserService.class
 ? ? ? ? ? ? ?  System.out.println(file1.getAbsolutePath());
?
 ? ? ? ? ? ? ?  /*
 ? ? ? ? ? ? ?  利用类加载加载class对象
 ? ? ? ? ? ? ?  我们要需要得不是所有得路径,我们只需要com.luochao.service.UserService路径
 ? ? ? ? ? ? ?  所以我们进行分解路径
 ? ? ? ? ? ? ? ? */
 ? ? ? ? ? ? ?  String fileName = file1.getAbsolutePath();
 ? ? ? ? ? ? ?  //判断是.class文件才进行截取替换
 ? ? ? ? ? ? ?  if (fileName.endsWith(".class")){
 ? ? ? ? ? ? ? ? ?  String className = fileName.substring(fileName.indexOf("com"), fileName.indexOf(".class"));
 ? ? ? ? ? ? ? ? ?  //com.luochao.service.UserService
 ? ? ? ? ? ? ? ? ?  className  = className.replace("\\", ".");
 ? ? ? ? ? ? ? ? ?  System.out.println(className);
?
 ? ? ? ? ? ? ? ? ?  try {
 ? ? ? ? ? ? ? ? ? ? ?  Class<?> aClass = classLoader.loadClass(className);
 ? ? ? ? ? ? ? ? ? ? ?  //判断类上是否有Component注解
 ? ? ? ? ? ? ? ? ? ? ?  if (aClass.isAnnotationPresent(Component.class)){
 ? ? ? ? ? ? ? ? ? ? ? ? ?  //表示当前这个类是一个bean
 ? ? ? ? ? ? ? ? ? ? ? ? ?  //解析类,判断当前bean是单例bean,还是原型bean 还是prototype的bean
 ? ? ? ? ? ? ? ? ? ? ? ? ?  // BeanDefinition bean的定义
?
 ? ? ? ? ? ? ? ? ? ? ? ? ?  //扫描到了LuoChaoBeanPostProcessor进行是否有实现BeanPostProcessor
 ? ? ? ? ? ? ? ? ? ? ? ? ?  //判断当前的aclass是否实现了BeanPostProcessor接口
 ? ? ? ? ? ? ? ? ? ? ? ? ?  if (BeanPostProcessor.class.isAssignableFrom(aClass)){
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  //利用反射得到对象  在spring是使用getBean的方法执行的 使得在BeanPostProcessor中我们也可以自动注入bean对象  但是这里我们就用简单的办法容易理解。
// ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  String name = aClass.getName();
// ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  BeanPostProcessor instance = (BeanPostProcessor) getBean(name);
// ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  beanDefinitionMap.put(name,beanDefinition);
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  BeanPostProcessor instance = (BeanPostProcessor) aClass.getDeclaredConstructor().newInstance();
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  //存放到集合中
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  beanPostProcessorList.add(instance);
 ? ? ? ? ? ? ? ? ? ? ? ? ?  }
?
 ? ? ? ? ? ? ? ? ? ? ? ? ?  Component componentAnnotation = aClass.getDeclaredAnnotation(Component.class);
 ? ? ? ? ? ? ? ? ? ? ? ? ?  //当前bean类所对应的名字
 ? ? ? ? ? ? ? ? ? ? ? ? ?  String beanName = componentAnnotation.value();
?
 ? ? ? ? ? ? ? ? ? ? ? ? ?  //表示bean的一个定义
 ? ? ? ? ? ? ? ? ? ? ? ? ?  BeanDefinition beanDefinition = new BeanDefinition();
 ? ? ? ? ? ? ? ? ? ? ? ? ?  //给beandefinition类的class属性设置值为当前类属性
 ? ? ? ? ? ? ? ? ? ? ? ? ?  beanDefinition.setClazz(aClass);
?
 ? ? ? ? ? ? ? ? ? ? ? ? ?  //判断是否存在scope注解
 ? ? ? ? ? ? ? ? ? ? ? ? ?  if (aClass.isAnnotationPresent(Scope.class)){
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  //原型bean
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  Scope scopeAnnotation = aClass.getDeclaredAnnotation(Scope.class);
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  beanDefinition.setScope(scopeAnnotation.value());
 ? ? ? ? ? ? ? ? ? ? ? ? ?  }else {
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  //单例bean 设置它对应的描述为单例的
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  beanDefinition.setScope("singleton");
 ? ? ? ? ? ? ? ? ? ? ? ? ?  }
 ? ? ? ? ? ? ? ? ? ? ? ? ?  //存放拿到的beanName
 ? ? ? ? ? ? ? ? ? ? ? ? ?  beanDefinitionMap.put(beanName,beanDefinition);
 ? ? ? ? ? ? ? ? ? ? ?  }
 ? ? ? ? ? ? ? ? ?  } catch (ClassNotFoundException e) {
 ? ? ? ? ? ? ? ? ? ? ?  e.printStackTrace();
 ? ? ? ? ? ? ? ? ?  } catch (InstantiationException e) {
 ? ? ? ? ? ? ? ? ? ? ?  e.printStackTrace();
 ? ? ? ? ? ? ? ? ?  } catch (InvocationTargetException e) {
 ? ? ? ? ? ? ? ? ? ? ?  e.printStackTrace();
 ? ? ? ? ? ? ? ? ?  } catch (NoSuchMethodException e) {
 ? ? ? ? ? ? ? ? ? ? ?  e.printStackTrace();
 ? ? ? ? ? ? ? ? ?  } catch (IllegalAccessException e) {
 ? ? ? ? ? ? ? ? ? ? ?  e.printStackTrace();
 ? ? ? ? ? ? ? ? ?  }
 ? ? ? ? ? ? ?  }
 ? ? ? ? ?  }
 ? ? ?  }
 ?  }
?
?
?
}
public class BeanDefinition {
?
 ?  //bean的类型
 ?  private Class clazz;
 ?  //是否是原型bean
 ?  private String scope;
?
?
 ?  public Class getClazz() {
 ? ? ?  return clazz;
 ?  }
?
 ?  public void setClazz(Class clazz) {
 ? ? ?  this.clazz = clazz;
 ?  }
?
 ?  public String getScope() {
 ? ? ?  return scope;
 ?  }
?
 ?  public void setScope(String scope) {
 ? ? ?  this.scope = scope;
 ?  }
}

//Bean的描述类
package com.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 {
 ?  String value() default "";
?
 ?  boolean required() default true;
}
?回调
package com.spring;
?
//回调
public interface BeanNameAware {
?
 ?  void setBeanName(String name);
}

package com.spring;
?
//AOP的最终归宿
public interface BeanPostProcessor {
?
 ?  //初始化前
 ?  Object postProcessBeforeInitialization(Object bean, String beanName);
?
 ?  //初始化后
 ?  Object postProcessAfterInitialization(Object bean, String beanName);
?
?
}
?
package com.spring;
?
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
?
//生成bean注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
 ?  String value() default "";
}
package com.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.TYPE)
public @interface ComponentScan {
?
 ?  String value();
}
package com.spring;
?
//初始化
public interface InitializingBean {
?
 ?  void afterPropertiesSet() throws Exception;
}
?
package com.spring;
?
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
?
//原型bean标签
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Scope {
 ?  String value();
?
 ?  //单例bean是指我们在测试类中通过getbean多次得到得对象是同一个  原型bean得到得则是不同得对象
}
package com.luochao.service;
?
?
import com.spring.BeanPostProcessor;
import com.spring.Component;
?
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
?
?
//将具体的AOP代理逻辑封装成一个LuoChaoBeanPostProcessor放入Spring容器中
@Component
public class LuoChaoBeanPostProcessor implements BeanPostProcessor {
?
 ?  @Override
 ?  public Object postProcessBeforeInitialization(Object bean, String beanName) {
 ? ? ?  if (beanName.equals("userService")){
 ? ? ? ? ?  System.out.println("初始化前");
 ? ? ? ? ?  ((UserService)bean).setBeanName("我是帅哥");
 ? ? ?  }
 ? ? ?  return bean;
 ?  }
?
 ?  @Override
 ?  public Object postProcessAfterInitialization(Object bean, String beanName) {
 ? ? ?  System.out.println("初始化后");
 ? ? ?  //模拟简易的AOP 这里就可以判断是否要aop
 ? ? ?  if (beanName.equals("userService")){
 ? ? ? ? ?  /*
 ? ? ? ? ?  JDK动态代理生成一个代理对象
 ? ? ? ? ?  在spring源码中 开启Aop就是在Spring容器中生成一个BeanPostProcessor的Bean对象
 ? ? ? ? ? ? 放到Spring容器中去
 ? ? ? ? ? ? */
 ? ? ? ? ?  Object proxyInstance = Proxy.newProxyInstance(LuoChaoBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
 ? ? ? ? ? ? ?  @Override
 ? ? ? ? ? ? ?  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 ? ? ? ? ? ? ? ? ?  //找到jionpoint 切点
 ? ? ? ? ? ? ? ? ?  System.out.println("AOP代理逻辑");
 ? ? ? ? ? ? ? ? ?  // 执行bean中的方法进行代理
 ? ? ? ? ? ? ? ? ?  return method.invoke(bean,args);
 ? ? ? ? ? ? ?  }
 ? ? ? ? ?  });
 ? ? ? ? ?  //代理对象
 ? ? ? ? ?  return proxyInstance;
 ? ? ?  }
 ? ? ?  return bean;
 ?  }
}
package com.luochao.service;
?
import com.spring.Component;
?
@Component("peopleService")
public class PeopleService {
?
?
}
package com.luochao.service;
?
public interface UserService {
?
 ?  void test();
?
 ?  void setBeanName(String beanName);
}
package com.luochao.service;
?
import com.spring.Autowired;
import com.spring.Component;
import com.spring.InitializingBean;
?
?
@Component("userService")
public class UserServiceImpl implements UserService {
?
 ?  @Autowired
 ?  private PeopleService peopleService;
?
 ?  private String beanName;
?
 ?  public void setBeanName(String beanName) {
 ? ? ?  this.beanName = beanName;
 ?  }
?
 ?  // Aware 回调
 ?  // ?  @Override
 ?  // ?  public void setBeanName(String name) {
 ?  // ? ? ?  beanName = name;
 ?  // ?  }
?
 ?  public void test(){
 ? ? ?  System.out.println(peopleService);
 ? ? ?  System.out.println(beanName);
 ?  }
?
?
// ?  //初始化
// ?  @Override
// ?  public void afterPropertiesSet() throws Exception {
// ? ? ?  System.out.println("初始化");
// ?  }
}
?
package com.luochao;
?
import com.spring.ComponentScan;
?
// 扫描启动类
@ComponentScan("com.luochao.service")
public class AppConfig {
}
?
package com.luochao;
?
import com.luochao.service.UserService;
import com.luochao.service.UserServiceImpl;
import com.spring.LuoChaoApplicationContext;
?
public class Test {
?
 ?  public static void main(String[] args) {
 ? ? ?  LuoChaoApplicationContext luoChaoApplicationContext = new LuoChaoApplicationContext(AppConfig.class);
 ? ? ?  UserService userService = (UserService) luoChaoApplicationContext.getBean("userService");
 ? ? ?  userService.test();
 ? ? ?  //1.代理对象 ? 2.业务test
?
 ?  }
}
至此我们模拟了Spring的扫描bean 并且注入bean 简易的Aop 简易的回调  还有单例池。后面继续完善。

迈出这一小步,一定能跨上山巅。
?
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-24 10:24:23  更:2021-09-24 10:25:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 11:02:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码