`

我的spring容器

    博客分类:
  • j2se
 
阅读更多

public class AplicationContextAnnotationListener implements
  ServletContextListener {
 Map<String, Object> map = new HashMap<String, Object>();
 public void contextDestroyed(ServletContextEvent event) {
  
 }

 public void contextInitialized(ServletContextEvent envent) {
  InputStream in = this.getClass().getResourceAsStream("beans.xml");
  SAXReader reader = new SAXReader();
  Document doc = null;
  try {
   doc = reader.read(in);
   Element root = doc.getRootElement();
   String packageName = root.element("context").attributeValue("base-package");
   Set<Class> classes = this.getClasses(packageName);
   this.instanceBeans(classes);
   this.injectObject(map);
  } catch (DocumentException e) {
   // TODO Auto-generated catch block
   throw new RuntimeException(e);
  }

 }
 
 //注入属性
 private void injectObject(Map<String,Object> map) {
  //对已实例化并存放在map里的所有对象进行迭代 注入属性
  Set<Map.Entry<String, Object>> set = map.entrySet();
  Iterator<Map.Entry<String, Object>> iter = set.iterator();
  while(iter.hasNext()){
   Entry<String, Object> entry = iter.next();
   Object bean = entry.getValue();
   Class beanClass = bean.getClass();
   Field[] fields = beanClass.getDeclaredFields();
   //获取该bean里所有的构造方法
   Constructor[] constructors = beanClass.getConstructors();
   try {
    //获得该对象的属性描述
    PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(beanClass).getPropertyDescriptors();
    for(Field field : fields){
     if(field.isAnnotationPresent(Resource.class)){
      String className = field.getAnnotation(Resource.class).value();
      String fieldName = field.getName();
      //迭代构造方法看构造方法里的参数有没有这个fileName
      for(Constructor constructor : constructors){
        TypeVariable[] typeVariables = constructor.getTypeParameters();
        System.out.println(typeVariables.length);
        for(TypeVariable typeVariable : typeVariables){
         String variableName = typeVariable.getName();
         System.out.println(variableName);
        }
      }
      Object property = map.get(className);
      //对属性描述进行迭代 查看标注Resource注解的属性的属性名是否与属性描述相同的
      for(PropertyDescriptor propertyDescriptor : propertyDescriptors){
       if(fieldName.equals(propertyDescriptor.getName())){
        //获取该属性的set方法
        Method method = propertyDescriptor.getWriteMethod();
        if(method==null){
         continue;
        }
        method.invoke(bean, property);
       }
      }
     }
    }
   } catch (Exception e) {
    // TODO Auto-generated catch block
    throw new RuntimeException(e);
   }
  }
 }
 //获取该包及其子包的class
 public Set<Class> getClasses(String packageName){
  //是否允许迭代子包
  boolean recursive = true;
  //定义存放class的集合
  Set<Class> classes = new LinkedHashSet<Class>();
  String packagedir = packageName.replace(".", "/");
  try {
   Enumeration<URL> dirs = Thread.currentThread().getContextClassLoader().getResources(packagedir);
   while(dirs.hasMoreElements()){
    URL url = dirs.nextElement();
    String protocol = url.getProtocol();
    if("file".equals(protocol)){
     //获取包的物理路径 大致是这个样子/D:/Tomcat 6.0/webapps/upload/WEB-INF/classes/com/cn/service/
     //不能直接用url.getFile() 否则 结果会是/D:/Tomcat%206.0/webapps/upload/WEB-INF/classes/com/cn/service/
     String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
     this.findAndAddClasses(packageName,filePath,classes,recursive);
    }
   }
  } catch (UnsupportedEncodingException e) {
   // TODO Auto-generated catch block
   throw new RuntimeException(e);
  } catch (IOException e) {
   // TODO Auto-generated catch block
   throw new RuntimeException(e);
  }
  return classes;
 }
 public void findAndAddClasses(String packageName,String filePath,Set<Class> classes,final boolean recursive){
  File dir  = new File(filePath);
  //看该路径是否存在 且必须是一个目录
  if(!(dir.exists())||!(dir.isDirectory())){
   return;
  }
  //对文件进行过滤 如果是子包且允许迭代或是一个class文件则不过滤
  File[] dirFiles = dir .listFiles(new FileFilter() {
   public boolean accept(File pathname) {
    return (recursive && pathname.isDirectory())||pathname.getName().endsWith(".class");
   }
  });
  //对文件列表进行迭代
  for(File file:dirFiles ){
   //如果是目录则继续进行扫描
   if(file.isDirectory()){
    findAndAddClasses(packageName+"."+file.getName(),file.getAbsolutePath(),classes,recursive);
   }else{
    //将.class去掉
    String className = file.getName().substring(0, file.getName().length()-6);
    try {
     //加载该class文件 并将获得的Class添加进classes
     classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName+"."+className));
    } catch (ClassNotFoundException e) {
     // TODO Auto-generated catch block
     throw new RuntimeException(e);
    }
   }
  }
 }
 
 public void instanceBeans(Set<Class> classes){
  for(Class cls : classes){
   if(cls.isAnnotationPresent(Repository.class)){
    String id = ((Repository) cls.getAnnotation(Repository.class)).id();
    //如果id为""则将该类名的首字母变成小写赋给id
    if("".equals(id)){
     id = cls.getSimpleName().substring(0,1).toLowerCase().concat(cls.getSimpleName().substring(1));
    }
    try {
     map.put(id, cls.newInstance());
    } catch (Exception e) {
     // TODO Auto-generated catch block
     throw new RuntimeException(e);
    }
   }
  }
 }
 public Object getBean(String beanName){
  return map.get(beanName);
 }
 //查看bean里有没有设置该属性的setter方法
 public boolean hasFieldSetMethod(){
  return false;
 }
 //查看bean里有没有设置该属性的构造方法
 public boolean hasIncludeFiledConstructor(){
  return false;
 }
}

分享到:
评论

相关推荐

    spring容器启动和关闭时事件监听

    spring容器启动和关闭时事件监听;spring容器启动和关闭时事件监听;spring容器启动和关闭时事件监听

    Spring简单模拟Spring容器

    标题中的“Spring简单模拟Spring容器”意味着我们将探讨Spring框架的核心特性——IoC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入),以及如何通过编程方式模拟Spring容器的工作原理。...

    简单Spring容器实现

    本主题将深入探讨“简单Spring容器实现”,基于提供的标签“源码”和“工具”,我们将聚焦于Spring容器的原理及其简易实现。下面,我们先来理解Spring容器的核心概念,然后逐步探索其内部机制,并通过一个名为...

    Spring容器的通俗理解及简单写法

    Spring容器是Spring框架的核心组成部分,它负责管理对象的生命周期和对象间的依赖关系。在Java开发中,Spring容器(也称为ApplicationContext或BeanFactory)扮演着重要角色,它通过控制反转(Inversion of Control,...

    在非spring注解类中使用spring容器中的bean_普通类中使用yml配置文件中的配置信息

    然而,在某些情况下,我们可能需要在非Spring注解的类中访问Spring容器中的Bean,或者在这些类中使用YAML配置文件中的配置信息。本篇将详细介绍如何在这样的场景下实现这一目标。 首先,让我们来理解如何在非Spring...

    Spring容器 .ppt

    Spring容器是Spring框架的核心组成部分,它负责管理对象的生命周期和对象之间的依赖关系。Spring容器的主要职责是读取配置元数据,创建和组装Bean,并提供Bean的完整生命周期管理。本篇内容将深入探讨Spring容器的...

    深度解析spring容器管理bean

    "深度解析spring容器管理bean"这一主题,旨在深入理解Spring如何通过反射机制、依赖注入(DI)以及XML或Java配置来实现对Bean的生命周期管理。 首先,Spring容器主要有两种类型:DefaultListableBeanFactory和...

    获取Spring容器

    ### 获取Spring容器的相关知识点 #### 一、Spring容器简介 Spring框架的核心是其IoC容器,也称为Spring容器。Spring容器负责管理应用对象的生命周期、配置以及装配过程。Spring提供了两种主要类型的容器: 1. **...

    获取spring容器的方法

    ### 获取Spring容器的方法详解 在Java开发中,Spring框架因其强大的依赖注入(Dependency Injection, DI)和面向切面编程(Aspect Oriented Programming, AOP)功能而被广泛使用。掌握如何获取Spring容器对于管理和...

    spring容器简单实例

    本实例将带你深入理解Spring容器的基本使用,通过实际操作来帮助你快速上手。 1. **Spring容器概述** Spring容器是Spring框架的核心,负责管理对象的生命周期和依赖关系。主要有两种类型的容器:BeanFactory和...

    JDK8 下 SpringBoot 应用动态编译 Java 源码并注入 Spring 容器

    基于接口、抽象类实现不停机动态调整代码的目的,将修改后的源码文件放置于指定目录下,读取文件后执行动态编译方法,即可将该类重新加载,新的类可以在Spring容器从新注册,且仅在当前窗口生效。如果重启了服务或...

    Spring 容器后处理器

    BeanFactoryPostProcessor接口是Spring框架提供的一个接口,用于扩展Spring容器的功能。该接口只有一个方法`postProcessBeanFactory`,该方法在容器加载完成之后被调用,可以用来改变容器中的配置或做一些初始化工作...

    spring容器学习笔记

    初始化和销毁方法在 Spring 容器中,我们可以通过配置来指定 Bean 在被创建后或销毁前需要执行的方法。这些方法可以用于执行初始化设置或者清理工作。 3.1. 初始化方法当我们想要在 Bean 创建完成后执行特定的初始...

    Spring容器中IOC

    Spring容器中IOC Spring容器中IOC(Inverse of Control,控制反转)是Spring框架的核心功能之一。IOC容器是Spring Framework的核心组件之一,负责管理应用程序中的对象实例,控制对象的生命周期,并提供依赖注入的...

    spring Ioc容器配置

    spring Ioc容器配置 IOC容器数据源配置 &lt;!-- 配置数据源 --&gt; destroy-method="close"&gt; &lt;value&gt;org.gjt.mm.mysql.Driver &lt;value&gt;jdbc:mysql://localhost:3306/demo &lt;value&gt;root ...

    spring动态向容器中添加bean和删除指定bean.md

    spring动态向容器中添加bean和删除指定bean,不需要重启应用

    spring 容器.docx

    Spring容器是Spring框架的核心组成部分,它负责管理和控制应用程序中的对象,这些对象被称为Bean。Spring容器主要有两种接口形式:BeanFactory和ApplicationContext,后者是前者的子接口。这两种接口都是用来表示...

    Spring源代码解析(一):IOC容器.doc

    在Spring源代码解析的第一部分,我们将聚焦于IOC容器,特别是BeanFactory接口,它是所有Spring容器的基础。 BeanFactory接口是Spring的基石,它定义了基本的容器操作,如获取Bean、检查Bean是否存在、确定Bean的...

    Spring之核心容器bean

    在Spring中,bean是一个由容器管理的对象,它的实例化、初始化、装配和销毁都是由Spring容器控制的。你可以通过XML、注解或者Java配置类来定义bean。例如,一个简单的XML配置如下: ```xml ``` 这里,`myBean`...

Global site tag (gtag.js) - Google Analytics