• Spring(八)编码剖析@Resource注解的实现原理


    配置文件beans2.xml

    <?xml version="1.0" encoding="UTF-8"?

    > <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <!-- 把针对注解的容器注射到Spring容器中 --> <context:annotation-config /> <bean id="personDaoxx" class="test.spring.dao.impl.PersonDaoBean" /> <!-- <bean id="personService" class="test.spring.service.impl.PersonServiceBean4"></bean> --> <bean id="personService" class="test.spring.service.impl.PersonServiceBean3"></bean> </beans>

    package test.spring.dao;
    
    public interface PersonDao {
    
        public abstract void add();
    
    }
    package test.spring.dao.impl;
    
    import test.spring.dao.PersonDao;
    
    
    public class PersonDaoBean implements PersonDao {
    
        @Override
        public void add(){
            System.out.println("执行PersonDaoBean里的test1()方法");
        }
    }
    
    package test.spring.service;
    
    public interface PersonService2 {
    
        public abstract void save();
    }
    package test.spring.service.impl;
    
    import test.spring.dao.PersonDao;
    import test.spring.jnit.AnnotationTest;
    import test.spring.service.PersonService2;
    
    public class PersonServiceBean3 implements PersonService2 {
    
        private PersonDao personDao;
        private String name;
    
        public PersonServiceBean3() {
    
        }
    
        public PersonServiceBean3(PersonDao personDao, String name) {
            this.personDao = personDao;
            this.name = name;
        }
    
        public PersonDao getPersonDao() {
            return personDao;
        }
    
        @AnnotationTest
        public void setPersonDao(PersonDao personDao) {
            this.personDao = personDao;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public void save() {
            // TODO Auto-generated method stub
            personDao.add();
            // System.out.println(name);
        }
    }
    
    package test.spring.jnit;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    import org.dom4j.Element;
    
    //选择在执行期
    @Retention(RetentionPolicy.RUNTIME)
    // 指定注解仅仅能用在字段和方法上
    @Target({ ElementType.FIELD, ElementType.METHOD })
    public @interface AnnotationTest {
    
        public String name() default "";
    }
    
    package test.spring.jnit;
    
    import java.beans.IntrospectionException;
    import java.beans.Introspector;
    import java.beans.PropertyDescriptor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.commons.beanutils.ConvertUtils;
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.XPath;
    import org.dom4j.io.SAXReader;
    
    import test.spring.entity.Bean2;
    import test.spring.entity.Property;
    
    public class AnnotationInjectTest {
    
        private List<Bean2> beanDefines = new ArrayList<Bean2>();
        private Map<String, Object> singletons = new HashMap<String, Object>();
    
        public AnnotationInjectTest(String filename) {
            this.readXML(filename);
            this.instanceBeans();
            this.injectObject();
            this.annotationInject();
        }
    
        private void annotationInject() {
            // TODO Auto-generated method stub
            for (String beanName : singletons.keySet()) {
                Object bean = singletons.get(beanName);
                if (bean != null) {
                    try {
                        PropertyDescriptor[] pDescriptors = Introspector
                                .getBeanInfo(bean.getClass())
                                .getPropertyDescriptors();
                        for (PropertyDescriptor propertyDescriptor : pDescriptors) {
                            Method setter = propertyDescriptor
                                    .getWriteMethod();
                            if (setter != null
                                    && setter
                                            .isAnnotationPresent(AnnotationTest.class)) {
                                AnnotationTest aTest = setter
                                        .getAnnotation(AnnotationTest.class);
                                Object value = null;
                                if (aTest.name() != null
                                        && !"".equals(aTest.name())) {
                                    value = singletons.get(aTest.name());
                                    setter.setAccessible(true);
                                    try {
                                        setter.invoke(bean, value);
                                    } catch (Exception e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                    }
                                } else {
                                    value = singletons.get(propertyDescriptor
                                            .getName());
                                    if (value == null) {
                                        for (String key : singletons.keySet()) {
                                            if (propertyDescriptor
                                                    .getPropertyType()
                                                    .isAssignableFrom(
                                                            singletons.get(key)
                                                                    .getClass())) {
                                                value = singletons.get(key);
                                                break;
                                            }
                                        }
                                    }
                                }
                                setter.setAccessible(true);
                                try {
                                    setter.invoke(bean, value);
                                } catch (Exception e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                            }
                        }
                        Field[] fields = bean.getClass().getDeclaredFields();
                        for (Field field : fields) {
                            if (field.isAnnotationPresent(AnnotationTest.class)) {
                                AnnotationTest aTest = field
                                        .getAnnotation(AnnotationTest.class);
                                Object value = null;
                                if (aTest.name() != null
                                        && !"".equals(aTest.name())) {
                                    value = singletons.get(aTest.name());
    
                                } else {
                                    value = singletons.get(field.getName());
                                    if (value == null) {
                                        for (String key : singletons.keySet()) {
                                            if (field.getType().isAssignableFrom(
                                                    singletons.get(key).getClass())) {
                                                value = singletons.get(key);
                                                break;
                                            }
                                        }
                                    }
                                }
                                field.setAccessible(true);
                                try {
                                    field.set(bean, value);
                                } catch (IllegalArgumentException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                } catch (IllegalAccessException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                            }
                        }
                    } catch (IntrospectionException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        /**
         * 为bean对象的属性注入值
         */
        private void injectObject() {
            for (Bean2 beanDefinition : beanDefines) {
                Object bean = singletons.get(beanDefinition.getId());
                if (bean != null) {
                    try {
                        PropertyDescriptor[] ps = Introspector.getBeanInfo(
                                bean.getClass()).getPropertyDescriptors();
                        for (Property propertyDefinition : beanDefinition
                                .getProperties()) {
                            for (PropertyDescriptor properdesc : ps) {
                                if (propertyDefinition.getName().equals(
                                        properdesc.getName())) {
                                    java.lang.reflect.Method setter = properdesc
                                            .getWriteMethod();// 获取属性的setter方法
                                                                // ,private
                                    if (setter != null) {
                                        Object value = null;
                                        if (propertyDefinition.getRef() != null
                                                && !"".equals(propertyDefinition
                                                        .getRef().trim())) {
                                            value = singletons
                                                    .get(propertyDefinition
                                                            .getRef());
                                        } else {
                                            value = ConvertUtils.convert(
                                                    propertyDefinition.getValue(),
                                                    properdesc.getPropertyType());
                                        }
                                        setter.setAccessible(true);
                                        setter.invoke(bean, value);// 把引用对象注入到属性
                                    }
                                    break;
                                }
                            }
                        }
                    } catch (Exception e) {
                    }
                }
            }
        }
    
        /**
         * 完毕bean的实例化
         */
        private void instanceBeans() {
            for (Bean2 beanDefinition : beanDefines) {
                try {
                    if (beanDefinition.getClassPath() != null
                            && !"".equals(beanDefinition.getClassPath().trim()))
                        singletons.put(beanDefinition.getId(),
                                Class.forName(beanDefinition.getClassPath())
                                        .newInstance());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
    
        }
    
        /**
         * 读取xml配置文件
         * 
         * @param filename
         */
        private void readXML(String filename) {
            SAXReader saxReader = new SAXReader();
            Document document = null;
            try {
                URL xmlpath = this.getClass().getClassLoader()
                        .getResource(filename);
                document = saxReader.read(xmlpath);
                Map<String, String> nsMap = new HashMap<String, String>();
                nsMap.put("ns", "http://www.springframework.org/schema/beans");// 增加命名空间
                XPath xsub = document.createXPath("//ns:beans/ns:bean");// 创建beans/bean查询路径
                xsub.setNamespaceURIs(nsMap);// 设置命名空间
                List<Element> beans = xsub.selectNodes(document);// 获取文档下全部bean节点
                for (Element element : beans) {
                    String id = element.attributeValue("id");// 获取id属性值
                    String clazz = element.attributeValue("class"); // 获取class属性值
                    Bean2 beanDefine = new Bean2(id, clazz);
                    XPath propertysub = element.createXPath("ns:property");
                    propertysub.setNamespaceURIs(nsMap);// 设置命名空间
                    List<Element> propertys = propertysub.selectNodes(element);
                    for (Element property : propertys) {
                        String propertyName = property.attributeValue("name");
                        String propertyref = property.attributeValue("ref");
                        String propertyValue = property.attributeValue("value");
                        Property propertyDefinition = new Property(propertyName,
                                propertyref, propertyValue);
                        beanDefine.getProperties().add(propertyDefinition);
                    }
                    beanDefines.add(beanDefine);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 获取bean实例
         * 
         * @param beanName
         * @return
         */
        public Object getBean(String beanName) {
            return this.singletons.get(beanName);
        }
    
    }
    
    package test.spring.jnit;
    
    import org.junit.Test;
    import test.spring.service.PersonService2;
    
    public class SpringTest4 {
    
        @Test
        public void testAnnotationInject() {
            AnnotationInjectTest applicationContext = new AnnotationInjectTest(
                    "beans2.xml");
            PersonService2 personService = (PersonService2) applicationContext
                    .getBean("personService");
            personService.save();
        }
    
    }
    

    待续

  • 相关阅读:
    Codeforces Round #415 (Div. 2) C. Do you want a date?
    Lifting the Stone 计算几何 多边形求重心
    计算几何 多边形面积 和 重心 的求法
    POJ 3304 segments 线段和直线相交
    LibreOJ #114. k 大异或和
    LibreOJ #113. 最大异或和
    对于各种各样平衡树的比较
    数组splay ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
    替罪羊树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
    红黑树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/8722277.html
Copyright © 2020-2023  润新知