Spring工厂的入门理解(一)

关于Spring框架的学习,通过底层的简单实现,能够更好的理解工厂对象的创建,以下代码是基于注解方式实现Spring工厂提供对象的方式。
1、代码实现的目录结构

2.目录结构的分层介绍
 2.1自定义的注解cn.spring.annotation
 @Component用来修饰需要创建对象的类

 @ComponentScan用来修饰需要扫描包的注解类

2.2定义注解类cn.spring.config

2.3需要交由工厂创建对象的类 cn.spring.beans

 
 
2.4自定义工厂类 cn.spring.factory
package cn.spring.factory;
import cn.spring.annotation. Component ;
import cn.spring.annotation. ComponentScan ;
import java.io.File;
import java.io.FileFilter;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
/**
* Created by lingkong on 2018/1/20.
*/
public class AnnotationConfigApplicationContext {
private Map<String,Object> beanMap = new HashMap<String, Object>();
public AnnotationConfigApplicationContext(Class<?> cls) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//1.获取自定义类上的注解
//cls:自定义用来扫描注解的类的.class文件
//Component.class: 自定的注解,包含此注解的对象将会被创建对象
ComponentScan annotation = cls.getAnnotation( ComponentScan . class );
//2.获取注解的值,该值为需要扫描的路径
String pkgName = annotation.value();
//3.获取的路径是以"."作为分隔符,需全部替换为"/"
String pkgPath= pkgName.replaceAll( " \\ ." , "/" );
//4.获取该路径的统一资源全路径
URL url = getClass().getClassLoader().getResource(pkgPath);
//5.获取绝对路径,并创建文件对象
File fileObj = new File(url.getPath());
//6.获取该文件下的所有文件,并过滤出后缀名是.class的文件
File[] files = fileObj.listFiles( new FileFilter() {
public boolean accept(File pathname) {
boolean flag = pathname.getName().endsWith( ".class" );
if (flag) return true ;
return false ;
}
});
//7.遍历获得所有.class文件
for (File file:files){
//8.截取文件的类名
String clsName = file.getName().substring( 0 , file.getName().lastIndexOf( "." ));
//9.通过反射获取类对象(此处有ClassNotFoundException异常先抛出)
System. out .println(clsName);
Class<?> aClass = Class. forName (pkgName + "." + clsName);
//10.该类是否含有指定的注解Component
boolean flag = aClass.isAnnotationPresent( Component . class );
//11.如果含有指定注解,就继续操作,没有就结束本次循环,获取下一个类
if (!flag) continue ;
//12.为含有指定注解的类创建对象,通过其无参构造器
// (此处有NoSuchMethodExceptionIllegalAccessException, InvocationTargetException,
// InstantiationException异常,先抛出)
Object obj = aClass.getDeclaredConstructor().newInstance();
//13.获取指定注解上的值
String value = aClass.getAnnotation( Component . class ).value();
//14.判断该值是否为空
if ( "" .equals(value)){
//15.如果为空,将类名首字母小写,赋值给value
value = String. valueOf (clsName.charAt( 0 )).toLowerCase() + clsName.substring( 1 );
}
//15.将value赋值给key,和obj组成键值对存入beanMap集合
String key = value;
beanMap .put(key,obj);
}
/**
}
* 通过key值返回一个对象
* @param key
* @return
*/
public Object getBean(String key){
return beanMap .get(key);
}
/**
* 重写的方法
* @param key
* @param cls
* @param <T>
* @return
*/
public < T > T getBean(String key,Class< T > cls){
return ( T ) beanMap .get(key);
}
/**
* 清空集合,实现关闭工厂
*/
public void close(){
beanMap .clear();
beanMap = null ;
}
}
2.5代码测试
import cn.spring.beans.ObjectGenerator;
import cn.spring.config.AnnotationConfig;
import cn.spring.factory.AnnotationConfigApplicationContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.lang.reflect.InvocationTargetException;

/**
 * Created by lyang on 2018/1/20.
 */
public class TestFactory {
    private AnnotationConfigApplicationContext ac;

    @Before
    public void init() throws Exception {
        ac = new AnnotationConfigApplicationContext(AnnotationConfig.class);
    }

    @Test
    public void Test1(){
        ObjectGenerator og = (ObjectGenerator)ac.getBean("object");
        System.out.println(og);
    }

    @After
    public void destroy(){
        ac.close();
        System.out.println(ac);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值