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.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();
    }

}

版权声明:本文为博主原创文章,未经博主允许不得转载。如需转载,请注明出处:http://blog.csdn.net/lindonglian

时间: 2024-10-07 05:16:24

Spring(八)编码剖析@Resource注解的实现原理的相关文章

Spring2.5学习3.2_编码剖析@Resource注解的实现原理

首先看一下J2EE提供的@Resource注解:该注解默认安照名称进行装配,名称能够通过name属性进行指定, 假设没有指定name属性,当注解写在字段上时,默认取字段名进行依照名称查找,假设注解写在setter方法上默认取属性名进行装配. 当找不到与名称匹配的bean时才依照类型进行装配.可是须要注意的是,假设name属性一旦指定.就仅仅会依照名称进行装配. 这里我们模拟@Resource注解,便于理解注解的实现原理: 1.首先在前面模拟的容器中加入注入的方法annotationInject(

深入探索spring技术内幕(四): 剖析@Resource注解实现原理与注解注入

一.@Resource注解原理 @Resource可以标注在字段或属性的setter方法上 1.  如果指定了name属性, 那么就按name属性的名称装配; 2. 如果没有指定name属性, 那就按照默认的名称查找依赖对象; 3. 如果按默认名称查找不到依赖对象, 那么@Resource注解就会回退到按类型装配; ① 先写一个自己的@MyResource: import java.lang.annotation.Retention; import java.lang.annotation.Re

Spring高级话题[email&#160;protected]***注解的工作原理

出自:http://blog.csdn.net/qq_26525215 @EnableAspectJAutoProxy @EnableAspectJAutoProxy注解 激活Aspect自动代理 <aop:aspectj-autoproxy/> 开启对AspectJ自动代理的支持. 在用到AOP的自动代理的时候用,如果你理解了Java的动态代理,很容易的就会熟悉AOP的自动代理的. @EnableAsync @EnableAsync注解开启异步方法的支持. 这个相信大家都比较熟悉的.对于异步

Spring第七弹—依赖注入之注解方式注入及编码解析@Resource原理

    注入依赖对象可以采用手工装配或自动装配,在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果. 手工装配依赖对象  手工装配依赖对象,在这种方式中又有两种编程方式 在xml配置文件中,通过在bean节点下配置,上边博客已经讲解,再次不在缀余. 在java代码中使用@Autowired或@Resource注解方式进行装配.但我们需要在xml配置文件中配置以下信息: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <be

Spring中@Autowired注解、@Resource注解的区别(转)

标签: Autowired Resource Spring(3)  Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@PreDestroy. @Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了.@Resource有两个属性是比较重要的,分是name和type,Spring将@Reso

Spring中@Autowired注解、@Resource注解的区别

Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@PreDestroy. @Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了.@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析

SSH深度历险(八) 剖析SSH核心原理+Spring依赖注入的三种方式

在java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中.依赖注入的另一种说法是"控制反转",通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做. Spring依赖注入(

spring中@Resource注解的应用

前言,spring是一个非常优秀的框架,在依赖IOC编程方面,手工方式提供了两种方式注入Bean,XML配置和使用注解+自动扫描package的方式 [email protected]应用在字段上,则注入规则是: a.先使用字段名字匹配bean,查找到bean则注入,如果类型不匹配则此时有异常,注入失败 b.如果字段名字没有匹配到Bean则spring会尝试采用字段类型匹配,如果找打bean则注入,如果字段类型是接口则有可能会匹配到多个类型,则会抛出匹配到多个bean的异常. 注入失败. [em

Spring 与 @Resource注解

Spring 中支持@Autowired注解,能够实现bean的注入.同时,Spring 也支持@Resource注解,它和@Autowired类似,都是实现bean的注入.该注解存在javax.annotation.Resource包中. 使用方法如下: 1 import javax.annotation.Resource; 2 public class A{ 3 4 @Resource 5 private B b; 6 7 } 其中@Resource有两个参数会在spring配置中进行准确的