首先分析。

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. Linux程序存储结构与进程结构堆和栈的区别【转】

    转自:http://www.hongkevip.com/caozuoxitong/Unix_Linux/24581.html 红客VIP(http://www.hongkevip.com):Linux ...

  2. 【PHP设计模式 10_ShiPeiQi.php】适配器模式

    <?php /** * [适配器模式] * 对于服务器的代码,需要不同的客户端都可以调用 * 也可能是新的程序员要修改以前程序员写的老代码 */ header("Content-typ ...

  3. Web前端工作2个月小结

    开始语: 2013年6月30日,Microsoft Learning support 项目结束,转而进入Forerunner Development 项目,这对于这块领域空白的我,空前的困难,可是我坚 ...

  4. run loop 输入源

    做了一年多的IOS开发,对IOS和Objective-C深层次的了解还十分有限,大多还停留在会用API的级别,这是件挺可悲的事情.想学好一门语言还是需要深层次的了解它,这样才能在使用的时候得心应手,出 ...

  5. APP运营推广那点事【干货】

    你的手机里面有多少应用?什么样的手机应用吸引你?下载之后经常用还是让他shi在那里?又或者刚点进去就卸载? 一款成功的应用,开发APP只是第一步,比前者更重要的是“养”APP,APP就像是一个需要不断 ...

  6. Oracle性能优化--DBMS_PROFILER

      想看到过程或者函数执行每一步的过程:想看到每一步所占的时间吗?借助profiler吧:它可以满足你来分析过程/函数执行比较久:可以直接快速找到病因:从而可以优化那一步需要优化下.        一 ...

  7. vim中设置自动匹配括号和引号

    vim ~/.vimrc 在.vimrc中添加一下几行 inoremap ( () <LEFT> inoremap { {} <LEFT> inoremap [ [] < ...

  8. 分页sql存储过程算法

    /****** Object: StoredProcedure [dbo].[PRO_Pub_FenYe] Script Date: 08/04/2014 11:14:22 ******/ SET A ...

  9. UVa 489,紫书P79,刽子手游戏

    题目链接:https://uva.onlinejudge.org/external/4/489.pdf 这个题很像之前的一个拓扑排序的题目,思路类似咯. 程序模块化: 每次判断一个字母,lose,wi ...

  10. invoke和beginInvoke

    首先说下,invoke和begininvoke的使用有两种情况: 1. control中的invoke.begininvoke. 2. delegrate中的invoke.begininvoke. 这 ...