《2020/04/15》spring中bean的注入简单实现

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...");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值