本文提供了一個簡單的依賴注入解析方法,參考了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();
}
}