Spring-扫描并创建bean
代码结构:
package com.java.spring; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface CustomizeComponentScan { String value(); }
package com.java.spring; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface CustomizeComponent { String value(); }
package com.java.spring; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface CustomizeScope { String value(); }
package com.java.spring; public class CustomizeBeanDefinition { private Class clazz; private String scope; public CustomizeBeanDefinition() { } public CustomizeBeanDefinition(Class clazz, String scope) { this.clazz = clazz; this.scope = scope; } public Class getClazz() { return clazz; } public void setClazz(Class clazz) { this.clazz = clazz; } public String getScope() { return scope; } public void setScope(String scope) { this.scope = scope; } }
package com.java.spring; @CustomizeComponentScan("com.java.service") public class CustomizeConfig { }
package com.java.spring; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.net.URL; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 定制的Spring */ public class CustomizeApplicationContext { private Class customizeConfig; /** * 单例池 */ private ConcurrentHashMap<String,Object> singleTonMap = new ConcurrentHashMap<>(); /** * bean定义Map */ private ConcurrentHashMap<String,CustomizeBeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(); public CustomizeApplicationContext(Class customizeConfig) { this.customizeConfig = customizeConfig; scan(); initAllSingleBean(); } /** * CustomizeComponentScan -->扫描路径-->获取Component注解-->CustomizeBeanDefinition-->放入beanDefinitionMap */ private void scan(){ //获取传入配置类注解 CustomizeComponentScan ccscan = (CustomizeComponentScan) this.customizeConfig.getDeclaredAnnotation(CustomizeComponentScan.class); //获取扫描路径 String scanPath = ccscan.value(); //将路径转换成 com.xx->com/xx String dotScanPath = scanPath.replace(".", "//"); //找到扫描路径下所有文件 //注意:这里不能用 CustomizeApplicationContext.class.getResource("com/java/service") //原因是我们需要获取的是工程所在的路径 ClassLoader classLoader = CustomizeApplicationContext.class.getClassLoader(); URL resource = classLoader.getResource(dotScanPath); File file = new File(resource.getFile()); if (file.isDirectory()) { File[] files = file.listFiles(); for (File f : files) { String fileName = f.getName(); if (fileName.endsWith(".class")) { try { //获取扫描路径下的class Class<?> aClass = classLoader.loadClass(subFilePath(f.getPath())); if(aClass.isAnnotationPresent(CustomizeComponent.class)){ //如果是自定义的注解,做自己想做的 CustomizeComponent ccp = aClass.getDeclaredAnnotation(CustomizeComponent.class); String beanName = ccp.value(); //判断是否是单例 CustomizeBeanDefinition beanDefinition = new CustomizeBeanDefinition(); if(aClass.isAnnotationPresent(CustomizeScope.class)){ CustomizeScope customizeScope = aClass.getDeclaredAnnotation(CustomizeScope.class); System.out.println(">>>"+ customizeScope.value()); beanDefinition.setScope(customizeScope.value().trim()); }else{ //如果不设置,默认单例 beanDefinition.setScope("singleton"); } beanDefinition.setClazz(aClass); beanDefinitionMap.put(beanName,beanDefinition); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } } } /** * 初始化所有单例bean */ private void initAllSingleBean(){ for(Map.Entry<String,CustomizeBeanDefinition> entry : beanDefinitionMap.entrySet()){ String beanName = entry.getKey(); CustomizeBeanDefinition beanDefinition = entry.getValue(); if("singleton".equals(beanDefinition.getScope())){ Object beanObj = createBean(beanDefinition); singleTonMap.put(beanName,beanObj); } } } /** * 截取路径 * * @param absFilePath * @return */ private String subFilePath(String absFilePath) { if (null == absFilePath) { return ""; } String subPath = absFilePath.substring(absFilePath.indexOf("com"), absFilePath.indexOf(".class")); if (subPath.length() > 0) { subPath = subPath.replace(File.separator, "."); } return subPath; } /** * 创基bean * @param beanDefinition * @return */ public Object createBean(CustomizeBeanDefinition beanDefinition){ Class clazz = beanDefinition.getClazz(); Object instance = null; try { instance = clazz.getDeclaredConstructor().newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return instance; } /** * 获取bean 对象 * * @param name * @return */ public Object getBean(String name) { if(beanDefinitionMap.containsKey(name)){ CustomizeBeanDefinition beanDefinition = beanDefinitionMap.get(name.trim()); if("singleton".equals(beanDefinition.getScope())){ //如果是单例,从单例池中返回 return singleTonMap.get(name); }else{ //原型模式,创建bean对象 return createBean(beanDefinition); } }else{ //不存在bean,可自定义异常 throw new NullPointerException(); } } }
package com.java.service; import com.java.spring.CustomizeComponent; import com.java.spring.CustomizeScope; @CustomizeComponent("userService") @CustomizeScope("prototype") public class UserService { }
package com.java.spring; import com.java.service.UserService; /** * Spring 启动类 */ public class SpringLoader { public static void main(String[] args) { CustomizeApplicationContext context = new CustomizeApplicationContext(CustomizeConfig.class); UserService userService1 = (UserService) context.getBean("userService"); UserService userService2 = (UserService) context.getBean("userService"); System.out.println(userService1); System.out.println(userService2); } }
原型模式
去掉注解单例模式