IOC的一种简易实现(二)

上一篇在这儿:

http://blog.csdn.net/wkgcass/article/details/43954249

大致说了一些基础功能。这篇来看看它全部的功能


1.全自动

如果注入没有歧义,没有特别的需求,只是要完成注入,则只要extends AutoWire,或者对类定义处进行@Wire注解标明,即可完成注入

不过对于@Wire注解标注的类,直接使用new来实例化是不能自动注入的,但是继承AutoWire的类可以随意实例化,若在实例化过程中“遇到”@Wire注解的类,就会对@Wire标注的类进行自动注入。

如果有歧义或者额外的需求(比如不希望某个setter被执行,或者强制让值为某个bean),比如setter是以接口方式定义的,就需要注解的帮忙了。


2.注解:

在框架使用中,通过注解进行配置是非常方便的,可以减少很多的xml语句。

所以,为了尽可能简单,必须指定配置的地方都使用注解完成。

默认提供这些注解:


@Target(ElementType.TYPE)
public @interface Bean {
	public String[] name();  //bean的名称,以String数组形式存放多个名称
	public boolean isSingleton() default true;  //是否为单例
}

@Target({ElementType.TYPE, ElementType.CONSTRUCTOR})
public @interface Default {
	public Class<?> clazz() default Default.class;  //遇到时默认使用哪个类(在constructor上标注时这个字段不会考虑)
	public String bean() default "";  //遇到时默认使用哪个bean(在constructor上标注时这个字段不会考虑)
}

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
public @interface Force {
	public String[] value();  //强制使用某个值
	public String[] in() default "";  //指定在哪个bean中使用
}

@Target( {ElementType.FIELD, ElementType.METHOD})
public @interface Ignore {  //忽略某个setter
}

@Target(ElementType.TYPE)
public @interface IsSingleton {  //指定该类为单例(只允许被实例化一次)
}

@Target( { ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
public @interface Use {  
	public Class<?>[] clazz() default Use.class;  //指定使用哪个类

	public String[] bean() default "";  //指定使用哪个bean

	public String[] in() default "";  //指定在哪个bean中使用上述参数
}

@Target(ElementType.TYPE)
public @interface Wire {  //在装配过程中如果遇到则进行自动装配
}

从上述代码,以及注释中可以了解每个Annotation的功能以及用在何处(@Target注解标明了位置)。

所以用法也显而易见了~~稍稍举一反三一下就好。


3.自定注解 / 注解解释

一个没有扩展性的程序不是好程序

                                                            ——wkgcass

开个玩笑= =

扩展性对程序是极其重要的。这里最大的可扩展点就是注解。所以注解必须可扩展

那么如何扩展呢?看如下4个接口:

public interface ConstructorFilter {
	boolean canHandle(Set<Annotation> annotations);

	Constructor<?> handle(Constructor<?>[] cons, ConstructorFilterChain chain) throws AnnotationHandlingException;
	
	double priority();
}


public interface ParamAnnotationHandler {
	boolean canHandle(Annotation[] annotations);

	Object handle(Member caller, Class<?> cls,Annotation[] toHandle, ParamHandlerChain chain) throws AnnotationHandlingException;
	
	double priority();
}


public interface SetterAnnotationHandler {
	boolean canHandle(Set<Annotation> annotations);

	boolean handle(Object target, Method setter, Set<Annotation> toHandle, SetterHandlerChain chain) throws AnnotationHandlingException;
	
	double priority();
}


public interface TypeAnnotationHandler {
	boolean canHandle(Annotation[] annotations);

	Object handle(Class<?> cls, TypeHandlerChain chain) throws AnnotationHandlingException;
	
	double priority();
}

从上到下依次为:

Constructor过滤器,用于选取特定的构造器,返回选取后的过滤器,选取失败返回null

参数注解处理,返回生成/取出的参数,失败则抛出异常

Setter注解处理,用于执行(invoke)指定的setter,执行成功返回true,失败返回false

类型注解处理,用于对类型进行操作,比如@Default注解,就需要这类接口实现一个handler去选取指定的类。


大家还能发现,每个接口的handle方法都有一个chain参数,它是这儿编程思想的主体之一

其中priority作用是区分先后。数值越低,则在chain中排得越早。注意:如果priority相同,那么相同数值的所有同类型handler只有一个会执行。



一个例子代码:

/**
 * Priority 0.0
 * <br/>
 * Default implementation of ParamAnnotationHandler
 * <br/> simply return the corresponding value of given parameter type.
 * @author wkgcass
 *
 */
public class DefaultParamHandler extends IOCController implements
		ParamAnnotationHandler {
//本工具默认的参数handler

        @Override
	public boolean canHandle(Annotation[] annotations) {
		return true;  //不管什么类型都能处理
	}

	@Override
	public Object handle(Member caller, Class<?> cls, Annotation[] toHandle,
			ParamHandlerChain chain) throws AnnotationHandlingException {
		if(AutoWire.DEBUG_MODE){  //一个syso,debug时候用来看执行过程,这儿不用管它
		System.out.println(this.getClass().getSimpleName()+"    "+cls);
		}
		try{
			return chain.next().handle(caller, cls, toHandle, chain);  //先执行chain的下一个handler,
                                                                                   //如果失败再接着走,成功则返回
		}catch(AnnotationHandlingException e){}
		if(AutoWire.DEBUG_MODE){  //一个syso,不用管它
		System.out.println(this.getClass().getSimpleName()+"    start");
		}
		return get(cls);  //返回获取的值,这儿get是IOCController中的一个用来方便handlers操作的方法,具体功能见下一篇。
	}

	@Override
	public double priority() {
		return 0.0;
	}

}


并且在IOCController中注册(调用static的register方法)即可

以类似的方式,可以完成更多自定义注解操作!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值