啥也不说,先上代码
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;
}