简单模拟IOC容器:返回对象并能抛出异常

本次要求:已知com.zzj.vo包下分别有Tiger、lion、Elephant三个Java源文件,请据此实现以下功能:
①、自定义一个名为Component的注解,要求该注解只能用于类且代码运行时该注解依然有效;
②、为Tiger和Lion类添加component注解
③、在Application类中定义静态代码块,该代码块可自动将有Component注解修饰的类创建对象并放在Map集合中;然后定义一个名为getBean的static方法,要求传入Class类实例时返回该Class类对应类的对象,如果没有Class类对应的对象,则引发NoSuchBeanDefinitionException异常并提示“No qualifying bean of type ‘com.lq.vo.类名‘available

Component注解

package com.zzj.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//范围只限定类,存在周期运行后
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {

}

定义三个java类并添加注解

package com.zzj.vo;
public class Elephant {

}

package com.zzj.vo;
import com.zzj.annotation.Component;
@Component
public class Lion {

}

package com.zzj.vo;
import com.zzj.annotation.Component;
@Component
public class Tiger {

}

application类

package com.zzj;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.NoSuchBeanDefinitionException;

import com.zzj.annotation.Component;

public class Application {

        //定义map集合存放对应类和对应的class对象
    private static Map<Class,Object> map = new HashMap<Class,Object>();

    static{

        String packageName = "com.zzj.vo";
        //获取包的绝对路径
        String path = ClassLoader.getSystemResource("").getPath() + packageName.replace(".",File.separator);
        //路径中文转码,由于是静态方法不能使用
        //path = java.net.URLDecoder.decode(path,"utf-8");
        //采用字符替换
        path = path.replace("%e7%a8%8b%e5%ba%8f%e7%8c%bf","程序猿");

        //获取包里的所有类
        File[] files = new File(path).listFiles();

        //获取所有类的相对路径(包名+类名,无扩展名)
        for (File file : files){
            String fileName = file.getName();
            String className = packageName + "." + fileName.substring(0,fileName.indexOf("."));

            //将获取的类放入Map集合,key为类型,value为映射对象(默认为对象地址)
            try {
                Class clazz = Class.forName(className);
                if(clazz.getAnnotation(Component.class) != null){
                    map.put(clazz,clazz.newInstance());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }

        //抛出异常
        public static Object getBean(Class clazz){
        Object object =  map.get(clazz);
        if(object == null){
            throw new NoSuchBeanDefinitionException("No qualifying bean of type ‘"+clazz.getName()+"‘available");
        }

        return object;
    }

}
    

异常类

package com.zzj.exception;

public class NoSuchBeanDefinitionException extends RuntimeException{

    private static final long serialVersionUID = 8124869159299733396L;

    public NoSuchBeanDefinitionException(String msg) {

        super(msg);

    }

}

测试类

package com.zzj.test;

import com.zzj.vo.Lion;

import com.zzj.Application;

/*
 已知com.zzj.vo包下分别有Tiger、lion、Elephant三个Java源文件,请据此实现以下功能:
①、自定义一个名为Component的注解,要求该注解只能用于类且代码运行时该注解依然有效;
②、为Tiger和Lion类添加component注解
③、在Application类中定义静态代码块,该代码块可自动将有Component注解修饰的类创建对象并放在Map集合中;然后定义一个名为getBean的static方法,
要求传入Class类实例时返回该Class类对应类的对象,如果没有Class类对应的对象,则引发NoSuchBeanDefinitionException异常并
提示“No qualifying bean of type ‘com.lq.vo.类名‘available”;
*/
public class Test {

    public static void main(String[] args){

        Object object = Application.getBean(Lion.class);
        System.out.println(object);

    }

}

运行结果

有对应对象的:输出对象地址

没有对应对象的:抛出异常

原文地址:https://www.cnblogs.com/yimengxianzhi/p/12244143.html

时间: 2024-10-14 05:48:42

简单模拟IOC容器:返回对象并能抛出异常的相关文章

简单模拟IOC容器:为添加了@Autowired的属性赋值(初始值)

创建@Autowired注解 package com.zzj.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; //设置范围和生存周期 @Target({ElementType.TYPE,ElementType.FI

几句代码简单实现IoC容器

前言 最近在调试EasyNetQ代码的时候发现里面有一段代码,就是IoC容器的简单实现,跟着他的代码敲了一遍,发现了奇妙之处.当然也是因为我才疏学浅导致孤陋寡闻了.他的思路就是通过动态调用构造函数生成对象,然后将对象保存,调用的时候进行单例调用,而且,代码中不会存在 new 字眼.所有实例对象的创建和映射都在容器中实现.当然,还是用第三方的容器比较稳妥,本文中只是很简单的一个示范.具体理解的是否正确,我也不敢说,只不过,能达到一些预期的效果,功能不够强大. 解析 首先,我们先添加几个接口.ISe

比Spring简单的IoC容器

比Spring简单的IoC容器 Spring 虽然比起EJB轻量了许多,但是因为它需要兼容许多不同的类库,导致现在Spring还是相当的庞大的,动不动就上40MB的jar包, 而且想要理解Spring的内部运行机制,阅读它的代码非常重要, 但是往往它的代码非常的"多". 现在根据Spring对Bean的生命周期的处理, 编写出一款非常小的IoC容器, 没有了对XML的解析,而是通过对Config对象的构造而完成IoC配置文件的声明, 相比较XML的方式, 对重构软件非常具有好处, 并且

最简单的ioc容器代码(低仿Spring )

Spring 的一大核心就是IOC,控制反转(依赖注入). 对象交由容器去控制,降低耦合性. Spring 的ioc实现原理其实很简单,容器启动后读取并解析配置文件,根据配置文件中<bean>标签的class属性,通过反射生成类,将各个属性都通过反射设置好值,最后将已经创建好的bean保存到容器中,等待注入. 详细的说明在这里:http://www.bccn.net/Article/web/jsp/jszl/200810/8059.html 参考这个帖子自己动手写了写,感觉对ioc理解又深入了

使用反射机制简单模拟IOC效果

package anno; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; /** * @program: tx_annotation_demo * @description: 使用反射机制模拟实现IOC(控制反

spring-从普通java类取得注入spring Ioc容器的对象的方案

1.启动服务时通过spring容器的监听器(继承ContextLoaderListener 监听器的方法) public class ListenerSpringContext extends ContextLoaderListener { private final Logger log = LoggerFactory.getLogger(ListenerSpringContext.class); public void contextInitialized(ServletContextEve

模拟服务容器Ioc

服务容器是一个用于管理类依赖和执行依赖注入的强大工具. 一个类要被容器所能够提取,必须要先注册至这个容器.既然称这个容器叫做服务容器,那么我们需要某个服务,就得先注册.绑定这个服务到容器,那么提供服务并绑定服务至容器的东西就是服务提供器(ServiceProvider). 依赖注入和控制反转是对同一件事情的不同描述,它们描述的角度不同.依赖注入是从应用程序的角度在描述,应用程序依赖容器创建并注入它所需要的外部资源.而控制反转是从容器的角度在描述,容器控制应用程序,由容器反向的向应用程序注入应用程

深入理解Spring--动手实现一个简单的SpringIOC容器

接触Spring快半年了,前段时间刚用Spring4+S2H4做完了自己的毕设,但是很明显感觉对Spring尤其是IOC容器的实现原理理解的不到位,说白了,就是仅仅停留在会用的阶段,有一颗想读源码的心于是买了一本计文柯的<Spring技术内幕>,第二章没看完,就被我扔一边了,看的那是相当痛苦,深深觉得自己资质尚浅,能力还不够,昨天在网上碰巧看到一个实现简单的SpringIOC容器的视频教程,于是跟着做了一遍,竟然相当顺利,至少每一行代码都能理解,于是细心整理了一番,放在这里. 主要思想: 提到

自己动手开发IOC容器

前两天写简历,写了一句:精通Spring IoC容器.怎么个精通法?还是自己动手写个IOC容器吧. 什么是IoC(Inversion of Control)?什么是DI(Dependency Injection)?不多解释,自己Google!希望你先明确几个概念,该文章不做这方面的阐述,重点关注如何实现.我将用简要的语言从需求,设计,代码三方面来描述一个简单的IoC容器,来说明IoC容器是如何帮我们创建类的实例.如何实现依赖注入,最后会奉上一个完整的IoC容器实例. 一.需求,实现一个IoC容器