简单分析一下spring为我们做了些什么

我就从用最简单的说法来说,不一定准确,spring为我们做了2件事:

  1. 省去了我们创建对象的操作
  2. 给我们声明的属性赋值

我们从最简单的bean的生成开始写起,我模仿的框架暂时未考虑支持xml配置的形式,全部采用注解的方式,实现主要功能。

好了我们开始进入正题,首先从bean的生产开始说起

首先先说spring是如何做的,相信用过spring的都知道下面这个标签,包扫描配置:

<context:component-scan base-package="com.bauer.java.activiti"/>

通过解析xml文件,首先找到(可能有的同学不知道这是如何找到的,可以留言,或者自行百度spring.handlers)

public class ContextNamespaceHandler extends NamespaceHandlerSupport {

	@Override
	public void init() {
		registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
		registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
		registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
		registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
		registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
		registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
		registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
		registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
	}

}

我们发现实际的component-scan的解析类是 ComponentScanBeanDefinitionParser 实际的扫描生成beandefination。

大致步骤:

  1. 分割路径
  2. 扫描代用@component注解的类(包括注解上包含的@componet,如@Controller类似的注解)
  3. 生成beandefination

值得注意的是spring的扫描采用的是asm技术扫描的,而非是加载类,然后通过Type信息去判断注解的,还有一个问题就是,只要包名一致spring也会去扫描jar包中的class。

华丽的风格线-----------------

模仿框架称之为autunm 

bean加载

autunm暂时没有实现xml配置文件的方式,所以项目的起点设置在了web.xml中如下图配置所示

    <context-param>
        <param-name>SCAN_PATH</param-name>
        <param-value>com.bauer.java.activiti</param-value>
    </context-param>

    <listener>
        <listener-class>com.bauer.framework.autumn.WebStartPoint</listener-class>
    </listener>

SCAN_PATH是包的扫描路径,接下来通过servletContext获取到路径,暂时还未支持多路径,首先获取到项目路径,然后通过项目路径获取到所有class的包路径,走后去扫描带@Bean注解的class

        if (beanFactory == null) {
            beanFactory = new AutowiredBeanFactory();
        }

        String pkgPath = servletContext.getInitParameter(SCAN_PATH_NAME);

        //扫描注解类生成
        String classPath = this.getClass().getResource("/").getPath();
        //获取所有class的路径
        List<String> listpath = PathUtils.getPkgPath(classPath, pkgPath);
        beanFactory.loadBeanDefination(Thread.currentThread().getContextClassLoader(), listpath);

注意,我采用的是通过类型信息判断类是否有@Bean注解具体的实现如下,

                Class loadClass = classLoader.loadClass(pkg);
                annotationPaser =  new AnnotationPaser(loadClass);
                if (annotationPaser.hasAnnotion(Bean.class.getName())) {
                    BeanDefination beanDefination = new BeanDefination();
                    beanDefination.setName(loadClass.getName());
                    beanDefination.setBeanClass(loadClass);
                    beanNames.add(loadClass.getName());
                    beanDefinationMap.put(beanDefination.getName(), beanDefination);
                }

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值