您的位置:首页 > 移动开发 > Objective-C

自己创建@Resource注解

2012-07-15 15:27 411 查看
      我们可以使用@Resource注解,为字段注入值,如果setXXX方法上有注解@Resource,那么spring容器会帮我们调用该set方法。那么注解功能是如何实现的呢?

      我们先来分析 @Resource注解作用于set函数上的。

      为了实现 @Resource注解的功能,我们可以根据以下几步做到:

      1: 取得bean的属性描述集合

            

PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass())
.getPropertyDescriptors();


      2:遍历属性集合,获取属性的set方法。

          

for(PropertyDescriptor properdesc : ps){
Method setter = properdesc.getWriteMethod();//获取属性的setter方法
}
      3:判断set方法是否为空,且是否有注解 @Resource

       

if(setter!=null && setter.isAnnotationPresent(ItcastResource.class))
             isAnnotationPresent(class c)方法用来判断是否有c类型的注解

     4:如果不为空,且有注解 @Resource,这时候我们就可以判断注解后面是否有相应的name属性,@Resource(name=""),如果有name属性,那么我们就到bean实例的集合中取出对应的值。

 
  5:如果没有指定name属性,那么我们就根据属性的名称去获取,例如String age;那么我们就查找key为age的bean实例。

 
 6:如果还是没有查找到,那么我们就到bean的集合中查找是否有和该属性一样类型的bean实例(相同类型包括父类,抽象类,接口),如果有则取出。

 
    我们可以使用isAssignableForm方法判断是否为相同类型

if(properdesc.getPropertyType().
isAssignableFrom(sigletons.get(key).getClass()))


 
 7:调用setXXX方法,将我们找出的值注入到属性中去。

 
 如果@Resource是作用于字段上面的话,判断过程和作用于set方法上面差不多。

 
 

 
 下面是模拟@Resource的代码。

 
  首先我们创建一个自己的注解,ItcastResource

 
   

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 ItcastResource {
public String name() default "";
}
  @Retention指明该注解作用的时机,RetentionPolicy.RUNTIME代表运行期。

 
 @Target指明该注解可以作用于哪里,ElementType.FIELD, ElementType.METHOD

表明作用于字段和方法。

 
  

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;
}

}


 

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;
}

}


 
  

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;

/**
*  *
*/
public class ItcastClassPathXMLApplicationContext {
private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
private Map<String, Object> sigletons = new HashMap<String, Object>();

public ItcastClassPathXMLApplicationContext(String filename){
this.readXML(filename);
this.instanceBeans();
this.annotationInject();
this.injectObject();
}
/**
* 通过注解实现注入依赖对象
*/
private void annotationInject() {
//遍历所有的bean实例
for(String beanName : sigletons.keySet()){
//根据id,获得bean实例
Object bean = sigletons.get(beanName);
if(bean!=null){
try {
//取得bean的属性描述集合
PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass())
.getPropertyDescriptors();
for(PropertyDescriptor properdesc : ps){
Method setter = properdesc.getWriteMethod();//获取属性的setter方法
//如果set方法不为空,且setXXX()方法上面有@ItcastResource注解
if(setter!=null && setter.isAnnotationPresent(ItcastResource.class)){
//获取到注解对象
ItcastResource resource = setter.getAnnotation(ItcastResource.class);
Object value = null;
//判断注解后面是否有name属性@ItcastResource(name="")
if(resource.name()!=null && !"".equals(resource.name())){
//如果有name值,那么将name对应的bean赋值给value
value = sigletons.get(resource.name());
}else{
//如果没有name值,则根据属性名到bean集合里面去取,比如
//属性名称为 age,则查找key为age的bean实例
value = sigletons.get(properdesc.getName());
//如果还是没有查找到,则查找和属性相同类型的bean
if(value==null){
//遍历bean集合
for(String key : sigletons.keySet()){
//判断bean集合中的对象是否和该属性相同类型(包括父类,
//接口,抽象类),我们可以调用isAssignableFrom方法
//如果有相同类型的,则赋值给value
if(properdesc.getPropertyType().
isAssignableFrom(sigletons.get(key).getClass())){
value = sigletons.get(key);
break;
}
}
}
}
//设置set方法为可访问的,类似于public
setter.setAccessible(true);
setter.invoke(bean, value);//把引用对象注入到属性
}
}
//获得bean实例声明的所有字段
Field[] fields = bean.getClass().getDeclaredFields();
//遍历所有的字段
for(Field field : fields){
//如果字段上面有注解@ItcastResource
if(field.isAnnotationPresent(ItcastResource.class)){
//获取到注解对象
ItcastResource resource = field.getAnnotation(ItcastResource.class);
Object value = null;
//判断注解后面是否有name属性@ItcastResource(name="")
if(resource.name()!=null && !"".equals(resource.name())){
value = sigletons.get(resource.name());
}else{
//如果没有name值,则根据属性名到bean集合里面去取,比如
//属性名称为 age,则查找key为age的bean实例
value = sigletons.get(field.getName());
//如果还是没有查找到,则查找和属性相同类型的bean
if(value==null){
//判断bean集合中的对象是否和该属性相同类型(包括父类,
//接口,抽象类),我们可以调用isAssignableFrom方法
//如果有相同类型的,则赋值给value
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);
}
}


 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息