Sorry em, anh reply chậm. Để có thể inject ở dạng interface thì em phải lưu map cả lớp cài đặt lẫn interface với cái bean em ạ, ví dụ:
public interface Ruler {}
và lớp cài đặt là:
public interface RulerImpl implements Ruler {}
Thì code DI của em có thể thế này:
@Retention(RetentionPolicy.RUNTIME)
@interface Instant {}
@Retention(RetentionPolicy.RUNTIME)
@interface Inject {}
class BeanManagement {
public static void main(String[] args) throws Exception {
EzyReflection reflections = new EzyReflectionProxy(
"org.youngmonkeys.di"
);
Set<Class<?>> classes = reflections.getAnnotatedClasses(Instant.class);
Map<String, Object> beanByName = new HashMap<>();
Map<Class<?>, Object> beanByType = new HashMap<>();
for (Class<?> clazz : classes) {
Object bean = clazz
.getDeclaredConstructor()
.newInstance();
beanByName.put(EzyClasses.getVariableName(clazz), bean);
Class<?> parentClass = clazz;
while (parentClass != null) {
beanByType.put(parentClass, bean);
parentClass = parentClass.getSuperclass();
}
for (Class<?> inf : clazz.getInterfaces()) {
beanByType.put(inf, bean);
}
injectDependenciesToBean(beanByName, beanByType, bean);
}
}
public static void injectDependenciesToBean(
Map<String, Object> beanByName,
Map<Class<?>, Object> beanByType,
Object bean
) throws Exception {
Field[] fields = bean.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Inject.class)) {
// lấy phụ thuộc từ name trước, nếu không có thì lấy theo type
Object dependency = beanByName.get(
EzyClasses.getVariableName(field.getType())
);
if (dependency == null) {
Class<?> parentClass = field.getType();
while (parentClass != null && dependency == null) {
dependency = beanByType.get(
parentClass
);
parentClass = parentClass.getSuperclass();
}
for (Class<?> inf : field.getType().getInterfaces()) {
dependency = beanByType.get(
inf
);
if (dependency != null) {
break;
}
}
}
field.setAccessible(true);
field.set(bean, dependency);
}
}
}
}
Theo cách này thì việc lấy ra bean nào sẽ phụ thuộc vào tên bean trước, sau đó đến type. Nếu giả sử có nhiều lớp cài đặt 1 interface thì có lẽ em nên đặt tên cho khớp để lấy ra được bean phù hợp em ạ.
Dạ vâng em cảm ơn anh, anh có thể nói thêm giúp em cái đoạn này nó hoạt động như nào không ạ.
EzyReflection reflections = new EzyReflectionProxy(
"org.youngmonkeys.di"
)
–
TungDP
1709242254000