https://www.iteye.com/blog/zxf-noimp-1071765
1. 注解定义
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface ResourceManager {
String name() default "";
}
2. 装配解析
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
public class ClassPathXMLApplicationContext {
Logger logger = LoggerFactory.getLogger(ClassPathXMLApplicationContext.class);
List<BeanDefine> beanDefines = new ArrayList<>();
Map<String, Object> singletons = new HashMap<>();
public ClassPathXMLApplicationContext(String filePath) {
// 读取配置文件中管理的bean
readXML(filePath);
// 实例化bean
instanceBean();
// 注解处理
annotationInject();
}
// 读取配置文件中管理的bean
public void readXML(String filePath) {
Document document = null;
SAXReader saxReader = new SAXReader();
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
try {
document = saxReader.read(contextClassLoader.getResourceAsStream(filePath));
Element beans = document.getRootElement();
for (Iterator<Element> beansList = beans.elementIterator(); beansList.hasNext();) {
Element next = beansList.next();
BeanDefine bean = new BeanDefine(next.attributeValue("id"), next.attributeValue("class"));
beanDefines.add(bean);
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
// 实例化bean
public void instanceBean() {
for (BeanDefine bean: beanDefines) {
try {
singletons.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
/**
* 注解处理器
* 如果 @ResourceManager 注解配置了name属性,则根据name所指定的名称获取要注入的实例引用
* 如果 @ResourceManager 注解没有配置name属性, 则根据属性所属类型来扫描配置文件获取要注入的实例引用
*/
public void annotationInject() {
for (String beanName: singletons.keySet()) {
Object bean = singletons.get(beanName);
if (null != bean) {
methodAnnotation(bean);
fieldAnnotation(bean);
}
}
}
/**
* 处理在set方法加入的注解
*/
public void methodAnnotation(Object bean) {
try {
// 获取属性描述
PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for (PropertyDescriptor descriptor: propertyDescriptors) {
Method method = descriptor.getWriteMethod();
// 判断set方法是否定义了注解
if (null != method && method.isAnnotationPresent(ResourceManager.class)) {
ResourceManager manager = method.getAnnotation(ResourceManager.class);
Object value = null;
if (StringUtils.isEmpty(manager.name())) {
for (String key: singletons.keySet()) {
if (descriptor.getPropertyType().isAssignableFrom(singletons.get(key).getClass())) {
value = singletons.get(key);
break;
}
}
} else {
String name = manager.name();
value = singletons.get(name);
}
method.setAccessible(true);
method.invoke(bean, value);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 处理在field上的注解
*/
public void fieldAnnotation(Object bean) {
Field[] fields = bean.getClass().getFields();
for (Field field: fields) {
try {
if (field.isAnnotationPresent(ResourceManager.class)) {
ResourceManager annotation = field.getAnnotation(ResourceManager.class);
Object value = null;
if (StringUtils.isEmpty(annotation.name())) {
for (String key: singletons.keySet()) {
if (field.getType().isAssignableFrom(singletons.get(key).getClass())) {
value = singletons.get(key);
break;
}
}
} else {
value = singletons.get(annotation.name());
}
field.setAccessible(true);
field.set(bean, value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public Object getBean(String id) {
return singletons.get(id);
}
public static void main(String[] args) {
test();
}
public static void test() {
String filePath = "configureAnnotation.xml";
ClassPathXMLApplicationContext context = new ClassPathXMLApplicationContext(filePath);
UserServiceImpl userService = (UserServiceImpl) context.getBean("userService");
userService.show();
}
}
3. xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id = "userDao" class="cn.lhcz.project.spring.annotation.UserDaoImpl" />
<bean id = "userService" class = "cn.lhcz.project.spring.annotation.UserServiceImpl" />
</beans>
4. BeanDefine
public class BeanDefine {
private String id;
private String className;
public BeanDefine() {
}
public BeanDefine(String id, String className) {
this.id = id;
this.className = className;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}
5. 其他
UserDaoImpl
public class UserDaoImpl {
public void show() {
System.out.println("this is dao method...");
}
}
UserServiceImpl
public class UserServiceImpl {
private UserDaoImpl userDao;
@ResourceManager(name = "userDao")
public void setUserDao(UserDaoImpl userDao) {
this.userDao = userDao;
}
public void show() {
userDao.show();
System.out.println("this is service method...");
}
}