天天看點

Java簡單依賴注入解析類

    本文提供了一個簡單的依賴注入解析方法,參考了Spring的依賴注入功能。

1、注解類定義

/**
 * Bean注解,用于定義Bean,注解在類上
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
@Inherited
public @interface Bean {

	/**
	 * Bean Name
	 * @return
	 */
	public String name() default "";

}
           
/**
 * Resource注解,用于注解需要注入資源的變量
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
@Inherited
public @interface Resource {

	/**
	 * Bean Name
	 * @return
	 */
	public String value() default "";

}
           

2、解析類

public class SimpleAnnotation {

	// 存儲掃描到的使用Bean注解的類Class
	private static final Map<String, Class<Object>> beanClasses = new HashMap<String, Class<Object>>();

	private SimpleAnnotation() {
	}
	
	/**
	 * 掃描pakageNames包裡添加了Bean注解的類
	 * @param pakageNames 包名全路徑,可以有多個,多個的話用英文半形逗號","分隔
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void scanBeans(String pakageNames) {
		SimpleAnnotation.beanClasses.clear();

		List<Class> classes = null;
		String[] pakageNameArray = pakageNames.split(",");
		for (String packageName : pakageNameArray) {
			if (packageName != null && !"".equals(packageName.trim())) {
				classes = ClassUtils.getPackageClasses(packageName.trim());
				if (classes != null) {
					for (Class clazz : classes) {
						// 掃描Bean注解的class
						if (clazz.isAnnotationPresent(Bean.class)) {
							Bean beanAnno = (Bean) clazz.getAnnotation(Bean.class);
							SimpleAnnotation.beanClasses.put(beanAnno.name(), clazz);
						}
					}
				} else {
					LoggerUtils.info("掃描[packageName: " + packageName + "]出錯!");
				}
			}
		}

	}

	/**
	 * 依賴注入<br>
	 * 将obj裡添加了Resource注解的字段注入Resource value值對應的Bean對象,Resouce value值等于Bean name值
	 * @param obj
	 */
	public static <T> void dependencyInject(T obj) {
		Class<T> clazz = (Class<T>) obj.getClass();

		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			Resource annotation = field.getAnnotation(Resource.class);
			if (annotation != null) {
				try {
					field.setAccessible(true);
					field.set(obj, getBeanInstance(annotation.value()));
				} catch (Exception e) {
					LoggerUtils.recordInfoAndDebugMessage(e, "注入對象出錯[Resource: " + annotation.value() + "]");
				}
			}
		}
	}

	/**
	 * 擷取添加了Bean注解的類class
	 * @param name Bean注解的name屬性
	 * @return
	 */
	public static Class<Object> getBeanClass(String name) {
		return SimpleAnnotation.beanClasses.get(name);
	}

	/**
	 * 擷取添加了Bean注解的類class的執行個體,多例
	 * @param name Bean注解的name屬性
	 * @return
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public static <T> T getBeanInstance(String name) throws InstantiationException, IllegalAccessException {
		Class clazz = SimpleAnnotation.beanClasses.get(name);
		return clazz == null ? null : (T) clazz.newInstance();
	}

}