19 Star 36 Fork 12

wkgcass / Pure.IoC

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

click here(git@osc) to get English tutorial.

#Pure.IoC Pure.IoC是一个轻量级基于类和注解的自动依赖注入框架。

使用jdk 1.8
推荐与Spring配合使用

<dependency>
  <groupId>net.cassite</groupId>
  <artifactId>pure.ioc</artifactId>
  <version>0.3.2</version>
</dependency>

##框架思想 以已有的逻辑关系代替复杂的配置

##主要功能

  • IOC
  • AOP

##设计思路 通常写java时会使用Spring框架进行IoC管理。而Spring是基于bean的,配置起来首先需要将类映射到bean,然后描述bean的依赖关系。

事实上,很多时候依赖关系仅仅需要类型即可确定。比如说

class A{
	...
	public void setB(B b){ this.b=b; }
}

class B{
}

很显然,A依赖于B,A需要将一个B的实例通过setB注入进来。这应当是很自然的逻辑关系。

类型依赖在编码时就会设定好,所以,如果有工具能帮助完成这类“显而易见”的依赖该多好。于是我开发了Pure.IoC

#框架的框架 ##扩展性 设计Pure.IoC时经历了不少思考。考虑下面这样的“复杂”情况(其实已经算不复杂了)

@Singleton
@Wire
class Complex{
	private ......
	
	public Complex(){ ... }
	@Default public Complex(AnotherClass obj){ ... }
	
	public void setA(A a){ ... }
	public void setB(B b){ ... }	
	public void setInterface(Interf1 interf){ ... }
	public void setInterface(@Use(clazz=Impl2.class)Interf2 interf){ ... }
}

@Default(clazz=Impl1.class) interface Interf1{ ... }

上述注解描述了:

  • @ Singleton Complex是一个单例
  • @ Wire 在通过AutoWire构建时需要注入
  • @ Default 指定默认的构造器(构造函数上),指定默认的实现类(接口上)
  • @ Use 指定使用的类

注解应当可以无限的附加,也不能增加系统复杂性。
所以,最终使用这种设计:

AnnotationHandler + HandlerChain

AnnotationHandler分为三种,

  • ParamAnnotationHandler 负责根据类型获取实例
  • ConstructorFilter 负责选择构造器,考虑构造器上的注解
  • TypeAnnotationHandler 负责选取要构造的类型,考虑类型上的注解

Handler被注册到IOCController上,根据注册的顺序进行handling操作。handler的内部实现有点像AOP,一般来说会调用chain.next().handle(...) ,然后根据返回值或者异常进行一些逻辑判断。详情见各Handler接口的handle方法文档

所以,可以非常方便的进行注解的扩展。

##循环依赖 循环依赖虽然不很常见,但没准会遇到。A->B->C->A
从逻辑上,A,B,C中必须有一个是单例,否则对象的创建将无限循环下去。

另外: Spring要求构造器不能循环依赖,否则无法完成构建。

不过Pure.IoC巧妙的解决了循环依赖的问题。

  • 所有注入在构造时进行。只有注入完成,构造才会完成。
  • 对于单例,在构造实际进行前把自己的引用交给IOCController,指示单例已经存在
  • 由于只有注入完成才构造完成,所以不必担心获取到一个构造一半的对象。

所以,即使是构造器中包含循环依赖,也能顺利的进行(本质上所有依赖都是构造器依赖)。

##适用性 Pure.IoC由于设计为构造时注入,所以不需要任何额外组建即可放入框架中使用。也可配合Spring使用。甚至可以一部分setter通过本框架注入,一部分通过Spring注入。

直接与Struts2等相接也可以。由于注入过程完全在类内部,所以并不需要像Spring一样配置接管Struts2的对象工厂,而是直接就可使用(一个对象本身就是注入“工厂”)。

推荐的使用方法是

extends AutoWire

但是有些情况下必须继承别的类,那么有两种解决办法:

@Wire class A { ... }

@Wire注解标注的类在任何经过Pure.IoC的情况下都会进行注入操作。
在单独获取时可使用

AutoWire.get(A.class)

获取实例

class A {
	public A(){
		AutoWire.wire(this);
	}
}

构造时将自己的引用交给框架进行注入。

实际上所有入口最终都调用AutoWire.wire(Object)

#如何使用?

  • 首先使用上述三种方法任何一种进行框架接入。

  • 接着在程序入口直接调用

      IOCController.autoRegister();

    或者手动register各Handler,比如

      register(new DefaultConstructorFilter());

    如果是JavaEE,则可以写一个Listener完成这种操作

  • 最后使用

      IOCController.closeRegistering();

    关闭handler的注册。(这一步可选,仅仅为了保证存储handler的list不会被修改)

没有注册Handler却已开始装配,将先行调用autoRegistercloseRegistering

##默认行为 没有任何注解参与时的默认行为是:

注入setter时,获取参数类型并向IOCController请求实例,获取实例后进行setter的invoke。

在获取实例时,取得唯一一个构造器,或者取得无参数的构造器。
如果构造器有参数,则取得参数类型对应实例。
最后进行构造

##扩展注解 ###Type

  • Wire 指示该类需要注入
  • Singleton
    指示该类为单例
  • Default(clazz)
    一般用于interface或者abstract class
    在Type检查时若遇到该注解则会转而构造该注解指定的类型

###Constructor

  • Default()
    在可能产生歧义时指定构造时默认使用的构造函数

###Param

  • Use(clazz, constant, variable)
    clazz代表使用指定的类型作注入 接下来会对指定的类型进行Type检查。
    value代表在scope中注册的值
  • Force(value)
    将String类型的value转化为对应的类型。Force只支持基本类型和String
  • Extend(handler, args)
    表示从其他对象工厂获取对象
    handler ExtendingHandler,指定一个handler,描述如何从其他对象工厂获取对象
    args 用于放入handler的参数
  • Session(value)
    表示该Setter的参数值将在同一个Session中共享
    value 共享的别名
  • Ignore
    忽略该参数,仅在Setter上使用,即忽略该setter

此外,进行Param处理时还提供自动的基本类型注入。
若没有找到可用的注入,则将检查基本类型和数组类型,并初始化为默认初始值(0,false,array[length=0])

#其他 ##Session Session存在于一次从装配操作开始到完成的所有中间操作之中.几乎每个方法传递参数时都会将Session作为参数传递.
例如:
A依赖于B,B依赖于C和D.其中,A和C继承于AutoWire(隐式调用了AutoWire.wire(o)),而B和D均使用Wire注解.
那么,ABD的装配工作共享一个Session,C的装配工作属于另一个Session

##Utils 提供了一个Utils类,包含了一些常见操作,以及IOCController中protected的方法。如果不方便继承IOCController,你还可以使用Utils中提供的方法来调用那些protected的方法。

##ExtendingHandler 设计初衷是用于简化从其他对象工厂获取实例的工作。但也不限于此。
其实可以理解为扩展的简化
它用于同时完成Type,Setter和Param的Handling工作,只不过接受的参数只能是字符串数组。

###ScopeAware 实现ScopeAware接口并标记@Wire,那么将会以当前Scope为参数调用其方法.实际上,直接书写setScope(Scope s)也可以完成注入

#AOP 从版本0.1.1开始新增AOP功能

在带接口的类上设置

@AOP({Weaver.class,...})

即可获取AOP支持。

当该类被Pure.IoC注入时,或者直接使用

AOPController.weave(()->该类实例,该类.class)

即可注入/获取代理对象。

##使用 ###创建你的Weaver

class YourWeaver implements Weaver{
	@Override
	protected void doBefore(AOPPoint point) {
		...
	}

	@Override
	protected void doAfter(AOPPoint point) {
		...
	}

	@Override
	protected void doException(AOPPoint point) throws Throwable {
		...
	}
}

before, after, exception分别对应Before, AfterReturn, AfterThrowing类型。此处实际上也是Around型。

还提供了BeforeWeaver, AfterWeaver, ExceptionWeaver。
如果你只需要特定的cut point类型,你可以继承这些类。

如果需要使用Introduction型,也非常方便,只需要让你的Weaver实现需要的接口即可,无需其他任何操作

###织入 使用

@AOP({Weaver1.class, Weaver2.class, ...})

来织入
如果要使用cglib,则可以强制useCglib=true

@AOP(value={Weaver1.class, Weaver2.class, ...} useCglib=true)	

AOP过程遵循如下步骤

  • 通过AutoWire.get(Class)获取各Weaver实例
  • 设置一个变量来存储当前的Weaver数组的下标
  • 从第一个到最后一个Weaver,依次进行'before'
  • --如果设置了returnValue,直接跳到'after'步骤
  • 执行方法
  • --如果遇到了异常, 从最后一个到第一个进行'exception'
  • 从存储的下标到第一个,依次进行'after'

###AOPPoint 该类包含如下公共字段/方法

  • target 目标对象
  • method 当前方法
  • args 输入参数(可直接修改)
  • returnValue() 获取返回值
  • returnValue(Object) 设置返回值
  • exception() 获取当前异常
  • exceptionHandled() 异常已处理

###TargetAware 在Weaver中实现TargetAware接口,那么在获取该Weaver实例后将会以被代理对象为参数调用其方法.

The MIT License (MIT) Copyright (c) 2015 wkgcass Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

轻量级基于类型和注解的依赖注入框架 展开 收起
Java
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/wkgcass/Pure.IoC.git
git@gitee.com:wkgcass/Pure.IoC.git
wkgcass
Pure.IoC
Pure.IoC
master

搜索帮助

14c37bed 8189591 565d56ea 8189591