一、@Resource注解原理
@Resource可以标注在字段或属性的setter方法上
1. 如果指定了name属性, 那么就按name属性的名称装配;
2. 如果没有指定name属性, 那就按照默认的名称查找依赖对象;
3. 如果按默认名称查找不到依赖对象, 那么@Resource注解就会回退到按类型装配;
① 先写一个自己的@MyResource:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
@Retention(RetentionPolicy.RUNTIME) // 指定注解保留的范围 (运行期)
@Target({ ElementType.FIELD, ElementType.METHOD }) // 允许注解标注的位置 (属性, 方法)
public @interface MyResource {
public String name() default ""; // 提供name属性
}② Spring Bean Factory: ClassPathXMLApplicationContext
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;
/**
* Spring Bean Factory
*/
public class ClassPathXMLApplicationContext {
private List
beanDefines = new ArrayList
(); private Map
sigletons = new HashMap
(); public ClassPathXMLApplicationContext(String filename) { this.readXML(filename); this.instanceBeans(); this.annotationInject(); this.injectObject(); } /** * 通过注解实现注入依赖对象 */ private void annotationInject() { for (String beanName : sigletons.keySet()) { // 循环所有的Bean对象 Object bean = sigletons.get(beanName); if (bean != null) { try { // 查找属性的setter上是否有注解 PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for (PropertyDescriptor properdesc : ps) { // 循环所有属性 Method setter = properdesc.getWriteMethod();// 获取属性的setter方法 if (setter != null && setter.isAnnotationPresent(MyResource.class)) { // 判断MyResource注解是否存在 MyResource resource = setter.getAnnotation(MyResource.class); Object injectBean = null; if (resource.name() != null && !"".equals(resource.name())) { injectBean = sigletons.get(resource.name()); // 通过MyResource注解的name属性获取Bean } else { injectBean = sigletons.get(properdesc.getName()); if (injectBean == null) { // 没有指定name属性, 根据属性名称进行寻找 for (String key : sigletons.keySet()) { // 根据属性类型进行寻找 if (properdesc.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())) { injectBean = sigletons.get(key); break; } } } } setter.setAccessible(true); setter.invoke(bean, injectBean);// 把引用对象注入到属性 } } // 查找字段上是否有注解 Field[] fields = bean.getClass().getDeclaredFields(); // 取得声明的所有字段 for (Field field : fields) { if (field.isAnnotationPresent(MyResource.class)) { // 判断字段上是否存在MyResource注解 MyResource resource = field.getAnnotation(MyResource.class); Object value = null; if (resource.name() != null && !"".equals(resource.name())) { // 判断是否指定name属性 value = sigletons.get(resource.name()); } else { value = sigletons.get(field.getName()); // 没有指定name属性,那么根据字段名称寻找 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 (BeanDefiniti