码迷,mamicode.com
首页 > 其他好文 > 详细

IOC容器的简单实现

时间:2020-05-06 21:37:56      阅读:72      评论:0      收藏:0      [点我收藏+]

标签:substring   bsp   shm   exist   users   end   this   targe   element   

IOC:控制反转。原先是程序员控制Java对象的创建,JVM GC负责Java对象的销毁,控制权在程序员手中。现在Java Bean的
实例对象由IOC容器负责创建、销毁,程序员反而是无需关心Bean的生命周期。这就是控制反转。


原理:内存中建立一个currentHashMap当作容器(考虑到多线程),采用(BeanID/BeanName,statance)形式存储Bean。
bean的建立在容器启动之后会通过Java反射来创建对象实例(通过注解、XML),然后放入容器中。依赖注入(一个bean中
含有其他bean)可以通过反射获取beanName/ID,然后遍历容器,获取到对应的Bean。

 

手动写简易实现:

目录图:

技术图片

 

 

SelfAutowired:
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SelfAutowired {

}

  

SelfService:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SelfService {
}
SelfPathXmlApplicationContext:
public class SelfPathXmlApplicationContext {
    /**
     * 包名
     */
    private String packageName;
    //IOC容器
    private ConcurrentHashMap<String, Object> beans = null;

    public SelfPathXmlApplicationContext(String packageName) throws Exception {
        System.out.println("容器类正在初始化");
        beans = new ConcurrentHashMap<String, Object>();
        this.packageName = packageName;
        initBeans();
        initEntryField();
        Arrays.asList(1,2,3);
    }

    /**
     * Description: 初始化所有的Bean
     *
     * @param
     * @return void
     * @date 9:44 2020/4/27
     */
    private void initBeans() throws Exception {
        //获取包下的所有类 TODO
        Set<Class<?>> classes = ClassUtil.scanPackage(packageName);
        //获取所有的类
        ConcurrentHashMap<String, Object> classAnnotation = findClassExistAnnotation(classes);
        if (classAnnotation == null || classAnnotation.isEmpty()) {
            throw new Exception("该包下没有任何注解");
        }
    }

    /**
     * Description: 判断是否有注解,并且初始化到容器里
     *
     * @param
     * @return java.util.concurrent.ConcurrentHashMap<java.lang.String, java.lang.Object>
     * @date 9:52 2020/4/27
     */
    private ConcurrentHashMap<String, Object> findClassExistAnnotation(Set<Class<?>> classes) throws InstantiationException, IllegalAccessException {
        for (Class<?> classinfo : classes) {
            SelfService annotation = classinfo.getAnnotation(SelfService.class);
            if (annotation != null) {
                String className = classinfo.getSimpleName();
                String beanId = toLowerCaseFirstOne(className);
                Object newInstance = newInstance(classinfo);
                beans.put(beanId, newInstance);
            }
        }
        return beans;
    }

    /**
     * Description:首字母转小写
     *
     * @param s
     * @return java.lang.String
     * @date 9:57 2020/4/27
     */
    private String toLowerCaseFirstOne(String s) {
        if(Character.isLowerCase(s.charAt(0))){
            return s;
        }else {
            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
        }
    }

    /**
     * Description: 根据类名获取实例对象
     *
     * @param classinfo
     * @return java.lang.Object
     * @date 9:56 2020/4/27
     */
    private Object newInstance(Class<?> classinfo) throws IllegalAccessException, InstantiationException {
        return classinfo.newInstance();
    }

    private void initEntryField() throws Exception {
        for (Map.Entry<String, Object> entry : beans.entrySet()) {
            //判断属性上是否有注解
            Object bean = entry.getValue();
            attriAssign(bean);
        }
    }

    /**
     * Description: 依赖注入原理
     *
     * @param object
     * @return void
     * @date 17:53 2020/4/26
     */
    private void attriAssign(Object object) throws Exception {
        //1、利用反射获取当前类的属性
        Class<? extends Object> classInfo = object.getClass();
        Field[] declaredFields = classInfo.getDeclaredFields();
        //2、判断当前类属性是否存在注解
        for (Field field : declaredFields) {
            SelfAutowired extResource = field.getAnnotation(SelfAutowired.class);
            if (extResource != null) {
                String beanId = field.getName();
                Object bean = getBean(beanId);
                if (bean != null) {
                    field.setAccessible(true);
                    field.set(object, bean);
                }
            }
        }
    }

    /**
     * Description: 根据beanID获取bean
     *
     * @param beanId
     * @return java.lang.Object
     * @date 9:41 2020/4/27
     */
    public Object getBean(String beanId) throws Exception {
        if (StringUtils.isEmpty(beanId)) {
            throw new Exception("beanID参数不能为空");
        }
        Object object = beans.get(beanId);
        return object;
    }
}

  

UserService:
public interface UserService {
    String getBeanName();
}

  

UserServiceImpl:
@SelfService
public class UserServiceImpl implements UserService {
    @SelfAutowired
    Bean bean;

    @Override
    public String getBeanName() {
        return bean.name;
    }

}

  

IocTest:
public class IocTest {
    public static void main(String[] args) throws Exception{
        SelfPathXmlApplicationContext context = new SelfPathXmlApplicationContext("com.example.ioc");
        UserService userService = (UserService) context.getBean("userServiceImpl");
        System.out.println(userService.getBeanName());
    }
}

  

IOC容器的简单实现

标签:substring   bsp   shm   exist   users   end   this   targe   element   

原文地址:https://www.cnblogs.com/ariczky/p/12838646.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!