• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Java > Spring boot实现一个简单的ioc(2)

Spring boot实现一个简单的ioc(2)

作者:clayanddev 字体:[增加 减小] 来源:互联网 时间:2017-05-28

clayanddev 通过本文主要向大家介绍了spring ioc实现原理,spring ioc实现,spring ioc实现方式,spring如何实现ioc,spring ioc原理等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

前言

跳过废话,直接看正文
仿照spring-boot的项目结构以及部分注解,写一个简单的ioc容器。
测试代码完成后,便正式开始这个ioc容器的开发工作。

正文

项目结构

实际上三四个类完全能搞定这个简单的ioc容器,但是出于可扩展性的考虑,还是写了不少的类。
因篇幅限制,接下来只将几个最重要的类的代码贴出来并加以说明,完整的代码请直接参考https://github.com/clayandgithub/simple-ioc。

SimpleAutowired

代码

import java.lang.annotation.*;

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SimpleAutowired {
 boolean required() default true;

 String value() default ""; // this field is moved from @Qualifier to here for simplicity
}

</div>

说明

@SimpleAutowired的作用是用于注解需要自动装配的字段。
此类和spring的@Autowired的作用类似。但又有以下两个区别:
- @SimpleAutowired只能作用于类字段,而不能作用于方法(这样实现起来相对简单些,不会用到aop)
- @SimpleAutowired中包括了required(是否一定需要装配)和value(要装配的bean的名字)两个字段,实际上是将spring中的@Autowired以及Qualifier的功能简单地融合到了一起

SimpleBean

代码

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SimpleBean {
 String value() default "";
}

</div>

说明

@SimpleBean作用于方法,根据方法返回值来生成一个bean,对应spring中的@Bean
用value来设置要生成的bean的名字

SimpleComponent

代码

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SimpleBean {
 String value() default "";
}

</div>

说明

@SimpleComponent作用于类,ioc容器会为每一个拥有@SimpleComponent的类生成一个bean,对应spring中的@Component。特殊说明,为了简单起见,@SimpleComponent注解的类必须拥有一个无参构造函数,否则无法生成该类的实例,这个在之后的SimpleAppliationContext中的processSingleClass方法中会有说明。

SimpleIocBootApplication

代码

import java.lang.annotation.*;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SimpleIocBootApplication {
 String[] basePackages() default {};
}

</div>

说明

@SimpleIocBootApplication作用于应用的入口类。
这个启动模式是照搬了spring-boot的启动模式,将启动任务委托给SimpleIocApplication来完成。ioc容器将根据注解@SimpleIocBootApplication的相关配置自动扫描相应的package,生成beans并完成自动装配。(如果没有配置,默认扫描入口类(测试程序中的SampleApplication)所在的package及其子package)

以上就是这个ioc容器所提供的所有注解,接下来讲解ioc容器的扫描和装配过程的实现。

SimpleIocApplication

代码

import com.clayoverwind.simpleioc.context.*;
import com.clayoverwind.simpleioc.util.LogUtil;

import java.util.Arrays;
import java.util.Map;
import java.util.logging.Logger;


public class SimpleIocApplication {
 private Class<?> applicationEntryClass;

 private ApplicationContext applicationContext;

 private final Logger LOGGER = LogUtil.getLogger(this.getClass());

 public SimpleIocApplication(Class<?> applicationEntryClass) {
 this.applicationEntryClass = applicationEntryClass;
 }

 public static void run(Class<?> applicationEntryClass, String[] args) {
 new SimpleIocApplication(applicationEntryClass).run(args);
 }

 public void run(String[] args) {
 LOGGER.info("start running......");

 // create application context and application initializer
 applicationContext = createSimpleApplicationContext();
 ApplicationContextInitializer initializer = createSimpleApplicationContextInitializer(applicationEntryClass);

 // initialize the application context (this is where we create beans)
 initializer.initialize(applicationContext); // here maybe exist a hidden cast

 // process those special beans
 processSpecialBeans(args);

 LOGGER.info("over!");
 }

 private SimpleApplicationContextInitializer createSimpleApplicationContextInitializer(Class<?> entryClass) {
 // get base packages
 SimpleIocBootApplication annotation = entryClass.getDeclaredAnnotation(SimpleIocBootApplication.class);
 String[] basePackages = annotation.basePackages();
 if (basePackages.length == 0) {
  basePackages = new String[]{entryClass.getPackage().getName()};
 }

 // create context initializer with base packages
 return new SimpleApplicationContextInitializer(Arrays.asList(basePackages));
 }

 private SimpleApplicationContext createSimpleApplicationContext() {
 return new SimpleApplicationContext();
 }

 private void processSpecialBeans(String[] args) {
 callRegisteredRunners(args);
 }

 private void callRegisteredRunners(String[] args) {
 Map<String, SimpleIocApplicationRunner> applicationRunners = applicationContext.getBeansOfType(SimpleIocApplicationRunner.class);
 try {
  for (SimpleIocApplicationRunner applicationRunner : applicationRunners.values()) {
  applicationRunner.run(args);
  }
 } catch (Exception e) {
  throw new RuntimeException(e);
 }
 }
}

</div>

说明

前面说到应用的启动会委托SimpleIocApplication来完成,通过将应用入口类(测试程序中的SampleApplication)传入SimpleIocApplication的构造函数,构造出SimpleIocApplication的一个实例并运行run方法。在run方法中,会首先生成一个applicationContext,并调用SimpleApplicationContextInitializer来完成applicationContext的初始化(bean的扫描、装配)。然后调用processSpecialBeans来处理一些特殊的bean,如实现了SimpleIocApplicationRunner接口的bean会调用run方法来完成一些应用程序的启动任务。
这就是这个ioc容器的整个流程。

SimpleApplicationContextInitializer

代码

import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class SimpleApplicationContextInitializer implements ApplicationContextInitializer<SimpleApplicationContext> {

  private Set<String> basePackages = new LinkedHashSet<>();

  public SimpleApplicationContextInitializer(List<String> basePackages) {
    this.basePackages.addAll(basePackages);
  }

  @Override
  public void initialize(SimpleApplicationContext applicationContext) {
    try {
      applicationContext.scan(basePackages, true);
    } catch (ClassNotFoundException e) {
      throw new RuntimeException(e);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
    applicationContext.setStartupDate(System.currentTimeMillis());
  }
}

</div>

说明

在SimpleIocApplication的run中,会根据basePackages来构造一个SimpleApplicationContextInitializer 的实例,进而通过这个ApplicationContextInitializer来完成SimpleApplicationContext 的初始化。
在SimpleApplicationContextInitializer中, 简单地调用SimpleApplicationContext 中的scan即可完成SimpleApplicationContext的初始化任务

SimpleApplicationContext

说明:

终于到了最重要的部分了,在SimpleApplicationContext中将真正完成扫描、生成bean以及自动装配的任务。这里scan即为SimpleApplicationContext的程序入口,由SimpleApplicationConte

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Spring boot实现一个简单的ioc(2)
  • Spring boot实现一个简单的ioc(1)
  • spring+html5实现安全传输随机数字密码键盘
  • Spring boot实现一个简单的ioc(2)
  • Spring boot实现一个简单的ioc(1)
  • spring+html5实现安全传输随机数字密码键盘

相关文章

  • 2017-05-28Spring Data JPA 简单查询--方法定义规则(详解)
  • 2017-05-28Java导出oracle表结构实例详解
  • 2017-05-28详解Spring Boot 定时任务的实现方法
  • 2017-05-28java、freemarker保留两位小数
  • 2017-05-28java 基础之JavaBean属性命名规范问题
  • 2017-05-28Spring+SpringMVC+MyBatis深入学习及搭建(三)之MyBatis全局配置文件解析
  • 2017-05-28Struts2 控制文件上传下载功能实例代码
  • 2017-05-28SpringMVC解析JSON请求数据问题解析
  • 2017-05-28javaweb判断当前请求是否为移动设备访问的方法
  • 2017-05-28Spring配置多个数据源并实现动态切换示例

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 详解如何用spring Restdocs创建API文档
    • Java 多线程优先级实例详解
    • 10个Java程序员熟悉的面向对象设计原则
    • spring boot装载自定义yml文件
    • Java中的几种读取properties配置文件的方式
    • 详解用Kotlin写一个基于Spring Boot的RESTful服务
    • Java线程同步、同步方法实例详解
    • 详解Java动态加载数据库驱动
    • 详解java枚举用法及实例
    • Java使用字节流复制文件的方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有