美文网首页
手写spring ioc注解方式(包扫描)+注解

手写spring ioc注解方式(包扫描)+注解

作者: ssttIsme | 来源:发表于2019-03-04 23:49 被阅读0次
    项目结构 注解创建方式
    注解创建方式
    使用注解可以避免在包扫描的时候为接口创建对象报错的问题
    
    package annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     *注解是java中的一种元数据-描述Java对象
     *用于描述java对象
     *本质上也是一个类(字节码对象)
     *它是jdk1.5的特性(jdk1.5就有了)
     *@Retention 表示定义的注解何时有效,RUNTIME运行时有效
     *@Target 表示定义的注解运行在哪里,TYPE应用在类上,METHOD应用在方法上,FIELD应用在类上
     */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Component {
    
    }
    
    
    package annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     *{ElementType.TYPE}的花括号可以省略,如:ElementType.TYPE,因为只有一个值
     *{ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.TYPE })
    public @interface Controller {
    
    }
    
    
    package annotation;
    
    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 Service {
    
    }
    
    
    package factory;
    
    import java.io.File;
    import java.io.FileFilter;
    import java.net.URL;
    import java.util.HashMap;
    import java.util.Map;
    
    import annotation.Component;
    import annotation.Controller;
    import annotation.Service;
    
    public class AnnotationApplicationContext {
        private Map<String,Object> beanMap=new HashMap<>();
        public AnnotationApplicationContext() {
            String pkg="project";
            scanPackage(pkg);
            
        }
        private void scanPackage(final String pkg){
            String pkgDir=pkg.replaceAll("\\.", "/");
            URL url = getClass().getClassLoader().getResource(pkgDir);
            File file=new File(url.getFile());
            File fs[]=file.listFiles(new FileFilter() {
                
                @Override
                public boolean accept(File file) {
                    String fName=file.getName();
                    if(file.isDirectory()){
                        scanPackage(pkg+"."+fName);
                    }else{
                        //判断文件后缀是否为.
                        if(fName.endsWith(".class")){
                            return true;
                        }
                    }
                    return false;
                }
            });
            for (File f : fs) {
                String fName=f.getName();
                //去除.class以后的文件名
                fName=fName.substring(0,fName.lastIndexOf("."));
                //将名字的第一个字母转为小写(用它作为key存储map)
                String key=String.valueOf(fName.charAt(0)).toLowerCase()+fName.substring(1);
                //构建一个类全名(包名.类名)
                String pkgCls=pkg+"."+fName;
                try {
                    //反射构建对象
                    Class<?> c = Class.forName(pkgCls);
                    //判定类上是否有注解isAnnotationPresent()
                    if(c.isAnnotationPresent(Controller.class)||
                            c.isAnnotationPresent(Service.class)||
                            c.isAnnotationPresent(Component.class)
                            ){
                        Object obj = c.newInstance();
                        //将对象放到map容器
                        beanMap.put(key, obj);
                    }
                    
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
        public Object getBean(String key){
            return beanMap.get(key);
        }
        public void close(){
            beanMap.clear();
            beanMap=null;
        }
    }
    
    
    package project.controller;
    
    import annotation.Controller;
    
    @Controller
    public class CarController {
        public void show(){
            System.out.println("CarController");
        }
    }
    
    
    package project.service.impl;
    
    import annotation.Service;
    import project.service.CarSercice;
    
    @Service
    public class CarServiceImpl implements CarSercice {
        public void save(){
            System.out.println("save car...");
        }
    }
    
    
    package project.service;
    
    public interface CarSercice {
        void save();
    }
    
    
    package test;
    
    import factory.AnnotationApplicationContext;
    import project.controller.CarController;
    import project.service.impl.CarServiceImpl;
    
    public class TestApp {
        public static void main(String[] args) {
            AnnotationApplicationContext ctx=new AnnotationApplicationContext();
            CarController obj = (CarController) ctx.getBean("carController");
            System.out.println(obj);
            obj.show();
            
            CarServiceImpl obj2=(CarServiceImpl) ctx.getBean("carServiceImpl");
            System.out.println(obj2);
            obj2.save();
            ctx.close();
            
        }
    }
    
    

    运行TestApp的运行结果

    project.controller.CarController@5323cf50
    CarController
    project.service.impl.CarServiceImpl@53ffb7d4
    save car...
    

    相关文章

      网友评论

          本文标题:手写spring ioc注解方式(包扫描)+注解

          本文链接:https://www.haomeiwen.com/subject/rvhguqtx.html