- 两个注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Service {
String value() default "";
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface ComponentScan {
String value() default "";
}
- 配置类,指定扫描哪个包
@ComponentScan("com.qhf")
class AppConfig {
}
- 组件标注的类,在com.qhf.spring 包下,自动实例化此包下的类
package com.qhf;
@Service("userService")
class UserService {
}
- productService
package com.qhf.service;
import com.qhf.Service;
@Service
public class ProductService {
}
- 工厂类
public class BeanFactory {
private Map<String, Object> objMap = new ConcurrentHashMap<>();
private Map<Class<?>, String> clsMap = new ConcurrentHashMap<Class<?>, String>();//记录所有Service 注解的字节码对象
public BeanFactory() {
}
/**
* 对含有ComponentScan 注解的包进行扫描,获取字节码对象存在Set集合中,暂不实例化对象,当使用时再实例化存在Map 中
*/
public BeanFactory(Class<?> configClass) throws Exception {
ComponentScan componentScan = configClass.getAnnotation(ComponentScan.class);
String pack = componentScan.value();
if ("".equals(pack)) {
pack = configClass.getPackage().getName();
}
String packPath = pack.replace(".", "/");
URL url = ClassLoader.getSystemResource(packPath);
// 若有中文路径
String realPath = URLDecoder.decode(url.getPath(), "gbk");
File dir = new File(realPath);
loopDir(dir, pack);
System.out.println(clsMap);
}
private void loopDir(File dir, String pack) throws Exception {
File[] files = dir.listFiles();
for (File file : files) {
if (file.isFile()) {
if (!file.getName().endsWith(".class")) {
continue;
}
// 是class 文件并且有@Service 注解,则加入clsMap
String simpleName = file.getName().split("\\.")[0];
Class<?> clazz = Class.forName(pack + "." + simpleName);
if (clazz.isAnnotationPresent(Service.class)) {
clsMap.put(clazz, simpleName.substring(0,1).toLowerCase() + simpleName.substring(1));
}
} else {
// 是目录, 递归
loopDir(file, pack + "." + file.getName());
}
}
}
private Object newInstance(String beanName, Class<?> clazz) throws Exception {
if (!clsMap.containsKey(clazz))
return null;
if (beanName == null) {
String simpleName = clazz.getSimpleName().substring(0,1).toLowerCase() + clazz.getSimpleName().substring(1);
if (objMap.containsKey(simpleName)) {
return objMap.get(simpleName);
} else {
Object instance = clazz.newInstance();
objMap.put(simpleName, instance);
return instance;
}
} else {
if (objMap.containsKey(beanName)) {
return objMap.get(beanName);
} else {
return null;
}
}
}
public <T>T getBean(Class<T> clazz) throws Exception {
return (T)newInstance(null, clazz);
}
public <T>T getBean(String beanName, Class<T> clazz) throws Exception {
return (T)newInstance(beanName, clazz);
}
public static void main(String[] args) throws Exception {
BeanFactory factory = new BeanFactory(AppConfig.class);
ProductService ps = factory.getBean(ProductService.class);
UserService us1 = factory.getBean(UserService.class);
UserService us2 = factory.getBean("userService", UserService.class);
System.out.println(ps);
System.out.println(us1);
System.out.println(us2);
System.out.println(us1 == us2);
}
}
- 结果
{class com.qhf.service.ProductService=productService, class com.qhf.UserService=userService}
com.qhf.service.ProductService@45ee12a7
com.qhf.UserService@330bedb4
com.qhf.UserService@330bedb4
true