本文提供了一个简单的依赖注入解析方法,参考了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();
}
}