简单实现spring注解扫描

啥也不说,先上代码

MyAnnotationApplicationContext context = new MyAnnotationApplicationContext(AppConfig.class);
UserService userService = (UserService) context.getBean("userService");
System.out.println(userService);

上面的MyAnnotationApplicationContext 是我创建的一个解析类,AppConfig类上面有@ComponentScan注解定义的扫描包路径,UserService 是通过添加@Component注解的类。

@ComponentScan("com.test.service")
public class AppConfig {
}

自定义Component注解

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Component {
    String value() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface ComponentScan {
    String value() default "";
}
public class MyAnnotationApplicationContext {

	//扫描的类放在map里面
	private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
	//创建的单例的类放在单例池里面
    private Map<String, Object> singletonMap = new HashMap<>();
    
	public MyAnnotationApplicationContext(Class clazz) {
        this.clazz = clazz;
        //查看类上面是否有ComponentScan注解
        if (clazz.isAnnotationPresent(ComponentScan.class)) {
        	//获取类上面ComponentScan注解的数据
            ComponentScan annotation = (ComponentScan) clazz.getAnnotation(ComponentScan.class);
            String value = annotation.value();
            value = value.replace(".", "/");
            //注解扫描,并放到beanDefinitionMap 里面
            scan(clazz, value);
            //创建对象
            for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
                String beanName = entry.getKey();
                BeanDefinition beanDefinition = entry.getValue();
                if ("singleton".equalsIgnoreCase(beanDefinition.getScope())) {
                    Object bean = createBean(beanDefinition, beanName);
                    singletonMap.put(beanName, bean);
                }
            }
        }
    }

	private void scan(Class clazz, String path) {
		//获取类加载器,AppClassLoader
        ClassLoader loader = clazz.getClassLoader();
        //通过类加载器,拿到本地编译的类绝对路径
        URL resource = loader.getResource(path);
        File file = new File(resource.getFile());
        if (file.isDirectory()) {
            for (File f : file.listFiles()) {
                String fileName = f.getAbsolutePath();
                String className = fileName.substring(fileName.indexOf("com"), fileName.indexOf(".class"));
                className = className.replace("\\", ".");
                try {
                	//再loaderClass是为了拿到类上的注解信息
                    Class claz = this.getClass().getClassLoader().loadClass(className);
                    if (claz.isAnnotationPresent(Component.class)) {
                        Component clazAnnotation = (Component) claz.getAnnotation(Component.class);
                        String beanName = clazAnnotation.value();
                        if ("".equals(beanName)) {
                            //根据类名,将类名的第一位变成小写字母
                            beanName = Introspector.decapitalize(claz.getSimpleName());
                        }
                        BeanDefinition beanDefinition = new BeanDefinition();
                        beanDefinition.setType(claz);
                        if (claz.isAnnotationPresent(Scope.class)) {
                            Scope scope = (Scope) claz.getAnnotation(Scope.class);
                            String value = scope.value();
                            if (!"".equals(value)) {
                                beanDefinition.setScope(value);
                            } else {
                                beanDefinition.setScope("singleton");
                            }
                        } else {
                            beanDefinition.setScope("singleton");
                        }
                        beanDefinitionMap.put(beanName, beanDefinition);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
	
	//创建bean对象
	private Object createBean(BeanDefinition beanDefinition, String beanName) {
		return null;
	}
	
	///根据beanName获取对象
	public Object getBean(String beanName) {
		return null;
	}
}
@Data
public class BeanDefinition<T> {
	//类名
    private Class<T> type;
    //单例、多例
    private String scope;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值