首先看一下J2EE提供的@Resource注解:该注解默认安照名称进行装配,名称能够通过name属性进行指定, 假设没有指定name属性,当注解写在字段上时,默认取字段名进行依照名称查找,假设注解写在setter方法上默认取属性名进行装配。

当找不到与名称匹配的bean时才依照类型进行装配。可是须要注意的是,假设name属性一旦指定。就仅仅会依照名称进行装配。

这里我们模拟@Resource注解,便于理解注解的实现原理:

1.首先在前面模拟的容器中加入注入的方法annotationInject();

XjjClassPathXMLApplicationContext.java

package junit.test;

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; /**
* Xjj版容器
*
*/
public class XjjClassPathXMLApplicationContext {
private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
private Map<String, Object> sigletons = new HashMap<String, Object>(); public XjjClassPathXMLApplicationContext(String filename){
this.readXML(filename);
this.instanceBeans();
this.annotationInject();
this.injectObject();
}
/**
* 通过注解实现注入依赖对象
*/
private void annotationInject() {
for(String beanName : sigletons.keySet()){
Object bean = sigletons.get(beanName);
if(bean!=null){
try {
PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for(PropertyDescriptor properdesc : ps){
Method setter = properdesc.getWriteMethod();//获取属性的setter方法
if(setter!=null && setter.isAnnotationPresent(XjjResource.class)){
XjjResource resource = setter.getAnnotation(XjjResource.class);
Object value = null;
if(resource.name()!=null && !"".equals(resource.name())){
value = sigletons.get(resource.name());
}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;
}
}
}
}
setter.setAccessible(true);
setter.invoke(bean, value);//把引用对象注入到属性
}
}
Field[] fields = bean.getClass().getDeclaredFields();
for(Field field : fields){
if(field.isAnnotationPresent(XjjResource.class)){
XjjResource resource = field.getAnnotation(XjjResource.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;
}
}
}
}
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 {
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 = null;
if(propertyDefinition.getRef()!=null && !"".equals(propertyDefinition.getRef().trim())){
value = sigletons.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(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);
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属性值
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");
String propertyValue = property.attributeValue("value");
PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyref, propertyValue);
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);
}
}

实现注解用的类型:@XjjResource
XjjResource.java
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 XjjResource {
public String name() default "";
}

BeanDefinition.java

package junit.test;

import java.util.ArrayList;
import java.util.List; public class BeanDefinition {
private String id;
private String className;
private List<PropertyDefinition> propertys = new ArrayList<PropertyDefinition>(); public BeanDefinition(String id, String className) {
this.id = id;
this.className = className;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getClassName() {
return className;
} public void setClassName(String className) {
this.className = className;
} public List<PropertyDefinition> getPropertys() {
return propertys;
} public void setPropertys(List<PropertyDefinition> propertys) {
this.propertys = propertys;
}
}

PropertyDefinition.java

package junit.test;

public class PropertyDefinition {
private String name;
private String ref;
private String value; public String getValue() {
return value;
} public void setValue(String value) {
this.value = value;
} public PropertyDefinition(String name, String ref, String value) {
this.name = name;
this.ref = ref;
this.value = value;
} public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
} }

PersonServiceBean.java对PersonDao进行注解方式注入

package xjj.service.impl;

import junit.test.XjjResource;
import xjj.dao.PersonDao;
import xjj.service.PersonService; public class PersonServiceBean implements PersonService {
@XjjResource private PersonDao personDao;
private String name; public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
} public PersonServiceBean(){} public PersonServiceBean(PersonDao personDao, String name) {
this.personDao = personDao;
this.name = name;
} public void save(){
//System.out.println(name);
personDao.add();
}
}

beans.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"> <context:annotation-config/>
<bean id="personDaoxxxx" class="xjj.dao.impl.PersonDaoBean"></bean>
<bean id="personService" class="xjj.service.impl.PersonServiceBean">
</bean>
</beans>

SpringTest2.java

package junit.test;

import org.junit.BeforeClass;
import org.junit.Test; import xjj.service.PersonService;
public class SpringTest2 { @BeforeClass
public static void setUpBeforeClass() throws Exception {
} @Test public void instanceSpring(){ XjjClassPathXMLApplicationContext ctx = new XjjClassPathXMLApplicationContext("beans.xml");
PersonService personService = (PersonService)ctx.getBean("personService");
personService.save(); }
}

模拟结果:成功注入了PersonDaoBean










最新文章

  1. C#获取CSV文件内容对逗号和引号分隔的处理
  2. ion-header-bar
  3. Redis-持久化
  4. celery简单入门
  5. html body的属性 格式控制标签 内容容器标签 超链接标签 图片标签 表格
  6. css3选择器的比较(二) -- 包含字符串
  7. js模块化开发——AMD规范
  8. 《Django By Example》第十一章 中文 翻译 (个人学习,渣翻)
  9. POJ-1256 next_permutation函数应用
  10. (转)如何阅读OpenStack源码
  11. TPS,并发用户数,吞吐量以及一些计算公式
  12. vxlan基础
  13. javap浅析-书籍第3章的手写稿样稿
  14. java中获取路径的方法
  15. 开源通用爬虫框架YayCrawler-页面的抽取规则定义
  16. u-boot移植(五)---代码修改---时钟修改、SDRAM
  17. keras学习简单线性回归【1】
  18. git使用遇到的坑
  19. 4、iptables扩展匹配及网络防火墙功能
  20. windows文件映射

热门文章

  1. BZOJ 3456 城市规划 ——NTT
  2. Uva 10590 Boxes of Chocolates Again
  3. https总结
  4. 流浪者(rover)
  5. Ruby系列教程(附ruby电子书下载)【转】
  6. 创建 router 连通 subnet
  7. [LeetCode] Number of 1 Bits 位操作
  8. Servlet乱码解决
  9. NieR:Automata中的一段文字
  10. 创建一个vue-cli项