欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring IOC 原理 ,Java 反射实例,自定义注解

程序员文章站 2022-06-22 15:34:35
...

Spring IOC 原理 和 Java 反射实例

                                                                                                        ——我一直不太信任自己的记忆力,所以我把它们都写下来

        

       自从接触了Spring的各种思想后,真的是被各种设计征服了,当然Spring的各种设计基本上都需要扎实的java基础支持;比如SpringIOC(依赖注入,bean管理思想)运用到了Java注解、反射、xml等等。下面用一个实例来说明SpringIOC的原理。

 

 

       在SpringMVC项目中,对DAO和service一般都是spring注解管理的,像@Service,@Respository,@Component等。项目用Maven管理,文章末尾有svn地址和下载地址,代码里只要稍微有点晦涩的地方都有注释,有java经验的应该都能看懂。下面是项目结构图

 


Spring IOC 原理 ,Java 反射实例,自定义注解
            
    
    博客分类: WEB后台 Java反射SpringIOCjava自定义注解 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

anntation包下面是对@Resource,@Respository,@Service 的注解实现类;util包下面是java反射的相关类,dao和service包见文思意。测试入口在src/test/java下面。

 

 

MySpring.class 是主要的逻辑类,模拟了SpringIOC的ApplicationContext,所有的注册过的bean都可以从这里获得。完整的类如下

package com.albert.AnnotationTest;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Test;

import com.albert.AnnotationTest.annotation.Resource;
import com.albert.AnnotationTest.annotation.Respository;
import com.albert.AnnotationTest.annotation.Service;
import com.albert.AnnotationTest.dao.MyDao;
import com.albert.AnnotationTest.service.MyService;
import com.albert.AnnotationTest.util.AlbertUtil;
import com.albert.AnnotationTest.util.ClassByPackage;

/**
 * @author albert
 * 这个类模拟Spring ioc 和mvc
 * 所有注解过的bean都从这里取得
 * 
 */
public class MySpring {
	/**
	 * 模拟Spring扫描的注解包
	 */
	private final static String packageName = "com.albert.AnnotationTest";
	/**
	 * 存放注解的bean对象
	 */
	private static Map<String,Object> beanMap = new HashMap<String, Object>();
	static{
		try {
			packageToScan();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 根据beanName从容器获取bean对象
	 * @param beanName
	 * @return
	 */
	public static Object getBean(String beanName){
		Object obj = null;
		obj = beanMap.get(beanName);
		return obj;
	}
	
	/**
	 * 遍历包中的注解类
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	private static void packageToScan() throws InstantiationException, IllegalAccessException{
		List<Class> clsList = ClassByPackage.getClasssFromPackage(packageName);
		//先加载dao
		for(Class cls : clsList){
                        //判断类是不是有@Respository注解
			if(cls.isAnnotationPresent(Respository.class)){
				String clsName = AlbertUtil.getBeanName(cls.getName());
				//bean对象存入map
				beanMap.put(clsName, cls.newInstance());
			}
		}
		//加载service,同时对其中@Resource注解的属性进行赋值
		for(Class cls : clsList){
			if( cls.isAnnotationPresent(Service.class)){
				String clsName = cls.getName();
				clsName = clsName.substring(clsName.lastIndexOf(".")+1, clsName.length());
				beanMap.put(AlbertUtil.toLowerCaseFirstOne(clsName), cls.newInstance());
				
				//扫描注解@Resource的属性并赋值
				Field[] field = cls.getDeclaredFields();
				for(Field f : field){
                                        //判断属性是不是有@Resource注解
					if(f.isAnnotationPresent(Resource.class)){
						f.setAccessible(true);
						f.set(beanMap.get(AlbertUtil.getBeanName(cls.getName())), beanMap.get(f.getName()));
					}
				}
			}
		}
	}
	
	
}

 项目SVN地址:http://code.taobao.org/svn/AnnotationTestAlbert/                                                                                

 

 

 

 


 

  • Spring IOC 原理 ,Java 反射实例,自定义注解
            
    
    博客分类: WEB后台 Java反射SpringIOCjava自定义注解 
  • 大小: 65.9 KB