【j2ee spring】2、深入理解注释@Resource注入
2015-03-19 20:50
417 查看
深入理解注释@Resource注入
@Resource默认是按照名称,名称可通过@Resource的name属性进行指定,如果没有指定name属性,当注解标注在字段上即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在setter方法上,则默认属性为bean名称寻找依赖对象。模拟@Resource实现
1、首先我们写一个自己的注释
/** * 书本:【SSH】 * 功能:实现spring里面的注解注入功能,个人实现 * 文件:Cutter_pointResource.java * 时间:2015年3月18日21:17:24 * 作者:cutter_point */ package junit.test; 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.FIELD, ElementType.METHOD}) //注解的地方是字段和属性 public @interface Cutter_pointResource { public String name() default ""; //name属性默认是空字符串 }
2、然后先相应的bean里面添加自己的注解在前面
package cn.itcast.service.impl; import java.util.HashSet; import java.util.Set; import javax.annotation.Resource; import junit.test.Cutter_pointResource; import cn.itcast.dao.PersonDao; import cn.itcast.service.PersonService; public class PersonServiceBean implements PersonService { // @Resource private PersonDao personDao; //通过注释来进行注入 @Cutter_pointResource private PersonDao personDao; private String name = "cutter_point"; public PersonServiceBean() { // TODO Auto-generated constructor stub } //使用set方法注释注入 // @Cutter_pointResource // public void setPersonDao(PersonDao personDao) // { // this.personDao = personDao; // } /** * @author xiaofeng * @param 这个是可以生成的构造器 */ public PersonServiceBean(PersonDao personDao, String name) { this.personDao = personDao; this.name = name; } public void save(){ System.out.println(name); personDao.add(); } }
3、然后在我们读取XML文档bean.xml的时候,注意注解注入,也就是在对象注入之前检测一下是否有注解,有的话就注入
this.readXML(filename); this.instanceBeans(); this.annotationInject(); //注解注入 this.injectObject(); //注入对象
然后具体实现注解的注入
/** * 通过注解实现注入依赖对象 */ private void annotationInject() { for(String beanName : sigletons.keySet()) //吧map里面的bean的id号一个一个地取出来 { Object bean = sigletons.get(beanName); //根据id取出相应的bean对象 if(bean!=null) { try { //取得这个bean实例化的属性信息,这个是方法前面加了 PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); //一个容器 for(PropertyDescriptor properdesc : ps) //一个属性一个属性取出来 { Method setter = properdesc.getWriteMethod();//获取属性的setter方法 if(setter!=null && setter.isAnnotationPresent(Cutter_pointResource.class)) //看看这个set函数上面是否有这个注解 { Cutter_pointResource resource = setter.getAnnotation(Cutter_pointResource.class); //取得这个注解 Object value = null; //量这个属性 if(resource.name()!=null && !"".equals(resource.name())) { value = sigletons.get(resource.name()); //name属性制定的是bean的名称 } else { value = sigletons.get(properdesc.getName()); //根据字段的名称在容器中寻找 if(value==null) { for(String key : sigletons.keySet()) { //根据字段的类型进行寻找 if(properdesc.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())) { value = sigletons.get(key); break; } } } } System.out.println("就是里面的方法前面加了注释"); setter.setAccessible(true); //运行访问私有的字符 setter.invoke(bean, value);//把引用对象注入到属性 } } //这个是对字段进行处理,数据成员前面加了注释 Field[] fields = bean.getClass().getDeclaredFields(); //bean的所有的字段数组 for(Field field : fields) //取出每个字段 { if(field.isAnnotationPresent(Cutter_pointResource.class)) //字段上是否存在注解 { Cutter_pointResource resource = field.getAnnotation(Cutter_pointResource.class); Object value = null; if(resource.name()!=null && !"".equals(resource.name())) { value = sigletons.get(resource.name()); } else { value = sigletons.get(field.getName()); if(value==null) { for(String key : sigletons.keySet()) { //根据字段的类型进行寻找 if(field.getType().isAssignableFrom(sigletons.get(key).getClass())) { value = sigletons.get(key); break; } } } } System.out.println("字段注解注入,就是相应的数据成员加上了注释"); field.setAccessible(true);//允许访问private字段 field.set(bean, value); } } } catch (Exception e) { e.printStackTrace(); } } } }
4、对于XML文档进行操作的全部代码
package junit.test; 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.HashSet; import java.util.List; import java.util.Map; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.XPath; import org.dom4j.io.SAXReader; /** * 传智传客版容器 * */ public class ItcastClassPathXMLApplicationContext { private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>(); private Map<String, Object> sigletons = new HashMap<String, Object>(); //存放所有的bean对象 public ItcastClassPathXMLApplicationContext(String filename) { this.readXML(filename); this.instanceBeans(); this.annotationInject(); this.injectObject(); //注入对象 } /** * 通过注解实现注入依赖对象 */ private void annotationInject() { for(String beanName : sigletons.keySet()) //吧map里面的bean的id号一个一个地取出来 { Object bean = sigletons.get(beanName); //根据id取出相应的bean对象 if(bean!=null) { try { //取得这个bean实例化的属性信息,这个是方法前面加了 PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); //一个容器 for(PropertyDescriptor properdesc : ps) //一个属性一个属性取出来 { Method setter = properdesc.getWriteMethod();//获取属性的setter方法 if(setter!=null && setter.isAnnotationPresent(Cutter_pointResource.class)) //看看这个set函数上面是否有这个注解 { Cutter_pointResource resource = setter.getAnnotation(Cutter_pointResource.class); //取得这个注解 Object value = null; //量这个属性 if(resource.name()!=null && !"".equals(resource.name())) { value = sigletons.get(resource.name()); //name属性制定的是bean的名称 } else { value = sigletons.get(properdesc.getName()); //根据字段的名称在容器中寻找 if(value==null) { for(String key : sigletons.keySet()) { //根据字段的类型进行寻找 if(properdesc.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())) { value = sigletons.get(key); break; } } } } System.out.println("就是里面的方法前面加了注释"); setter.setAccessible(true); //运行访问私有的字符 setter.invoke(bean, value);//把引用对象注入到属性 } } //这个是对字段进行处理,数据成员前面加了注释 Field[] fields = bean.getClass().getDeclaredFields(); //bean的所有的字段数组 for(Field field : fields) //取出每个字段 { if(field.isAnnotationPresent(Cutter_pointResource.class)) //字段上是否存在注解 { Cutter_pointResource resource = field.getAnnotation(Cutter_pointResource.class); Object value = null; if(resource.name()!=null && !"".equals(resource.name())) { value = sigletons.get(resource.name()); } else { value = sigletons.get(field.getName()); if(value==null) { for(String key : sigletons.keySet()) { //根据字段的类型进行寻找 if(field.getType().isAssignableFrom(sigletons.get(key).getClass())) { value = sigletons.get(key); break; } } } } System.out.println("字段注解注入,就是相应的数据成员加上了注释"); field.setAccessible(true);//允许访问private字段 field.set(bean, value); } } } catch (Exception e) { e.printStackTrace(); } } } } /** * 为bean对象的属性注入值 */ private void injectObject() { for(BeanDefinition beanDefinition : beanDefines) { Object bean = sigletons.get(beanDefinition.getId()); //取出所有的实例化 if(bean!=null) { try { //Introspector.getBeanInfo(bean.getClass())取得类的信息 PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); //后面这个函数是取得相应的属性信息 for(PropertyDefinition propertyDefinition : beanDefinition.getPropertys()) { for(PropertyDescriptor properdesc : ps) { if(propertyDefinition.getName().equals(properdesc.getName())) { Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private if(setter!=null) { Object value = sigletons.get(propertyDefinition.getRef()); setter.setAccessible(true); setter.invoke(bean, value);//把引用对象注入到属性 } break; } } } } catch (Exception e) { } } } } /** * 完成bean的实例化,吧所有的bean放到sigleton里面,并实例化保存 */ private void instanceBeans() { for(BeanDefinition beanDefinition : beanDefines) { try { if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim())) sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).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); //获取xml文档的路径 document = saxReader.read(xmlpath); //读取xml文档 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属性值 BeanDefinition beanDefine = new BeanDefinition(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"); PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyref); beanDefine.getPropertys().add(propertyDefinition); } beanDefines.add(beanDefine); } } catch(Exception e) { e.printStackTrace(); } } /** * 获取bean实例 * @param beanName * @return */ public Object getBean(String beanName){ return this.sigletons.get(beanName); } }
5、最后运行结果
项目图
相关文章推荐
- 【j2ee spring】1、使用注释@Resource进行注入
- Spring AOP注解通过@Autowired,@Resource(J2EE提供),@Qualifier,@PostConstruct,@PreDestroy注入属性的配置文件详解
- 深入理解Spring中的Lookup(方法注入)
- 深入探索spring技术内幕(四): 剖析@Resource注解实现原理与注解注入
- 关于Spring中的[控制反转]和[依赖注入]的深入理解
- ######Spring第5天ssh整合(注解版)难理解知识点:【自定义 方法加注解的方式】给dao注入sessionFactory属性+【搞清@Autowared和@Resource含义】
- 深入探索spring技术内幕(四): 剖析@Resource注解实现原理与注解注入
- 深入探索spring技术内幕(四): 剖析@Resource注解实现原理与注解注入
- 深入探索spring技术内幕(四): 剖析@Resource注解实现原理与注解注入
- MyEclipse中Spring工程使用@Resource注释的问题
- 深入理解spring注解(1)java注解基础
- 如果想对控制反转和依赖注入有更深入的理解
- spring注入方式之Resource注入
- spring下应用@Resource, @Autowired 和 @Inject注解进行依赖注入的差异
- Spring 学习总结(一)依赖注入的理解
- Spring @Resource、@Autowired、@Qualifier的注解注入及区别
- 我见过的理解spring自动注入原理最形象最生动的一个例子了!!
- 对Spring中接口注入的理解实例分析
- 关于Spring的控制反转、依赖注入等的理解
- Spring 之 编码实现 @Resource注解属性注入