/*** @description:
*@author: ZhuCJ
* @date: 2020-08-27 10:16*/
public class AnnotationBeanFactory implementsBaseFactory {private static final Logger logger = LoggerFactory.getLogger(AnnotationBeanFactory.class);privateString packerName ;private static final String EXT = "class";
@OverridepublicObject getBean(String beanName) {returnBEAN_MAP.get(beanName);
}publicAnnotationBeanFactory(String packerName){this.packerName =packerName;//加载注解Bean
loadBean();//加载注入的属性Bean
loadInjectBean();
}/*** 加载bean到容器中*/
public voidloadBean(){//读取包名的路径
String packerPath = null;try{
packerPath=getPkgPath(packerName);
}catch(UnsupportedEncodingException e) {
logger.info("文件路径编码异常:{}",e.getMessage());throw new RuntimeException("packerName path error");
}
logger.info("扫描文件目录的路径:{}", packerPath);//查找包含Component注解的类
Map, Set>> classesMap = scanClassesByAnnotations(packerName, packerPath, true,
Arrays.asList(ServiceTest.class));if (classesMap.size() == 0){
logger.error("目录:{}下,未获取到需要加载的类", packerPath);return;
}//标记的反射对象
Set> classSet = new HashSet<>();
classesMap.forEach((k, v)->{
classSet.addAll(v);
});//默认设置类名为类名小写
for (Class>classObj:classSet){
Object object= null;try{
object=classObj.newInstance();
}catch(InstantiationException e) {throw new RuntimeException(classObj.getSimpleName()+ " create error");
}catch(IllegalAccessException e) {throw new RuntimeException(classObj.getSimpleName()+ " create error");
}
BEAN_MAP.put(StringUtils.uncapitalize(classObj.getSimpleName()),object);
}
}/*** 加载注入的Bean属性*/
public voidloadInjectBean(){
BEAN_MAP.forEach((k,v)->{
setAttributeValue(v);
});
}/*** 根据包名获取包的URL
*@parampkgName com.demo.controller
*@return
*/
public static String getPkgPath(String pkgName) throwsUnsupportedEncodingException {
String pkgDirName= pkgName.replace('.', File.separatorChar);
URL url=Thread.currentThread().getContextClassLoader().getResource(pkgDirName);return url == null ? null : URLDecoder.decode(url.getFile(), "UTF-8");
}/*** 获取指定包下包含指定注解的所有类对象的集合
*@parampkgName 包名(com.demo.controller)
*@parampkgPath 包路径(/Users/xxx/workspace/java/project/out/production/classes/com/demo/controller)
*@paramrecursive 是否递归遍历子目录
*@paramtargetAnnotations 指定注解
*@return以注解和对应类集合构成的键值对*/
public static Map, Set>>scanClassesByAnnotations(
String pkgName, String pkgPath,final booleanrecursive,
List>targetAnnotations){
Map, Set>> resultMap = new HashMap<>(16);
Collection allClassFile =getAllClassFile(pkgPath, recursive);for(File curFile : allClassFile){try{
Class> curClass =getClassObj(curFile, pkgPath, pkgName);for (Class extends Annotation>annotation : targetAnnotations){if(curClass.isAnnotationPresent(annotation)){if (!resultMap.containsKey(annotation)){
resultMap.put(annotation,new HashSet>());
}
resultMap.get(annotation).add(curClass);
}
}
}catch(ClassNotFoundException e) {
logger.error("load class fail", e);
}
}returnresultMap;
}/*** 遍历指定目录下所有扩展名为class的文件
*@parampkgPath 包目录
*@paramrecursive 是否递归遍历子目录
*@return
*/
private static Collection getAllClassFile(String pkgPath, booleanrecursive){
File fPkgDir= newFile(pkgPath);if (!(fPkgDir.exists() &&fPkgDir.isDirectory())){
logger.error("the directory to package is empty: {}", pkgPath);return null;
}return FileUtils.listFiles(fPkgDir, newString[]{EXT}, recursive);
}/*** 加载类
*@paramfile
*@parampkgPath
*@parampkgName
*@return*@throwsClassNotFoundException*/
private static Class> getClassObj(File file, String pkgPath, String pkgName) throwsClassNotFoundException{//考虑class文件在子目录中的情况
String absPath = file.getAbsolutePath().substring(0, file.getAbsolutePath().length() - EXT.length() - 1);
String className= absPath.substring(pkgPath.length()).replace(File.separatorChar, '.');
className= className.startsWith(".") ? pkgName + className : pkgName + "." +className;returnThread.currentThread().getContextClassLoader().loadClass(className);
}/*** 属性赋值
*@paramobject*/
private static voidsetAttributeValue(Object object){
Class> aClass =object.getClass();
Field[] declaredFields=aClass.getDeclaredFields();for(Field field:declaredFields){if (field.isAnnotationPresent(AutowiredTest.class)){//默认取属性值类型小写为 BeanId
String simpleName =field.getType().getSimpleName();
Object obj=BEAN_MAP.get(StringUtils.uncapitalize(simpleName));//允许私有属性赋值
field.setAccessible(true);try{
field.set(object,obj);
}catch(IllegalAccessException e) {throw new RuntimeException(field.getName() +" attribute set value exception");
}
}
}
}public static voidmain(String[] args) {
BaseFactory baseFactory= new AnnotationBeanFactory("com.spring");
BaseFactory baseFactory1= new XmlBeanFactory("/spring/test.xml");
Body body= (Body) baseFactory.getBean("body");
System.out.println("加载类:"+BaseFactory.BEAN_MAP.size()+"个");
Object apple= baseFactory.getBean("apple");
System.out.println(body);
System.out.println(apple);
Order order= newOrder();for(Field field:order.getClass().getDeclaredFields()){
System.out.println(field.getName());
System.out.println(field.getType().getSimpleName());
}
}
}