首先分析。

1: 肯定要利用dom4j读取xml配置文件,将所有的bean的配置信息读取出来

2: 利用反射技术,实例化所有的bean

3: 写注解处理器, 利用注解和内省实现依赖对象的注入。

4: 利用XML中<property>信息,通过内省beanUtils实现基本数据类型的注入

实现:

package cn.gbx.example;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.File;
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;
public class MyClassPathXmlApplicationContext {
private List<DefBean> defBeans = new ArrayList<DefBean>();
private Map<String, Object> singletons = new HashMap<String, Object>(); public MyClassPathXmlApplicationContext(String filename) {
this.readXML(filename);
this.instanceBean();
this.injectAnotation();
this.injectXML(); } //注入基本类型的属性
private void injectXML() {
//枚举bean
for (DefBean defBean : defBeans) {
Object bean = singletons.get(defBean.getId());
if (bean != null) {
//枚举该bean的Property看有没有基本数据类型的注入
for (DefProperty defProperty : defBean.getDefPropertys()) {
if (defProperty.getValue() != null){
try {
PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for (PropertyDescriptor p : ps) {
if (p.getName().equals(defProperty.getName())) {
Method setter = p.getWriteMethod();
//保证有set方法
if (setter != null) {
Object value = ConvertUtils.convert(defProperty.getValue(), p.getPropertyType());
setter.setAccessible(true);
setter.invoke(bean, value);
}
break;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
} //注解处理器
private void injectAnotation() {
//枚举实例化的bean
for (String key : singletons.keySet()) {
Object bean = singletons.get(key);
if (bean != null) { /*
* 检查setter方法
*/
try {
PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
//枚举每个bean的属性
for (PropertyDescriptor p : ps) {
Method setter = p.getWriteMethod();
Object value = null;
//存在set方法, 并且有setter上边有Resource注解
if (setter != null && setter.isAnnotationPresent(GbxResource.class)){
GbxResource gbxResource = setter.getAnnotation(GbxResource.class);
//若有name 则按name查找
if (gbxResource.name() != null && !"".equals(gbxResource.name())) {
value = singletons.get(gbxResource.name());
} else { //若没有,先安名字查找, 再按数据类型查找
value = singletons.get(p.getName());
if (value == null) {
for (String key2 : this.singletons.keySet()) {
if (p.getPropertyType().isAssignableFrom(this.singletons.get(key2).getClass())) {
value = this.singletons.get(key2);
break;
}
}
}
}
setter.setAccessible(true);
setter.invoke(bean, value);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} /*
* 检查字段
*/
Field[] fileds = bean.getClass().getDeclaredFields();
for (Field field : fileds) {
if (field.isAnnotationPresent(GbxResource.class)) {
GbxResource gbxResource = field.getAnnotation(GbxResource.class);
Object value = null;
if (gbxResource.name() != null && !"".equals(gbxResource.name())) {
value = this.singletons.get(gbxResource.name());
} else {
value = this.singletons.get(field.getName());
if (value == null) {
for (String key2 : this.singletons.keySet()) {
if (field.getType().isAssignableFrom(this.singletons.get(key2).getClass())) {
value = this.singletons.get(key2);
break;
}
}
}
}
field.setAccessible(true);
try {
field.set(bean, value);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
} } //实例化bean对象
private void instanceBean() {
for (DefBean bean : defBeans) {
System.out.println(bean.getId() + " : " + bean.getClassName());
if (bean.getClassName() != null && !"".equals(bean.getClassName())) {
try {
singletons.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
//读取xml文件
private void readXML(String filename) {
SAXReader reader = new SAXReader();
Document document = null;
URL xmlPath = this.getClass().getClassLoader().getResource(filename); try {
//的到document
document = reader.read(xmlPath);
//设置命名空间
Map<String, String> nsMap = new HashMap<String, String>();
nsMap.put("ns", "http://www.springframework.org/schema/beans");
//创建查询路径
XPath xPath = document.createXPath("//ns:beans/ns:bean");
xPath.setNamespaceURIs(nsMap); List<Element> beans = xPath.selectNodes(document);
DefBean defBean = null;
for (Element e : beans) {
String id = e.attributeValue("id");
String className = e.attributeValue("class");
defBean = new DefBean(id, className); XPath xPath2 = e.createXPath("ns:property");
xPath2.setNamespaceURIs(nsMap);
List<Element> propertys = xPath2.selectNodes(e); DefProperty defProperty = null;
for (Element e2 : propertys) {
String name = e2.attributeValue("name");
String ref = e2.attributeValue("ref");
String value = e2.attributeValue("value"); defProperty = new DefProperty(name, ref, value);
defBean.getDefPropertys().add(defProperty);
}
defBeans.add(defBean);
}
} catch (Exception e) {
e.printStackTrace();
}
} public Object getBean(String key) {
return singletons.get(key);
}
}

  

package cn.gbx.serviceimpl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import cn.gbx.daoimpl.PersonDao;
import cn.gbx.example.GbxResource;
import cn.gbx.service.PersonService; public class PersonServiceImpl implements PersonService {
@GbxResource
private PersonDao personDao;
private String name; public void save() {
personDao.save();
System.out.println("Name = " + name);
System.out.println("service层的 save方法");
} public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public PersonDao getPersonDao() {
return personDao;
} }

  

注解:

package cn.gbx.example;

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 GbxResource {
public String name() default "";
}

  

编码实现Spring 利用@Resource注解实现bean的注入,xml实现基本数据类型的注入的更多相关文章

  1. Spring学习--通过注解配置 Bean (三)

    组件装配: <context:component-sacan> 元素还会自动注册 AutowiredAnnotationBeanPostProcesser 实例 , 该实例可以自动装配具有 ...

  2. Spring 与 @Resource注解

    Spring 中支持@Autowired注解,能够实现bean的注入.同时,Spring 也支持@Resource注解,它和@Autowired类似,都是实现bean的注入.该注解存在javax.an ...

  3. Spring之使用注解实例化Bean并注入属性

    1.准备工作 (1)导入jar包 除了上篇文章使用到的基本jar包外,还得加入aop的jar包,所有jar包如下 所需jar包 (2)配置xml <?xml version="1.0& ...

  4. Spring学习--通过注解配置 Bean (二)

    在 classpath 中扫描组件: 当在组件类上使用了特定的注解之后 , 还需要在 Spring 的配置文件中声明 <context:component-scan>: base-pack ...

  5. Spring中@Resource注解报错

    描述:Spring框架中,@Resource注解报错,在书写时没有自动提示 解决方法:因为maven配置文件的pom.xml文件中缺少javax.annotation的依赖,在pom.项目路中加入依赖 ...

  6. Spring中用@DependsOn注解控制Bean的创建顺序

    1. 概述 Spirng容器自己会管理bean的生命周期和bean实例化的顺序,但是我们仍然可以根据我们自己的需求进行定制.我可以可以选择使用SmartLifeCycle接口,也可以用@Depends ...

  7. Spring_day01--Spring的bean管理(xml方式)_属性注入介绍

    Spring的bean管理(xml方式) Bean实例化的方式 1 在spring里面通过配置文件 创建对象 2 bean实例化(创建对象)三种方式实现 第一种 使用类的无参数构造创建(重点) Use ...

  8. spring利用扫描方式对bean的处理(对任何版本如何获取xml配置信息的处理)

    利用扫描的方式将组件注入容器,就也可以不用操作bean来实例化对象了. 下面我做一个例子 我用的spring3.2.2版本的 首先写一个spring.xml. <?xml version=&qu ...

  9. Spring学习--通过注解配置 Bean (一)

    在 classpath 中扫描组件: 组件扫描(component scanning): Spring 能够从 classpath 下自动扫描 , 侦测和实例化具有特定注解的组件. 特定组件包括: @ ...

随机推荐

  1. 使用Jconsole监控weblogic的配置方法

    在项目中发现full gc非常频繁.达到了每分钟13次.我怀疑可能会有内存泄露.于是在晚上找了内存泄露的资料. 内存长期占用并导致系统不稳定一般有两种可能: 1. 对象被大量创建而且被缓存,在旧的对象 ...

  2. jquery+thinkphp实现跨域抓取数据的方法

    jquery的$.post发送数据到服务器后台,在由后台的PHP代码执行远程抓取,存到数据库ajax返回数据到前台,前台用JS接受数据并显示. //远程抓取获取数据$("#update_ac ...

  3. linux下对sh文件的操作

    1.创建test.sh文件 touch test.sh 2.编辑sh文件 vi test.sh(i:插入 | esc:退出insert模式 | wq+回车:退出) 3.保存退出 敲击esc, 然后输入 ...

  4. WPF:获取控件内的子项

    一.界面内容(部分:仅供参考) <Window> <Window.Resources> <!--工具数据源--> <XmlDataProvider x:Key ...

  5. shell十三问:关于${0##*/} 和${0%/*}

    转自shell十三问:  http://bbs.chinaunix.net/thread-218853-1-1.html …… 假設我們定義了一個變量為:file=/dir1/dir2/dir3/my ...

  6. C#.Net理论

    -------------2014年8月28---------------------------- 1.C#的委托是什么,事件是不是一种委托?答:委托可以把一个方法作为参数代入另一个方法.委托可以理 ...

  7. fragment相关

    1.鸿洋大神前两年写的,从最基础的开始详解.对常用的方法都做了精炼的总结,分上下两篇 http://blog.csdn.net/lmj623565791/article/details/3797096 ...

  8. ACM题目————Find them, Catch them

    Description The police office in Tadu City decides to say ends to the chaos, as launch actions to ro ...

  9. Android网络通信之WiFi Direct

    使用Wi-Fi Direct技术可以让具备硬件支持的设备在没有中间接入点的情况下进行直接互联.Android 4.0(API版本14)及以后的系统都提供了对Wi-Fi Direct的API支持.通过对 ...

  10. php之上传类

    <?php /** * Created by PhpStorm. * User: Administrator * Date: 2016/5/26 * Time: 20:29 */ class u ...